Your content bottleneck isn't ideas. It's the edit.
Animation Studio Interstaff
Build log

Your content bottleneck isn't ideas. It's the edit.

How I built a desktop app that turns HTML into broadcast-ready video — frame for frame, the same way every time.

Written by Cris, who built it · Interstaff · 9 min read
Frames per reel1,080 Export formats6 With alpha4 Aspect ratios per click3 Cloud services0

Nobody talks about this enough. The teams producing the most content aren't the ones with the best ideas. They're the ones with the shortest distance between "I want to say this" and "it's live."

We had the ideas. Forty hooks in a doc. A content calendar that looked great on Monday.

Then every one of them hit the edit. And that's where they died.

The problem

The part nobody warns you about

I've watched this loop kill more content than bad copy ever did.

You write a script. You brief an editor. Three days later you get a cut. The headline's wrong. You send notes. Two days later, v2. Now you want it in square for the feed and vertical for Reels. That's two more renders and another wait.

By the time the video is right, the thing that made you want to make it is stale.

And here's the part that really got me: the actual change was usually seven words. One line of text. A number that moved. We were spending a week of calendar time to change seven words.

That's not a creative problem. That's a plumbing problem.
The fix

Make the video a text file

The insight is dumb once you see it. Every video we make is text, shapes, and motion. A browser already does text, shapes, and motion better than anything — it's the most battle-tested rendering engine on the planet, and it's free.

So the source of truth for our videos isn't a project file locked inside an editor. It's an HTML file.

Change the copy, change the video. Change one number, re-render. No round trip. No one to brief.

The only thing missing was a way to turn that HTML into an actual MP4 that Instagram would accept. So I built it.

Animation Studio is a Mac app. You point it at an HTML animation, it renders a pixel-accurate video. That's the whole pitch.

Animation Studio's Studio tab: a dark structured text editor listing every line of copy in the animation, with a render settings panel and a live 9:16 preview below.
01The Studio tab. Copy fields on top, render settings bottom-left, live preview on the right. The preview is the real animation, paused at 16.4 seconds.
How it works

It doesn't record. It scrubs.

This is the one technical bit worth understanding, because it's the reason the output is trustworthy.

The obvious way to record a web animation is to play it and screen-capture. That approach is garbage. If your machine stutters, the video stutters. Render the same file twice, get two different videos. You can't build a content system on something that unreliable.

So the studio doesn't play anything. It scrubs.

It loads your animation in a headless browser, freezes every animation on the page, then walks through it one frame at a time — jump to 0.0417 seconds, screenshot, jump to 0.0833 seconds, screenshot — and hands the pile of frames to ffmpeg.

Source
One HTML file — CSS keyframes, a GSAP timeline, or both.
Headless Chromium
Load, wait for fonts. Then for every output frame: set each animation's currentTime, flush a paint, screenshot.
ffmpeg
Frames encoded to H.264, audio muxed and capped to the video length.
Output
~/Desktop/AnimationRenders/ — ready to upload.

A 45-second reel at 24fps is 1,080 frames. Every one of them is placed deliberately. Nothing is captured in real time, so nothing can drift.

The upshot: the same file always produces the same video. On my machine, on a laptop, at 2am while something else is compiling. That determinism is the whole foundation — everything else in the app is only useful because you can trust the output.

Plain CSS animations work with zero effort. For JavaScript timelines, a file opts in by exposing one hook:

The seek contract
gsap.ticker.lagSmoothing(0);
const tl = gsap.timeline({ paused: true });
// …build the timeline…

window.__studioSeek     = (seconds) => tl.seek(seconds);
window.__studioDuration = () => tl.duration();
window.__studioReady    = true;

That's the contract. Anything that can be asked "show me what you look like at 12.5 seconds" can be rendered.

And every file carries its own settings, so a saved animation reopens exactly as you left it:

Settings live in the file
<meta name="render-name"     content="interstaff_outbound_one_call">
<meta name="render-duration" content="45">
<meta name="render-fps"      content="24">
<meta name="render-width"    content="1080">
<meta name="render-height"   content="1920">
<meta name="render-audio"    content="vo_one_call_MASTER.wav">
The studio

Edit the video without touching the code

Here's where it stopped being a renderer and started being a studio.

The Text tab pulls every piece of copy out of the animation and lists it as plain fields. Scene 3, line 1. The eyebrow. The reply. You rewrite the words, hit ⌘S, and the file updates. You never see a tag.

That's the seven-words problem, solved. It's now about eleven seconds of work.

But sometimes the copy is fine and the layout is wrong. So there's a second mode: click Select, then click anything in the preview. Drag it. Resize it. Retype it.

Select mode in Animation Studio: the headline element in the preview has drag handles around it and an inspector panel showing its position, size and font weight, with a note reading writes to line 418.
02Select mode. Drag handles on a live element, and an inspector that reports exactly which line of the source file it's about to rewrite.

The part I'm proudest of is in the corner of that inspector: writes to line 418. You're not editing a copy or a layer. You're editing the actual HTML file, in place. Move a headline with your mouse, and the source changes underneath you.

No export step. No sync. The file is the video.
Throughput

One render becomes three

Every platform wants a different shape. Vertical for Reels and TikTok. Square for the feed. Landscape for YouTube.

Historically that's three separate exports and three separate waits. In the studio it's three toggles — Square, Landscape, Story HD — next to the Render button. Hit render once and the variants queue up alongside the original. The app measures the animation, scales it to fit each canvas, and letterboxes what's left over.

Renders run in parallel, in the background, while you keep working on the next one.

The render queue showing two jobs rendering in parallel with striped progress bars and ETAs, one queued job, two completed jobs including a ProRes 4444 alpha export, and one failed job with a plain-language error message.
03The queue. Two renders in flight, one waiting, and a failure that says what actually broke — not "render failed."

Two things I care about in that queue. Finished jobs reload straight back into the studio with their exact settings, so a re-render is one click. And when something breaks, it names the cause — timed out waiting for window.__studioReady — so you know where to look.

Deliverables

Six formats, four with transparency

Not every deliverable is a finished video. Sometimes you need a lower-third to drop over real footage in Premiere, with a genuine alpha channel.

The export format dropdown listing MP4 H.264, ProRes 4444, QuickTime PNG, WebM VP9, PNG sequence and GIF — with alpha badges on four of them — beside a preview showing a lower-third card floating on a transparency checkerboard.
04Overlay mode strips the background out of the stage and renders straight onto transparency. Same source file, different deliverable.

ProRes 4444 for Premiere and Resolve. WebM for the web. PNG sequence when someone downstream insists. Same animation, no rebuild.

The library

That grid is the argument

Everything lands in one folder and shows up in the Gallery with its format, dimensions and size.

The gallery tab showing five rendered videos as tall thumbnails: a dark call-transcript animation, a phone with missed-call notifications, a calendar reading 47 meetings on the board, a large numeral 187 exported as ProRes with an alpha badge, and a hook animation as a GIF.
05Mixed formats, mixed aspect ratios, one folder. These aren't separate productions — they're a handful of HTML files, re-cut.
Outcomes

What actually changed

The honest summary of what this did to our workflow:

TaskBeforeNow
Copy change on a finished videoBrief, wait, review, repeatRetype the field, ⌘S, render
Getting three aspect ratiosThree exports, three waitsThree toggles, one click
Re-rendering an old videoFind the project file, hope it opensOne click from the queue
A transparent overlay for PremiereA separate ask entirelyA dropdown
Same file rendered twiceTwo slightly different videosByte-for-byte identical
Who can change a videoWhoever has the editor openAnyone who can type

That last row is the one that changed how we work. Video stopped being a specialist request and became something anyone on the team could touch.

The app runs entirely on the machine — Chromium and ffmpeg ship inside it, so it renders offline with nothing installed and nothing phoning home. There's also a command line, which means our AI agents can render video with no human in the loop:

Terminal
./studio render interstaff_outbound_one_call.html --fmt prores --overlay
Disruption

Why this is bigger than my content calendar

Every tool in the video industry was built on an assumption: that video is hard to produce, so the work is worth serializing through a specialist with a timeline open.

That assumption is where the revision loop comes from. It's where "let's just use the one we have" comes from. It's why most companies publish a fraction of what they mean to.

When the source of truth for a video is a text file, that assumption breaks, and things that were impossible get boring:

The moat was never creative talent. It was access to the pipeline. Whoever could open the editor decided what shipped, and everyone else waited in line.

That line is what disappears. Not editors — editors are still far better than me at editing. What disappears is the queue in front of them for the routine stuff: the stat card, the before/after, the lower-third, the twelfth variation of a hook that's already working.

The teams that figure this out won't just make videos faster. They'll make different decisions, because they'll stop asking "is this worth an edit?" and start asking "what do we actually want to say?"

So — how many of your ideas died in a queue this month, and would you still call that a creative problem?

Animation Studio is an internal tool at Interstaff. It renders every animation on our feed.
Built with Tauri, FastAPI, Playwright and ffmpeg.