pixelpush
v0.3.0
Published
Edit your running Vite+React+Tailwind app like Figma — changes land in your source code as clean Tailwind class edits
Maintainers
Readme
pixelpush
Edit your running app like Figma. Changes land in your source code.
cd your-vite-react-tailwind-app
npx pixelpushpixelpush opens your local app on a canvas at localhost:4400. Click any
element, drag its padding, pull the gaps between siblings, click an alignment
dot — and every adjustment is written back to your source files as a clean,
single-token Tailwind class edit:
- <div className="mx-auto flex w-full max-w-3xl flex-col gap-6 px-4 py-8">
+ <div className="mx-auto flex w-full max-w-3xl flex-col gap-6 px-4 pt-12 pb-8">No AI in the loop. No generated slop. The exact value you dragged, in the exact place it belongs, byte-identical everywhere else — a diff your team will actually approve.
Screenshots below are pixelpush running on a real production-style codebase (a design-system playground), not a toy demo.
Why
Designers generate UI with AI, then suffer to fine-tune it: "make the padding a bit bigger" via prompt is slow, imprecise, and rewrites things it shouldn't. The fine-tuning you want is direct manipulation — Figma's click-and-drag — but on your real code, not a mockup.
pixelpush maps every DOM element back to its exact source location at build time, so canvas edits become deterministic source edits. Fast, precise, free.
Select & inspect
Click any element: selection box, padding tint, drag handles on the canvas —
box model, layout values, and the element's actual Tailwind classes in the
inspector. The source location (file:line:col) is always shown.
![]()
Drag the gaps (Auto Layout style)
Select a flex/grid container and the spaces between its children light up —
including children that are design-system components. Drag a band and the
parent's gap-* class changes, one token.
![]()
Alignment, Figma-style
The 9-dot grid, direction toggle, and space-between — each click is a
single-token items-* / justify-* / flex-* replacement.
| center (before) | left dot clicked | between toggled |
|---|---|---|
|
|
|
|
Edit text inline
Double-click static text, type, press Enter. The JSX text node updates;
expression text ({user.name}) is politely refused instead of corrupted.
![]()
Everything else you'd expect
- Padding / margin / size / radius / font / colors — drag handles and
inspector fields; values snap to your Tailwind scale (v3 and v4 detected
automatically), off-scale values fall back to arbitrary (
pt-[23px]) - Undo / redo — ⌘Z / ⇧⌘Z, snapshot-accurate
- Live preview — drags preview instantly; the file write syncs back through Vite HMR without a flash
- Design-system safe —
node_modulescomponents are never instrumented; clicking inside one selects the nearest element of your code. Your design system cannot be touched by accident. - Honest failures — dynamic
className(template literals, spreads) is rejected with a toast telling you where to edit manually. Never a silent wrong write. - List rendering — one source element rendered N times is labeled "edits apply to all N instances"
Requirements
Vite + React + Tailwind CSS. pixelpush checks your project on startup
and tells you plainly if something is missing (Next.js and CRA are not
supported yet). Zero config — it loads your existing vite.config and never
modifies it.
npx pixelpush # project root = current dir
npx pixelpush --open "/settings" # open a specific route on the canvas
npx pixelpush --cwd apps/web # point at a subdirectoryWorking with AI agents
pixelpush pairs naturally with agent-driven coding: let the agent generate,
then fine-tune by hand. docs/AGENT_RULES.md is a
drop-in rules file (CLAUDE.md / .cursorrules) that keeps agent output fully
pixelpush-editable — string-literal classNames, gap-based spacing (the Figma
Auto Layout model), no variant factories.
How it works
- A Vite plugin (injected at runtime — your config is untouched) tags every
JSX host element with
data-bs-id="src/App.tsx:12:8"during dev transform - The editor embeds your app in an iframe; a tiny agent script reports
hit-tests, geometry, and computed styles over
postMessage - Edits go to a local server that patches your source with byte-exact string splices guided by the AST — formatting, blank lines, and quote styles survive untouched
- Vite HMR refreshes the iframe; the canvas re-measures
Status
Early but real: the money path (select → drag → clean diff → HMR) is tested
end-to-end on both Tailwind v3 and v4 codebases. Not yet: responsive/state
variants are read-only (md:, hover:), hug/fill sizing, component variant
props, multi-select.
License
MIT
