cd /news/developer-tools/two-real-vs-code-extensions-built-wi… · home › topics › developer-tools › article
[ARTICLE · art-140637] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

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

A developer built two real VS Code extensions using vsceasy, a CLI and framework that scaffolds projects with a React webview, a typed RPC bridge between the extension host and webview, and file-based routing for panels, commands, menus and tree views. The framework also provides a mini-ORM, an LLM client, editor-surface helpers and a language project type for grammar-based extensions. One of the extensions, Code Trainer, verifies every model-generated exercise by running its tests against both a reference solution (must pass) and a starter (must fail), rejecting and regenerating anything else.

by read3 min views1 publishedSep 27, 2026

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, 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:

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 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 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" 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.

── more in #developer-tools 4 stories · sorted by recency
── more on @vsceasy 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/two-real-vs-code-ext…] indexed:0 read:3min 2026-09-27 · —