Screenshot-to-Code: Drop a Mockup, Get HTML, Tailwind, React, or Vue
screenshot-to-code (~73k stars) does exactly what the name promises: drop in a screenshot (or mockup-like image) and generate front-end code — HTML/Tailwind, React, Vue, and related targets depending on configuration. It became a bookmark for designers who need a first cut of markup and for developers rebuilding UIs when the only artifact left is a PNG from a dead Figma export.
What the project actually does
Under the hood, screenshot-to-code sends the image to a vision-capable model with stack-specific instructions. The model infers layout, typography, colors, and component boundaries, then emits code in the format you selected. It is not magic pixel-perfect reconstruction — it is structured guessing aided by strong priors (Tailwind utility classes, React functional components, etc.). That distinction matters for setting stakeholder expectations: you get a sprint starter, not a production drop-in.
Where it shines
- Turning designer PNGs into a first cut of markup when deadlines are tight
- Rebuilding legacy UI from screen grabs when source files are missing
- Teaching juniors how AI maps visual hierarchy to components
- Spiking landing pages before committing to a design system
- Comparing model quality across providers on the same screenshot
Where humans still win
- Accessibility and semantics — heading order, focus states, ARIA, keyboard nav
- Design tokens and real component libraries — shadcn, MUI, your internal kit
- Production performance — responsive images, font loading, CLS, bundle size
- Brand fidelity — exact spacing, custom type, motion
- Backend wiring — forms, auth, data fetching, error boundaries
Treat the output as a draft, then finish in your editor with design review and QA. The best teams use screenshot-to-code to eliminate blank-page syndrome, not to skip design sign-off.
Local setup (typical flow)
Deployment options change — read the repo README for Docker vs local Node paths. A common developer flow:
git clone https://github.com/abi/screenshot-to-code.git
cd screenshot-to-code
# Follow README: Docker compose OR yarn install
# Add OPENAI_API_KEY / ANTHROPIC_API_KEY / etc. to .env
yarn devYou will need at least one vision-capable API key. Some configs let you route generation through alternative hosts — check the settings panel in the running app for stack toggles (HTML+Tailwind vs React vs Vue). For teams with strict data policies, run locally and avoid uploading sensitive internal UIs to shared SaaS accounts.
Recommended workflow
- Crop and clean the screenshot — remove OS chrome, use consistent viewport width
- Pick the closest stack to your target (Tailwind if you ship Tailwind)
- Generate and save output to a spike branch
- Refactor into real components — extract repeated cards, wire props
- Replace hardcoded colors with tokens from your theme
- Run a11y and visual diff against the original mockup
- Eject to your main app structure — often the Vite + React + Tailwind + shadcn stack
Comparisons in the vibe-coding landscape
Open Lovable targets whole-site recreate loops with scraping and chat, not single images. bolt.diy builds full-stack apps in the browser from prompts. Figma MCP and Code Connect integrations (when you have Figma source) usually beat screenshots for ongoing sync. screenshot-to-code wins when the input is literally a picture and you want code in minutes.
For iterative repo editing after the spike, switch to Aider or Cline. For design-system-heavy products, start from components, not from PNG inference.
WordPress and hybrid shops
Marketing teams often hand developers a flat comp for a WordPress landing template. screenshot-to-code can bootstrap the static HTML/Tailwind slice; you then port into a Sage Blade partial or block pattern. Content fields still belong in ACF — for bulk text edits across many pages, point editors to Quickfields Bulk Editor for ACF rather than re-running image-to-code for every copy tweak.
Risks
- Hallucinated assets — placeholder images and icons that do not exist in your CDN
- Incorrect text — OCR-like mistakes on small type; always proofread
- Non-responsive layouts — desktop screenshots become fixed-width div soup without manual breakpoints
- IP leakage — unreleased UI sent to third-party APIs; use local/enterprise routes when needed
FAQ
Is the generated code licensed cleanly? Treat it like any AI output — review before shipping commercially.
Can it match our design system? Only if you refactor afterward; it does not know your internal Button variant API.
Does it replace Figma Dev Mode? No — it replaces staring at a PNG with no Figma file, or accelerates early spikes.
What models work best? Vision-quality matters more than raw coding scores; test on your UI density (dashboards vs marketing).
Choosing models and stacks in the UI
Not every vision model respects Tailwind spacing equally. Run the same screenshot through two providers and diff the output — you will see one favor flexbox while another hardcodes pixel widths. For marketing pages, HTML+Tailwind is often fastest to hand off to a WordPress Blade partial. For product dashboards, React with component extraction saves time later when you wire real data. Document which combo your team standardizes on so designers know what to expect from the first pass.
Design QA checklist after generation
- Compare heading hierarchy against the mockup — models love skipping
h1semantics - Tab through interactive elements — focus rings are usually missing
- Resize to mobile — add breakpoints where the screenshot was desktop-only
- Swap placeholder images for licensed assets from your DAM
- Run Lighthouse accessibility and performance audits
- Have a human designer sign off before merge — AI output is a draft, not approval
Team workflow with designers
The healthiest handoff is: designer exports a clean PNG at the target breakpoint, developer runs screenshot-to-code into a spike branch, designer reviews in Vercel preview, developer refactors into the real design system. That loop takes hours instead of days of manual markup, without pretending the tool replaces design critique. When the site also has a WordPress editorial layer, keep copy out of generated JSX — wire ACF fields and train editors on Quickfields for bulk text updates.