Skip to content
← home

Build Your Own Lab

5 min read

I highly recommend anyone who works on interfaces has a lab. A scratch pad you go to for making components and tuning interactions, that slowly turns into your own personal library. I revisit mine all the time.

I posted about mine on X and it did way better than I expected, so I pulled the bones out into something you can use. It's called byolab (build your own lab), and it's open source.

Where it came from

Emil Kowalski made himself an interaction lab that generates new interactions every day from rules he set, and he only keeps the ones he likes, so it looks more like him over time. Benji Taylor's Stageshow skill is incredible and was a great base for mine.

But my lab is just a place for me to build components. It's opinionated. I use the components models build to figure out my own taste. I added video exporting in case you want to share stuff, but that's a bonus.

This one is a blank canvas. You make the art.

Ask your agent

You don't really need to read the docs. Open it with your agent and ask how to use it. It checks your setup, starts the lab, and walks you through your first component.

From there, bring whatever you like. Add your favorite UI skills, or tell it to use a certain shadcn component or theme, and it builds on that.

The loop

You ask your agent for something:

make a copy button that shows what it copied

It runs pnpm lab new, builds it, and sends you a link. It shows up in the gallery under "To judge". Click around, try to break it, then keep it or toss it. The agent doesn't get a vote.

Keeping a draft moves it into the lab.

Tossing asks why, in one line.

Tossing a draft. The note goes into TASTE.md.

That note goes into TASTE.md. Next time your agent comes up with ideas, it turns the notes into rules and reads them before building anything. Mine has stuff like "product motion stays under 300ms" now, and I stopped getting the same mistakes back.

Leave good notes

Took me a while to figure this one out. The note is the only thing that sticks around, so a lazy one wastes the toss. "looks bad" teaches your agent nothing.

Name the part, say what's wrong with it, and if you know, what you'd want instead:

Instead ofTry
looks badspacing is too loose, it reads as a mockup
mehI've seen this toggle a hundred times
not practicalclever, but no product would ship a cancel button you drag
button is offthe upgrade button floats in the header, put it next to the status it answers

Say what you liked too. "love the receipt, hate the timer bar" keeps the good half around for next time.

Tuning

It starts from a grid, an idea I got from @MSchwaibold: set the grid first, then design inside it. Mine is 8px with a 24px outer radius, and pnpm lab grid checks every component against it. Tune it, or ask your agent to fit it to your aesthetic.

Some stuff you just can't describe. "a little less bouncy" goes back and forth forever, so DialKit is built in (Josh Puckett made it, it's great). Drag until it feels right, hit Copy, and paste the numbers back to your agent. It bakes them in.

Radius, padding, and gap on a draft, live.

If you want to try different viewports, locales, or times, ask your agent to add knobs by @mertduzgun.

Films

Anything you keep can get a film. You write a few beats (move the cursor here, click this, tween that) and it drives the real component, not a screen recording of it.

film.ts
beats: [
  { at: 1.4, click: '[data-slot="trigger"]', values: { progress: 1 } },
  { at: 3.6, click: '[data-slot="trigger"]', values: { progress: 0 } },
]

Every frame is a function of time, so the renderer steps through it frame by frame into ffmpeg. You get the exact same video every time, light and dark, at whatever size you want:

pnpm lab export copy-button --theme both --height 2160

There's also a check that scrubs the film out of order and compares frames, so a stray timer or Math.random gets caught before you render.

Agent first

Every command takes plain arguments, explains its errors, and has a --json flag, since your agent runs them way more than you will:

pnpm lab new <slug> [--kind component|explainer|breakdown]
pnpm lab keep <slug>
pnpm lab toss <slug> --reason "..."
pnpm lab grid <slug>
pnpm lab export <film>

grid checks your component against a few hard rules: 8px grid, 24px outer radius, no more than three font sizes. Those are my numbers, swap in yours. It also ships with an AGENTS.md and a few skills, so Claude Code, Codex, Pi, or whatever you use can find its way around.

Make it yours

There are no components in it. TASTE.md starts with a few of my defaults, and you should delete most of them. The grid, the theme, the skills, the way films look, all of it is meant to change.

This lab base is mine, but you should make it yours. No skill is going to give you taste. I read and absorb a lot of other designers' work, there are courses and free resources for it, and I learn a ton from the designers and engineers I work with at Mastra. The lab's just where I practice.

You are the skill.

Try it

It's at jal-co/byolab (MIT), on v0.1.0 right now. Hit "Use this template", open it with your agent, and ask it what to do.

If you build one, show me what's in it :)