Merv-Tutor — step debugger for JavaScript & TypeScript
Introduction
Merv-Tutor is a teaching and debugging tool for small scripts. It instruments your entry file
with Babel, runs it under Node, and writes a tutor-only trace to
merv-reports/merv-tutor/latest.json. Open the debugger with
npx merv-tutor open to step line-by-line, inspect variables in scope, and read
mirrored console output — without mixing tutor noise into Playwright or Cucumber
suite reports.
- How to install and configure a tutor-ready project
- CLI options for run and
open - Worked examples (JS, TS, async, multi-file)
- How the debugger UI, Project Files panel, and complexity analysis work
Why Merv-Tutor
- Learn by stepping — walk assignments, loops, branches, and calls one line at a time
- See memory live — Name, Scope, Value, Type at every step (Next / Prev)
- Multi-file lessons — keep several scripts in Project Files; re-run replaces only that path’s trace
- Console + trace — terminal
console.logstill prints and is mirrored in the UI - Tutor-only reports — no suite folders; dedicated
merv-tutor.html - Complexity teaching aid — estimated time/space complexity from loop nesting and growing collections
Requirements
| Requirement | Version / notes |
|---|---|
| Node.js | 18+ |
merv-client | 4.0.22+ recommended |
merv-tutor | 4.0.22+ recommended (aligned with merv-client) |
merv.properties | Not required — tutor finds the nearest package.json as project root |
Install
npm install merv-client merv-tutor
Or as dev dependencies in a lesson / course repo:
npm install -D merv-client merv-tutor
Optional package.json scripts:
{
"scripts": {
"tutor": "merv-tutor",
"tutor:open": "merv-tutor open"
}
}
Configuration
Setup steps
- Create or open a Node project with a root
package.json. - Install
merv-clientandmerv-tutor(see Install). - Add a small script under a folder such as
exercises/orlessons/. - Run
npx merv-tutor path/to/file.js— this createsmerv-reports/merv-tutor/. - Open the debugger with
npx merv-tutor open.
merv.properties needed. Merv-Tutor always writes under
<nearest-package.json>/merv-reports. Running from a nested folder such as
javascript/ does not create a second report tree there.
Report layout on disk
| Path | Purpose |
|---|---|
merv-reports/merv-tutor/latest.json |
Persistent project trace — only files executed via merv-tutor |
merv-reports/merv-tutor.html |
Step debugger UI (refreshed from the package when you run / open) |
merv-reports/log/ |
Optional NDJSON if Merv-Logs file logging is enabled (separate from the debugger) |
Optional Merv-Logs
Tutor instrumentation also emits lines through MervLogger. If you already use
Merv-Logs, those lines can appear under
merv-reports/log/. The debugger UI itself only needs merv-tutor/latest.json.
# Optional — only if you also want NDJSON / show-logs
merv.report.folder=./merv-reports/
merv.logger.file=true
merv.logger.level=INFO
Quick start
npx merv-tutor exercises/variables.js
npx merv-tutor part1.js part2.js
npx merv-tutor open
merv-tutor open serves the report folder and opens
http://127.0.0.1:6174/merv-tutor.html (same default port as merv show-report).
You can run open from any project subfolder; it still opens the root-level
merv-reports.
CLI reference
Run files
merv-tutor <file.js|file.ts> [more files…] [options]
| Option | Description |
|---|---|
--keep | Leave generated merv-test.js on disk for inspection |
-h / --help | Show help |
Open debugger
merv-tutor open [reportDir] [options]
| Option | Description |
|---|---|
reportDir | Optional path (default: project merv-reports) |
--host <host> | Bind host (default 127.0.0.1; use 0.0.0.0 for LAN) |
--port <port> | Bind port (default 6174) |
--no-open | Print the URL only — do not open a browser |
npx merv-tutor open
npx merv-tutor open ./merv-reports --port 6174
npx merv-tutor open --host 0.0.0.0 --no-open
Examples
Example 1 — variables & functions
Save as exercises/basics.js:
function add(x, y) {
return x + y;
}
let a = 10;
let b = 20;
let c = add(a, b);
console.log('sum =', c);
npx merv-tutor exercises/basics.js
npx merv-tutor open
In the debugger, step until c = add(a, b) — you will see a, b, and
c update in the variables table, and sum = 30 in the console panel.
Example 2 — loops & classes
Save as exercises/counter.js:
class Counter {
constructor(start) {
this.n = start;
}
bump() {
this.n += 1;
return this.n;
}
}
const counter = new Counter(0);
for (let i = 0; i < 3; i++) {
counter.bump();
}
console.log('final', counter.n);
npx merv-tutor exercises/counter.js
npx merv-tutor open
Watch loop iterations increase in the summary bar, and i / counter change each step.
The analysis panel estimates loop-based complexity for teaching.
Example 3 — async / await
Save as exercises/async-demo.js:
async function load() {
return await Promise.resolve(42);
}
load().then((v) => {
console.log('loaded', v);
});
npx merv-tutor exercises/async-demo.js
npx merv-tutor open
Example 4 — TypeScript
Save as exercises/greet.ts:
function greet(name: string): string {
return `Hello, ${name}`;
}
const msg: string = greet('MERV');
console.log(msg);
npx merv-tutor exercises/greet.ts
npx merv-tutor open
TypeScript is compiled with esbuild, then instrumented. The debugger shows the
compiled JavaScript lines (not the original .ts text).
Example 5 — multi-file project
Run several files in one session:
npx merv-tutor exercises/basics.js exercises/counter.js
npx merv-tutor open
Or accumulate over separate commands:
npx merv-tutor src/lessons/test1.js
npx merv-tutor src/examples/test2.js
npx merv-tutor open
Both paths remain under Project Files (folder tree preserved). Click a file to see only that file’s source and steps. Re-running the same path refreshes its trace without removing others.
What is traced
| Concept | What you see |
|---|---|
| Assignments / variables | Values updated at each step (for example a = 10) |
for / while / for-of |
Loop body markers and loop variables each iteration |
if / else |
Branch taken (if branch / else branch) |
| Functions / classes | Definitions and enter / constructor / method calls |
Calls / new / await |
Call summaries and resolved promise values where available |
console.log / info / warn / error |
Terminal output plus console panel in the debugger |
Array mutations (push, …) |
Array variable refreshed after mutating methods |
try / catch / finally |
Branch markers and catch bindings |
How it works
- Reads your file (TypeScript via esbuild).
- Instruments with Babel (scope-aware: variables, control flow,
console.*, calls,await). - Writes a temporary
merv-test.jswith tutor hooks. - Runs
node merv-test.js(console.*still prints; MervLogger itself is quiet on stdout). - Updates
merv-reports/merv-tutor/latest.jsonand refreshesmerv-tutor.html. - Deletes
merv-test.jsunless you pass--keep.
Debugger UI
- Summary bar — total steps, loop iterations, files executed
- Project Files — expandable folder tree of paths run through the CLI
- Source (left) — line-by-line; comments hidden; active line marked with ▶
- Variables (right) — Name, Scope, Value, Type; row colors by scope depth
- Console (lower right, ~60%) — cumulative
console.*up to the current step - Analysis (lower right, ~40%) — steps, iterations, estimated time/space complexity
- Controls — First / Prev / Next / Last; keyboard arrows, Home, End
Scope and shadowing
Shadowed names use Babel binding keys: global a vs block a@19 when
let a is declared on line 19. When a block-scoped variable goes out of scope, it disappears from
later steps.
Complexity note
Time complexity is estimated from loop nesting (O(1), O(n), O(n²)…);
space from whether a collection grows inside a loop. Treat this as a teaching aid, not a proof.
Limitations
- CLI entry files only — only paths you pass to
merv-tutorare instrumented and listed. Code loaded viaimport/requirestill runs but is not stepped unless you pass those files too. - No full MERV suite — tutor runs do not create Playwright/Cucumber suite folders.
- ESM — use
varor proper ESM exports where needed; tutor follows Node module mode of your file. - TypeScript display — debugger shows compiled JS lines, not original
.tssource text.
Troubleshooting
| Issue | What to check |
|---|---|
| Debugger page looks outdated |
Re-run merv-tutor or merv-tutor open so merv-tutor.html refreshes;
hard-refresh the browser (Cmd+Shift+R).
|
| Empty variables or steps |
Confirm merv-tutor/latest.json exists under merv-reports/merv-tutor/.
Run a file first: npx merv-tutor test.js.
|
| Wrong / empty report folder |
Ensure a package.json exists at the intended project root. Or pass an explicit path:
npx merv-tutor open ./merv-reports.
|
| Port already in use |
Another show-report / tutor server may be serving a different folder. Use
--port or stop the other process.
|
| Syntax error after instrumentation |
Try --keep and inspect merv-test.js; report edge cases on the
forum.
|
What’s next
- Home — Merv-Tutor section
- Merv-Logs guide —
MervLoggerfor tests and scripts - Merv-Doctor — scaffold logging projects
- Custom report — full suite/testcase reporting in code
- Merv-Local documentation
MERV