# Two Real VS Code Extensions, Built with vsceasy (and What Each Feature Does)

> Source: <https://dev.to/jairofernandez/two-real-vs-code-extensions-built-with-vsceasy-and-what-each-feature-does-3opc>
> Published: 2026-09-27 21:13:37+00:00

That 90-second video isn't a mockup. Every VS Code frame in it is a real screen recording: two extensions I built with [**vsceasy**](https://vsceasy.dev), running in VS Code, doing real work. Real keystrokes, real tests, a real local LLM answering.

This post walks through what you see in the video and which part of the framework makes each piece possible.

vsceasy is a CLI and a small framework for building VS Code extensions. It scaffolds a project with a **React webview**, a **typed RPC bridge** between the extension host and the webview, and **file-based routing** for panels, commands, menus and tree views. On top of that come a mini-ORM, an LLM client, editor-surface helpers (ghost text, typing guards, decorations) and a `language` project type for grammar-based extensions.

```
bunx @vsceasy/cli create my-extension
```

That gives you a working extension: a palette command, a webview panel, an RPC contract and a React UI, with `package.json#contributes` wired for you.

This is the layout the scaffold generates:

```
src/
  extension/extension.ts
  commands/hello.ts                  → palette command
  panels/dashboard.ts                → webview panel
  shared/api.ts                      → RPC contract
  webview/panels/dashboard/App.tsx   → React UI
```

Drop a file into `panels/`, `commands/`, `menus/` or `treeViews/` and the generator registers it and updates `contributes`. You never hand-edit that block again.

The piece I'm happiest with. You declare one interface:

```
// shared/api.ts
export interface DashboardApi {
  listFiles(pattern: string): Promise<string[]>;
}
```

Implement it on the extension side:

```
// panels/dashboard.ts
export default definePanel<DashboardApi>({
  title: 'Dashboard',
  rpc: (vscode) => ({
    async listFiles(pattern) {
      const uris = await vscode.workspace.findFiles(pattern);
      return uris.map((u) => vscode.workspace.asRelativePath(u));
    },
  }),
});
```

And call it from React:

``` js
const files = await api.listFiles('**/*.ts'); // string[], fully typed
```

No `postMessage`, no message-name strings, no `switch (msg.type)`. Rename a method and TypeScript tells you everywhere it breaks, on both sides.

`type: ui`)
[Code Trainer](https://github.com/jairoFernandez/code-coach) teaches algorithms by making you actually type them. In the video, each vsceasy feature shows up in order:

`bun test` in a captured terminal: 3 pass.
One idea from this project worth stealing: **generated exercises are verified by running them.** Every problem the model generates is written to a scratch directory and its tests run twice, against the reference solution (must pass) and against the starter (must fail). Anything else is rejected and regenerated. A model will happily produce tests that don't compile or that pass against an empty function, and no static check catches that.

`type: language`)
Not every extension needs a webview. [The TOML extension](https://github.com/jairoFernandez/toml_extension) was scaffolded with:

```
vsceasy create toml-support --type language
```

That generates a TextMate grammar, `language-configuration.json`, snippets and a file icon, with no React and no RPC. In the video:

`.toml`, plus `Cargo.lock`, `poetry.lock`, `Pipfile` and friends.`table`, `kvstr`, `inline`: type the prefix and tab through the placeholders.
`vsceasy doctor` checks that every grammar, snippet and icon referenced in `package.json` actually exists before you package.

If you build with Claude, Codex or Cursor, two entry points give the agent everything it needs:

`https://vsceasy.dev/llms.txt`
`npx @vsceasy/cli ai-guide` prints every command, flag, type and default as JSON.
So you can literally say *"help me build a VS Code extension, read [https://vsceasy.dev/llms.txt](https://vsceasy.dev/llms.txt)"* and the agent scaffolds with real commands instead of guessing at boilerplate.

```
bunx @vsceasy/cli create my-extension
cd my-extension && bun install
bun run launch
```

If you build something with it, open an issue or PR with the repo link and it goes on the showcase page. I'd love to see it.
