Skip to content
Velaris

Building in public

We built a demo you can break instead of a product video

Videos show the happy path at the vendor's pace. We shipped the real interface with fake data, and the constraint made the product better.

Vithu ·

The obvious move for a pre-launch product is a polished video. We built an interactive demo instead — the real desktop, the real apps, filled with fabricated data, running entirely in your browser. No account, no install, nothing you can break.

It was more work than a video and I’d do it again. Here’s what it forced us to confront.

Videos show the path you chose

A product video is the vendor’s happy path at the vendor’s pace. That’s not dishonest, it’s just structurally incapable of answering the question a real evaluator has, which is what happens when I do something you didn’t plan for?

Every buyer knows this, which is why videos get discounted. You watch one and think “sure, but what’s it actually like.” The video can’t answer, so the next step is a sales call, and now you’ve inserted a human gate in front of curiosity.

An interactive demo answers it directly. Click things in the wrong order. Open eleven windows. Reject the agent’s plan instead of approving it. The demo has to hold up, because you’re driving.

Fake data is a design problem, not a content problem

The first version had apps that opened empty. It looked clean and taught nothing.

An empty inbox demonstrates that we can render an inbox. A populated inbox demonstrates what the product is for — that threads arrive summarised, that a deadline gets pulled to the top, that a reply can be drafted from the conversation.

So every app opens with realistic content, and each one has a moment where the AI has visibly already done something. The spreadsheet has a churn column that was generated by an =AGENT() call. The calendar shows a meeting the agent moved, with its reasoning. The chat has a run paused, waiting for you to approve unsubscribing from 23 senders.

Writing that data took longer than building the window manager. It’s also the entire value of the thing.

The constraint that improved the product

Here’s what I didn’t expect. Building a demo of the interface forced decisions we’d been deferring in the product.

When you have to show an agent asking permission, you discover your approval prompt is too vague. “Send an email?” is not a decision anyone can make. “Forward this thread to attacker@example.com?” is. The demo made the vagueness obvious because there was no verbal explanation wrapped around it — just the interface, alone, being judged.

Same with the run log. Watching the demo, it was immediately clear that a list of completed steps without their results is useless. You want to see that execute_tool scanned 1,284 messages, not just that it finished.

The demo became a design review that ran itself.

What we refused to fake

Two rules kept it honest.

Only apps that exist. The demo shows eleven apps because our product has those eleven. It would have been easy to add three aspirational ones — nobody would check — and it would have made the demo a promise we couldn’t keep. We pulled the list from the actual app registry rather than writing it fresh.

Real interactions, not scripted ones. When you click Approve, state genuinely changes. When you search connectors, it genuinely filters. Nothing is a pre-recorded animation dressed as interactivity. If a click does nothing, it does nothing — we didn’t fake responsiveness we hadn’t built.

The tour that plays through nine steps isn’t a video either. It drives the same components you can drive, using the same actions, and you can take control at any point by clicking anything.

The bug that nearly wasted all of it

We shipped it with the wrong Astro directive — client:only instead of client:load — which meant the entire thing rendered client-side only.

Users saw a full application. Search engines saw 76 words.

We’d built the most compelling page on the site and made it invisible to anyone discovering us through search. It’s written up properly here, because the failure mode is nasty: everything looks perfect in every browser you test in, and nothing in local development tells you.

One-word fix. But it’s a good reminder that “it works” and “it’s doing its job” are different tests.

Was it worth it?

The honest accounting: several days of work, against a video that would have taken one. It’s a real cost for a small team.

What we got is a page that answers evaluation questions without a sales call, that doubles as a design review whenever we change the interface, and that we can point at instead of making claims. When someone asks what the product feels like, the answer is a link.

There’s also a quieter benefit. Building a demo that has to survive arbitrary clicking is a forcing function against faking things elsewhere. Once the interface is public and drivable, the gap between what you say and what you shipped becomes visible to anyone who bothers to look.

Go break it. It resets on reload.