Inspiration

Every frontend team we know has the same loop: someone tweaks a design in Figma, someone else re-types it into code, and the two drift apart within a week. Visual builders like Webflow or Framer fix that by owning your code. AI builders like v0 or Lovable regenerate whole components, so a "make the button a bit wider" request can quietly rewrite things you didn't ask about.

We wanted the opposite: keep your editor, your Git history and your Tailwind classes, and let the visual tool be a thin layer on top. Your source files are the only artifact.

What it does

Clairity is a VS Code / Cursor extension plus a web editor. Open your Next.js project and the editor opens in your browser with a canvas, a layer tree and an inspector for the file you're working on.

  • Visual edits are deterministic. Drag a button to 240px and the extension rewrites w-48 to w-60 in your className. No model involved, and nothing else in the file moves.
  • AI edits are proposals. Ask "make this hero more premium and cinematic" and NVIDIA Nemotron (running on Nebius Token Factory) answers with a list of small Changes: a color here, a font size there, a line of copy. You tick the ones you want. Only those get written.
  • Live and Code views. Flip between the scene graph, your real running page, and the source with the selected element highlighted. It's all the same project.

How we built it

Four TypeScript packages:

  • Parser: turns JSX into a scene graph where every node points back to its exact file, line and column. It also does the writing: style values map to Tailwind classes, and edits are spliced into the source at Babel's offsets, so your formatting survives.
  • Extension: runs your next dev, watches your files, and is the only thing that writes code.
  • Server: a small Hono broker that pairs the extension with the web app over WebSocket, and calls nvidia/nemotron-3-super-120b-a12b through Token Factory's OpenAI-compatible API with streaming and structured JSON output.
  • Web app: Next.js, React and Zustand. The UI only reads state and calls actions. It never sends messages itself.

Every Change the model proposes is checked against the nodes it was actually shown before you ever see it. Unknown or Read-only nodes, and properties we can't write, get dropped.

Challenges

  • Keeping diffs small. Our first plan used recast to reprint edited files. It reformatted whole return blocks on real projects, so we switched to splicing new strings in at exact source offsets.
  • Text is harder than it looks. A heading split by a <br /> is two separate text runs. An early version replaced the whole element's children and wiped the line break.
  • Tailwind's text- prefix means both color and size. Changing a heading's color briefly deleted its font size.
  • Ids are positions. Making a class longer shifts every node after it on the same line, so the extension resends the whole scene graph when that happens.
  • Three moving parts. The extension, broker and web app all reconnect on their own. Most of our bugs lived in the gaps between them.

What we learned

How much of "visual editing" is really careful source-position bookkeeping. Why a deterministic path matters even when you have a strong model. And how to treat model output as untrusted input: validate it against what you showed it, retry once with the reason, and let the developer have the last word.

What's next

An agent that builds the project, reads the compile errors and fixes its own Changes. Following imports so the canvas shows the whole page instead of one file. And support beyond Next.js + Tailwind.

Built With

Share this project:

Updates

Submission history