Open-source alternative to Quokka.js
by Aashwin Patki · raised 0 credits · spent 0 credits · pool 0 credits
# Quoll — Project Spec & Agent Context > A live-scratchpad VS Code extension: runs JS/TS as you type and shows runtime > values inline. An open-source, modern-stack reimagining of Quokka.js, scoped to > VS Code only. > > This file is the source of truth for the build. If you use Claude Code, rename > or symlink it to `CLAUDE.md` so it auto-loads as project memory. ## Identity - **Name:** Quoll — an endangered Australian marsupial; the quokka's "Qu-" sibling. - **npm package (core):** `quoll` - **Publisher:** `apatki` · **Extension id:** `apatki.quoll` · **Command namespace:** `quoll.*` - **Repo:** `https://github.com/apatki1996/quoll` - Note: the `@quoll` npm org scope is taken by someone else, so avoid `@quoll/*`. `quoll-http` also exists (inactive) but does not block the bare `quoll` name. ## Scope & end goal - **End goal: full feature parity with Quokka.js (Community AND Pro).** v1 is a deliberate subset, but every interface below is designed so that no later parity feature requires a breaking protocol change. - **VS Code only** — no WebStorm/Sublime/JetBrains abstraction layer (this is the deliberate simplification vs. real Quokka; collapses the host layer to one decoration API). Quokka's multi-editor support is explicitly NOT a parity target. - JS + TS + JSX/TSX. **Node-style target first** (Deno runner); browser/jsdom support is phase 7. - **v1 features:** inline runtime values, coverage gutter, value explorer, inline errors. - **Non-goals (for now):** a Quokka-style plugins API, a hosted sharing service. Revisit post-parity. ### Parity matrix (Quokka feature → Quoll phase) | Feature | Quokka edition | Quoll phase | |---|---|---| | Live execution + inline values, as you type | Community | 1–4 | | Inline errors | Community | 2 | | Live coverage incl. partial (branch) coverage | Community | 4 | | Value Explorer (treeview, copy values) | Pro | 5 | | Project file imports + auto change detection | Community | 6 | | Browser-like runtime (jsdom) | Community | 7 | | Live Comments `//?`, perf `//?.`, value-on-selection | Community | 8 | | Logpoints (breakpoints as log sites) | Community | 9 | | Time Machine (step through execution) | Community | 10 | | Interactive Timeline | Pro | 11 | | Interactive Value Graphs | Pro | 11 | | CPU Profiler | Community | 12 | | Snaps (run snippets in Vue/Svelte files) | Community | 13 | | Quick Package Install + config (env, runtime, tsconfig paths) | Community | 14 | | Codeclip-style sharing (recording export; no hosted service) | Community | 15 | | Plugins API | — | post-parity | ## Architecture Five components. Define the interfaces between them BEFORE writing component code. 1. **Extension host (TypeScript)** — activation, debounced re-run on edit, inline value decorations (`DecorationRenderOptions.after`), coverage gutter decorations, a value-explorer `TreeDataProvider`, and orchestration of the runner. Owns the **append-only run event log** (the foundation for Time Machine, Timeline, and sharing). The extension shell stays TS because the VS Code host is Node-based. 2. **Instrumentation core (Rust / Oxc)** — a **single pass**: parse TS/JSX → strip types/JSX **and** inject value-capture (plus coverage counters) in one `Traverse` → `oxc_codegen` with **one** source map. Also extracts `//?` / `//?.` comment annotations and accepts caller-supplied extra capture positions (Logpoints, selection). Shipped to the extension via **napi-rs** (fallback: WASM). 3. **Runner / sandbox (Deno)** — executes the instrumented code in a permission-locked subprocess (`--deny-net`, `--deny-read`, etc.), captures console output, captured values, errors, and timings, and reports over IPC. Must also be able to drive V8 inspector profiling (CPU Profiler, phase 12). Keep the IPC layer runtime-agnostic so Node is swappable. 4. **Serialization protocol** — CDP-`RemoteObject`-style: lazy expansion via `objectId`, truncation, circular-ref handling; correct handling of typed arrays, `Map`/`Set`, class instances, and Promises (resolve and show). 5. **Golden-eval harness** — a corpus of `input snippet → expected annotations` (line N shows value X; lines covered; line dead). Run on **every** iteration. This is the objective quality signal and the regression net. ## Phased roadmap (each phase is a checkpoint) 0. **Scaffold** — `yo code`, esbuild bundling, activate on a scratch file. 1. **Run + capture** — run file in subprocess, capture `console.log` → output channel. *(Proves the loop.)* 2. **Inline decorations** — render values as `after` decorations; debounced re-run; `runId` discard discipline from day one. 3. **Transpile + source map** — single-pass Oxc; map instrumented line → source line. 4. **Value capture + coverage** — AST instrumentation emitting capture calls; coverage gutter with statement AND branch sites (partial-coverage yellow). **Build the golden-eval harness before starting this phase.** 5. **Serialization + value explorer** — protocol + tree view with lazy expansion; copy-value-to-clipboard. 6. **Async + project imports** — run-completion semantics (`done`/grace/`exit`); module resolution (ESM/CJS, tsconfig paths, node_modules); track the module dependency graph and **auto re-run when an imported project file changes**. 7. **Hardening + jsdom** — large/circular values, cancellation, perf, settings; browser-like runtime via jsdom (verify jsdom-under-Deno early — see stack notes). 8. **Live Comments + selection values** — `//?` value comments, `//?.` timing, show-value-on-selection. Core work is comment extraction in the Oxc pass; the rest is `kind`-aware rendering. 9. **Logpoints** — map VS Code breakpoints in Quoll files to `extraSites` capture positions; render like live comments. 10. **Time Machine** — persist the per-run event log (already ordered by `seq`); step forward/back re-rendering decorations from the log prefix. 11. **Interactive Timeline + Value Graphs** — webview consuming the same event log (color-coded function/line transitions, stack traces) and `RemoteValue` lazy expansion for visual data-structure graphs. 12. **CPU Profiler** — drive V8 inspector profiling in the runner (`profileStart`/`profileStop`); flamegraph webview; map frames back through the source map. 13. **Snaps** — run snippets inside Vue/Svelte SFCs: extract the `<script>` block, offset-shift positions into the instrumentation pass. 14. **Quick Package Install + config** — install npm packages from the editor; `.quoll` config (env vars, runtime version, jsdom toggle, tsconfig paths). 15. **Sharing (Codeclip-style)** — export a run recording (source + event log + retained previews) as a file or gist; hosted service out of scope.