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.