Reel

01What problem did you find?
Nobody can try a video of a product
A screen recording shows a product to someone who is not in the room, and the moment they get curious there is nothing to press. I wanted a demo that was still the product.
So Reel keeps only what the app says happened. This file is the whole recording behind the film at the top of this story: 10 commands, each with its time, then the chapters and captions a viewer reads on the same clock.
{
"format": "reel-project",
"formatVersion": 1,
"id": "receipt-split-release",
"title": "Fix a shared receipt",
"disclosure": "Synthetic data with no real people, receipts or balances",
"scene": {"id": "receipt-split", "version": 1},
"seed": 1,
"checkpointEvery": 256,
"trim": null,
"posterT": 12872,
"commands": [
Show the whole file
{"seq": 1, "t": 1816, "type": "selectExpense", "payload": {"id": "e2"}, "source": "user"},
{"seq": 2, "t": 4228, "type": "setSplitMode", "payload": {"mode": "percent"}, "source": "user"},
{"seq": 3, "t": 5735, "type": "setSplit", "payload": {"member": "mina", "value": 5000}, "source": "user"},
{"seq": 4, "t": 6841, "type": "setSplit", "payload": {"member": "theo", "value": 4000}, "source": "user"},
{"seq": 5, "t": 7947, "type": "setSplit", "payload": {"member": "ana", "value": 3000}, "source": "user"},
{"seq": 6, "t": 9565, "type": "confirmEdit", "payload": {}, "source": "user"},
{"seq": 7, "t": 12572, "type": "setSplit", "payload": {"member": "ana", "value": 1000}, "source": "user"},
{"seq": 8, "t": 14181, "type": "confirmEdit", "payload": {}, "source": "user"},
{"seq": 9, "t": 14634, "type": "saveResult", "payload": {"requestId": 1, "ok": true}, "source": "outcome"},
{"seq": 10, "t": 16798, "type": "setView", "payload": {"view": "balances"}, "source": "user"}
],
"chapters": [
{"id": "chapter-1", "t": 0, "title": "Open the receipt"},
{"id": "chapter-2", "t": 4228, "title": "Adjust the split"},
{"id": "chapter-3", "t": 9565, "title": "Hit a validation error"},
{"id": "chapter-4", "t": 12172, "title": "Correct the shares"},
{"id": "chapter-5", "t": 16798, "title": "Inspect the balances"}
],
"captions": [
{"id": "caption-1", "start": 200, "end": 4000, "text": "Theo paid for dinner and split it equally, so open that receipt", "target": "expense-list"},
{"id": "caption-2", "start": 4328, "end": 9400, "text": "Mina had more, so switch to percent and adjust the shares", "target": "split-editor"},
{"id": "caption-3", "start": 9665, "end": 12200, "text": "The shares add up to 120%, so the save is refused", "target": "save"},
{"id": "caption-4", "start": 12272, "end": 16600, "text": "Lower Ana to 10% and the same save goes through", "target": "split-editor"},
{"id": "caption-5", "start": 16798, "end": 20000, "text": "Balances are recomputed from every receipt", "target": "balances"}
],
"camera": [
{"id": "shot-1", "t": 0, "target": null},
{"id": "shot-2", "t": 4228, "target": "split-editor"},
{"id": "shot-3", "t": 16798, "target": null}
]
}
02Who was affected?
The one showing a product, and the one watching
02Who was affected?
The one showing a product, and the one watching
A founder or engineer shows the product. Whoever watches may be on a keyboard or a phone, so every export carries the story as plain sentences too.
Nobody outside the project has used it yet, and the two products it demonstrates, Tabkin and Relaymoth, are invented, with sample data.
03What was your hypothesis?
If the recording is commands, playback is the application itself, so whoever is watching can take over
If the recording is commands, playback is the application itself, so whoever is watching can take over
It came with a number: any point of a 20,000 command log in under 100 ms. The bet and the number both held, but the first benchmark I ran to prove the number had to be thrown out.
04What was your first attempt?
I sketched two ways to take over and built the one that forks
04What was your first attempt?
I sketched two ways to take over and built the one that forks
In the first sketch a sandbox opens beside the story, and the viewer loses the exact moment they were curious about. In the second the state on screen becomes your copy and the timeline forks where you stopped.
I built the second that night, and this is it, taken over. The timeline forks down where the viewer stopped, and nothing they change reaches the recording.
05What did later attempts look like, and what was learned?
I redrew the viewer twice in one day
05What did later attempts look like, and what was learned?
I redrew the viewer twice in one day
On 9 November I redrew the viewer twice. This is the first pass at 0:16, a plain receipt form where the demo ends on who owes what.
The form became Tabkin, a product in a window, with a pointer that nobody recorded: Reel works out where it goes from the commands.
Two code reviews also found what my passing tests had missed, including a way to clear a viewer's copy while telling them nothing was lost.
06How did you iterate and test?
The first benchmark flattered itself
It said seeking was fast and replaying was slow, which is what I wanted to hear. But the browser had replayed the log in 98 ms where Node took 672 ms, and a replay cannot get faster by moving to a browser.
My sampler had sent most of its seeks to the start of the log, where everything is cheap. I marked the run failed in the report, gave the new sampler a test that it spreads its seeks evenly, and measured again. Below is every seek of the run I kept, dark dots replaying from the start and grey ones from a checkpoint, under the target. Drag along the log to wait as long as each one took.
Seeking to command 15,000 of 20,000 took 708 ms replaying from the start and 18.5 ms from a checkpoint
07What came of it?
It passed, on a log nobody has recorded
23 ms
to reach any point of a generated 20,000 command log at the 95th percentile once the page is warm, against 1,130 ms replaying from the start
3.5 ms
on the real recording of 10 commands, no better than the 3.1 ms it takes with no checkpoints at all
The numbers show a long log can be reached anywhere, fast. They cannot show that anyone needs it, because a real demo is 10 commands. The whole viewer is 115 KB of code once gzipped, and a second model caught 6 of 6 money bugs I seeded, which checking seek against replay could not see. All of it is one laptop in a lab.
08What would you do next?
Next is putting it in front of a person
Nobody has used Reel in a study yet, so that comes first. After it: camera moves that interpolate by time, a friendlier way to repair an edit that breaks later commands, and video export, which is not built.



