LeetCode Practice Extension
A VS Code extension for LeetCode practice — 40+ commands, cloud sync, interview mode, AI-assisted hints. Live on VS Code Marketplace and Open VSX.
The problem
I was practicing LeetCode in the browser and writing solutions in VS Code, copy-pasting back and forth like an idiot. The context-switch cost was killing my flow — and the actual act of solving a problem is 5% the fun of algorithm work; I wanted to spend more time on the solve and less on the tooling around it.
What it does
A full VS Code extension, shipped to the Marketplace and Open VSX. It:
- Fetches problems from LeetCode’s (private) GraphQL API
- Generates solution templates in TypeScript, JavaScript, Python, or C++ with example test cases wired up
- Runs examples inline in the editor terminal, highlights pass/fail
- Tracks your progress with XP, streaks, and per-problem timestamps
- Syncs everything through Firestore so stats follow you across machines
- Supports an “interview mode” — timed problems + auto-generated post-mortem reports in a custom
.lcireportfile
And because I kept getting annoyed by having to copy URLs, there’s a companion Chrome extension: one-click “Open in VS Code” on any leetcode.com problem page.
Architecture
- Core: TypeScript, the VS Code Extension API, 40+ registered commands.
- Custom editors for
.leetcode,.lcInterview,.lcireport, and.hintfile types. - API layer: wraps the private LeetCode GraphQL endpoint — problem fetch, user stats, daily challenge.
- Cloud sync: Firestore. Stats, streaks, and saved problem state. Optional; works offline too.
- Chrome extension: thin bridge that launches a
vscode://URI handler to open problems in-editor. - Distribution: published to both Microsoft VS Code Marketplace and Open VSX (so it works in VSCodium, Cursor, Gitpod, Theia).
Interesting problems I solved
Template generation that matches LeetCode’s test harness. LeetCode’s problem metadata doesn’t give you ready-to-run function signatures — you have to reconstruct them from the problem description and sample code. I parse the language’s starter stub and walk the AST to pull out the entry point, then generate matching test case bindings.
Cloud sync without making it a liability. Firestore is easy to reach for, but losing a user’s solve history to a sync bug would be unforgivable. Local storage is the source of truth; Firestore is write-behind. Conflict resolution favors “more progress, less regress”.
Distributing to two registries. Most developers only ship to the Microsoft Marketplace. I ship to Open VSX too — takes a signed package upload and a GitHub-verified publisher. Small chore, huge reach gain (VSCodium, Cursor users get the extension natively).
What I’d do differently
- Build the extension with
esbuildbundling from day one, not rely ontsc --watch. First cold-start was embarrassingly slow until I bundled. - Write acceptance tests. Most of my bugs were in command wiring I’d have caught trivially.