screenshot-to-code — Claude Code skill: UI code from an image
Turns a screenshot, mockup or Figma export into working front-end code, then renders it and compares the result against the image. Handy when the design exists but the markup does not.
npx skills add OneWave-AI/claude-skills --skill screenshot-to-code -a claude-codeWhat screenshot-to-code does
The skill reads a UI image and builds code from it: React + Tailwind CSS v4, Next.js, Vue, or plain HTML/CSS. It writes a short spec first — layout regions top to bottom, colors as hex, type scale, spacing rhythm, corner radius. The build follows that spec.
Inside an existing project it reads package.json, works out whether you are on React, Next or Vue and which Tailwind version, then reuses your components and icon library. It will not ask when the repo already answers. With no project, a single screen becomes one index.html; a multi-screen app goes to React + TypeScript + Tailwind v4 on Vite.
After building, the skill renders the page and compares it side by side with the source image at the same viewport width. Fixes run in order of impact: layout and alignment first, then spacing, then type size and weight, then color. That step needs Playwright, a headless browser or a browser tool. If rendering was not possible, the skill says the comparison was not done instead of claiming a match. You get the files, how to run them, and a list of assumptions — guessed fonts, invented states, missing assets.
What it helps with
- build markup from a UI screenshot
- turn a Figma mockup into React components
- make the screen responsive for mobile
- extract repeated cards into one component with props
- check a finished page against the original image
Example prompts for the agent
- here's a screenshot of a dashboard, build it in React and Tailwind
- make this design real, pick the stack from package.json
- code this up and compare the render against the screenshot
How to install screenshot-to-code
1Skills CLI (Vercel)
npx skills add OneWave-AI/claude-skills --skill screenshot-to-code -a claude-code2Manually: put the files in place
~/.claude/skills/screenshot-to-code/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/screenshot-to-code/
1Skills CLI (Vercel)
npx skills add OneWave-AI/claude-skills --skill screenshot-to-code -a codex2Manually: put the files in place
.agents/skills/screenshot-to-code/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add OneWave-AI/claude-skills --skill screenshot-to-code -a cursor2Manually: put the files in place
.cursor/skills/screenshot-to-code/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install OneWave-AI/claude-skills screenshot-to-code2Manually: put the files in place
.github/skills/screenshot-to-code/SKILL.md1Skills CLI (Vercel)
npx skills add OneWave-AI/claude-skills --skill screenshot-to-code -a gemini-cli2Platform CLI
gemini skills install https://github.com/OneWave-AI/claude-skills --path screenshot-to-codeManually: put the files in place
.devin/skills/screenshot-to-code/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add OneWave-AI/claude-skills --skill screenshot-to-code -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about screenshot-to-code
How do I install screenshot-to-code in Claude?
Run npx skills add OneWave-AI/claude-skills --skill screenshot-to-code -a claude-code. The skill file then sits at ~/.claude/skills/screenshot-to-code/SKILL.md.
What does screenshot-to-code do?
It breaks a UI image into regions, colors and a type scale, writes front-end code from that, then compares the rendered result with the source image.
Which stack does the skill pick?
Inside a project, whatever is already there: React, Next.js or Vue plus the current Tailwind version. Without a project, a single screen goes into one index.html and an app goes to React + TypeScript + Tailwind v4 on Vite.
Source text
SKILL.md · MIT
---
name: screenshot-to-code
description: Turns a screenshot, mockup, Figma export, or photo of a UI into working front-end code - React + Tailwind CSS v4 by default, or Next.js, Vue, or plain HTML/CSS - matching layout, spacing, colors, and typography, then renders the result and compares it against the image to close visual gaps. Use whenever the user shares an image of a website, app screen, dashboard, component, or wireframe and wants it built, cloned, recreated, or "made real", or says "code this up", "build this design", or "match this screenshot".
---
# Screenshot to Code
Recreate the UI in the image as clean, responsive, accessible code, then check the render against the image.
## Workflow
1. **Pick the target stack.** If the user is inside a project, match it: read `package.json` for React/Next/Vue and the Tailwind version, and reuse existing components, tokens, and icon libraries. Do not ask when the repo already answers it. With no project:
- Single screen or quick prototype: one self-contained `index.html` (Tailwind via the browser build, see [references/stack-setup.md](references/stack-setup.md)).
- App or multi-screen: React + TypeScript + Tailwind v4 on Vite.
- User mentions Next.js, SSR, or routing: Next.js App Router.
2. **Write a short spec before coding.** Looking at the image, note:
- Layout regions top to bottom (nav, hero, sidebar, grid, footer) and the grid or flex structure of each
- Design tokens: 3-6 colors as hex, font family guess and the type scale, spacing rhythm (usually multiples of 4px), corner radius, shadow style
- Repeated components (cards, list rows, buttons) that should be one component with props
- What the image cannot show: hover and focus states, mobile layout, real data, content below the fold
Estimate sizes from the image resolution. If the screenshot is 2x (a Retina capture 2880px wide is a 1440px layout), halve the pixel measurements.
3. **Build.** Use semantic elements (`header`, `nav`, `main`, `section`, `button`, `a`), extract repeated pieces into components, and put tokens in one place (Tailwind v4 `@theme` or CSS custom properties) rather than scattering hex codes. Use real text from the image, not lorem ipsum. For images and logos you cannot extract, use sized placeholders with descriptive `alt` text. Use an icon library the project already has (default: `lucide-react`), not hand-drawn SVGs or emoji.
4. **Make it responsive.** Build for the screenshot's viewport first, then define how it collapses: multi-column grids stack, navs become a menu button, and type scales down with `clamp()` or responsive utilities. If the screenshot is mobile, go the other direction.
5. **Render and compare.** If you can run a browser (Playwright, a headless browser, or a browser tool), screenshot the result at the source image's viewport width and compare side by side. See [references/visual-check.md](references/visual-check.md). Fix the largest differences first: layout and alignment, then spacing, then type size and weight, then color. Two or three passes is usually enough; stop when remaining differences are at the level of font rendering.
6. **Deliver.** Provide the files, how to run them, and a short list of assumptions (fonts guessed, states invented, content inferred). Name anything that needs real assets.
## Stack notes
- **React 19**: function components with TypeScript prop types. `propTypes` checks were removed from React 19; do not add them. `forwardRef` is not needed for passing `ref` to function components.
- **Tailwind CSS v4**: configuration lives in CSS. Use `@import "tailwindcss";` and `@theme { --color-brand: #...; }`, not a `tailwind.config.js` and not the v3 `@tailwind base/components/utilities` directives. Custom tokens become utilities automatically (`bg-brand`).
- **Next.js (App Router)**: pages in `app/`, components are Server Components by default. Add `"use client"` only to components that use state, effects, or event handlers.
- **Create React App** is deprecated. Use Vite for plain React.
Setup commands for each stack are in [references/stack-setup.md](references/stack-setup.md).
## Worked example
Input: a 1440px-wide screenshot of a pricing section - centered heading, three plan cards with the middle one highlighted, feature checklists, and a button per card.
Spec:
- Regions: heading block, then a 3-column card grid, max width about 1100px, 24px gap
- Tokens: background `#0B1220`, card `#111A2E`, accent `#3B82F6`, text `#E5E7EB`, muted `#94A3B8`; Inter-like sans; radius 12px
- Components: `PlanCard` with `name`, `price`, `features[]`, `highlighted`, `cta`
- Unknowns: hover states, monthly/annual toggle behavior, mobile layout
Build: `PricingSection.tsx` mapping a `plans` array into `PlanCard`; `highlighted` adds an accent border and a "Most popular" label; `grid-cols-1 md:grid-cols-3`. Check icons from `lucide-react`.
Compare: the first render has cards 40px too tall because of button padding, and the heading weight is 600 against a 700 in the image. Fix both, re-render, and deliver with an assumptions list: toggle not built, font assumed Inter.
## Failure modes
- **Guessing the stack** when the repo already defines it, or mixing Tailwind v3 config into a v4 project.
- **Absolute positioning to force a pixel match.** It breaks on the first resize. Use flex and grid, and accept small differences.
- **One giant component.** Anything that repeats three times is a component with props.
- **Invisible states.** Buttons and links need hover and `focus-visible` styles even though the screenshot cannot show them. Inputs need labels.
- **Color drift.** Sample colors from flat areas of the image, not anti-aliased edges or gradients, and check text contrast meets WCAG AA (4.5:1 for body text).
- **Claiming a match without looking.** If you could not render the result, say the comparison was not done.
© OneWave-AI · MIT · OneWave-AI/claude-skills