Screenshot → code · Illustrated guide

Screenshot to Code AI for Free: the Open-Source Converter and the DeepSeek Route

Two ways to turn one design screenshot into markup that runs — install the MIT-licensed abi/screenshot-to-code with Docker and a single model key, or attach the image to DeepSeek and have it rebuilt as one HTML file. 15 steps, every claim checked against the repo and api-docs.deepseek.com.

The short version

  • The software is free, the tokens are not. abi/screenshot-to-code is MIT-licensed and costs nothing to run yourself, but it needs at least one model key — OpenAI, Anthropic or Gemini — and you pay that provider per token.
  • DeepSeek is not one of its models. The README's default list is Gemini 3 Flash / 3.1 Pro, GPT-5.5 / 5.4 Mini and Claude Opus 4.6 / 4.8, and the string "deepseek" appears nowhere in the repository.
  • DeepSeek's vision model is deepseek-flash: its official pricing table shows Vision ✓ for flash and "Not supported" for deepseek-v4-pro. Images go in as base64, a public URL, or a Files API file_id.
  • Both routes end the same way — a single HTML file you double-click from disk. One screenshot plus a few thousand tokens of markup costs well under one US cent at DeepSeek's published Flash rates.

Install Screenshot-to-Code Locally — Convert Screenshot to Functional Code

Channel:Fahd Mirza9:38

Open

DeepSeek R1 Coding — Testing Screenshot to Code Conversion

Channel:United Top Tech3:06

Open

abi/screenshot-to-code README — supported stacks, required keys, Docker

Docs:github.com/abi/screenshot-to-codeDocs

Open

DeepSeek API Docs — Vision (base64, external URL, Files API)

Docs:api-docs.deepseek.comDocs

Open

DeepSeek API Docs — Models & Pricing (the Vision row)

Docs:api-docs.deepseek.comDocs

Open

Frames come from two clean screen recordings (no camera overlays, no burned-in captions); the supported stacks, required keys, Docker commands and DeepSeek image limits are cross-checked against the abi/screenshot-to-code README, its source files, and api-docs.deepseek.com.

Screenshots credit the recording channels and each step deep-links to the exact timestamp. Both recordings predate today's DeepSeek model names, so wherever a frame shows an older picker label the written steps follow the official documentation instead.

All 15 steps, from one screenshot to a page that runs

Start from one screenshot

  1. 1

    Capture the UI you want rebuilt

    Any flat image works — the converter's own demo uses a YouTube channel page, and the DeepSeek route below uses a 68 KB login mockup saved as log.PNG. A screenshot beats a written brief because spacing, colour and hierarchy are already decided: the model reads them instead of inventing them. Crop to the component you care about, because a full desktop shot mostly spends tokens on chrome you will delete.

    Login form mockup saved as log.PNG and opened in the Windows Photos app, the kind of flat design screenshot you hand to an AI model to have rebuilt
    The starting point: a login card mockup saved as a PNG, before anything is converted.Watch at 1:02
  2. 2

    Open the converter and see its four input paths

    After the local install, http://localhost:5173 gives you one upload box and three shortcuts: Record Screen (capture a clip of a live site), Enter URL plus Capture (the app screenshots a URL for you), and Import from Code (paste existing HTML to keep editing it). The Generating dropdown picks the stack — HTML + Tailwind, HTML + CSS, React + Tailwind, Vue + Tailwind, Bootstrap, or Ionic + Tailwind. No account is involved; the app talks to your model provider directly.

    Screenshot to Code running on localhost:5173 with HTML + Tailwind selected and all four input paths visible: the drag and drop box, Record Screen, Enter URL with Capture, and Import from Code
    Front door of the self-hosted app: drop zone, screen recorder, URL capture and code import.Watch at 4:00

Install the free open-source converter

  1. 3

    Check the host before installing

    The app is a React/Vite frontend and a FastAPI backend, and the Docker route needs a working Docker Engine. Fahd Mirza verifies his box first with cat /etc/*release — Ubuntu 22.04.4 LTS here — because the commands that follow assume a POSIX shell with docker compose available. macOS and Windows work just as well as long as Docker Desktop is running.

    Ubuntu terminal printing cat /etc/*release down to PRETTY_NAME Ubuntu 22.04.4 LTS, the host check to run before installing screenshot-to-code with Docker
    A two-second host check: Ubuntu 22.04.4 LTS, with Docker Desktop behind it.Watch at 2:12
  2. 4

    Clone the repo and put one key in backend/.env

    Run git clone https://github.com/abi/screenshot-to-code, cd into it, and write a key into the .env file the compose stack reads — the README's own line is echo "OPENAI_API_KEY=sk-your-key" > .env. One key is enough to start; OpenAI, Anthropic and Gemini are the three the README accepts, and adding more lets the app pick a stronger mix of models per run. DeepSeek is not on that list, and FAQ question 2 explains why the base-URL override does not change that.

    Terminal inside the cloned screenshot-to-code folder writing echo OPENAI_API_KEY=sk-your-key into the backend .env file, still holding the placeholder key from the README
    The placeholder key straight from the README, written to the file the backend loads at start-up.Watch at 2:55
  3. 5

    Build and start both containers with one command

    From the repository root, docker compose up -d --build pulls the base images, installs Poetry for the backend and yarn packages for the frontend, then leaves both running in the background. Expect a few minutes on a cold cache: the compose file maps the backend to port 7001 and the frontend to 5173. The README warns that this route is for running rather than developing, because file edits will not trigger a rebuild.

    Command line at the root of the screenshot-to-code repository with docker compose up -d --build typed out and ready to start
    The entire install is one command; -d detaches it so you can close the terminal.Watch at 3:25
  4. 6

    Watch the backend and frontend layers build

    The log is the useful part when something fails: backend 2/7 RUN pip install "poetry==1.4.1" and frontend 4/5 RUN yarn install are the layers that break behind a proxy or on a locked-down network. If the build stops there, the fix is almost always your Docker DNS or an npm mirror rather than the app. When the last layer finishes, localhost:5173 starts answering.

    Docker build log for screenshot-to-code at 20.2 seconds, backend layer 2 of 7 installing poetry 1.4.1 while frontend layer 4 of 5 runs yarn install
    Twenty seconds in, both images are already through their dependency layers.Watch at 3:45

Convert, save, refine

  1. 7

    Drop the screenshot in

    Drag the file onto the dashed box or click it to open a picker; the image lands in the left rail as ORIGINAL SCREENSHOT and stays there as the reference for every later version. Dark or light is a preference under the gear icon, not a functional difference. That gear dialog is also where you can paste keys instead of editing .env — the README notes keys set there live only in your browser and override the .env config.

    Screenshot to Code switched to dark mode with the dashed Drag and drop a screenshot here box empty and HTML + Tailwind still set as the generating target
    Same app in dark theme, waiting for the file — the drop zone is the whole interface.Watch at 4:45
  2. 8

    Generate and compare the variants

    The app runs more than one model per prompt so you pick a result instead of accepting the first one: Option 1 and Option 2 are tabs over the same screenshot, and how many variants you get comes from NUM_VARIANTS in backend/config.py — four for image input, two for video. Code streams into the sidebar as it is produced, with a Cancel button for when the direction is wrong. Every run is kept under Versions, so nothing is lost by experimenting.

    Screenshot to Code mid-generation with Option 1 highlighted over Option 2, a Cancel button under the Generating code spinner, and the uploaded page held as ORIGINAL SCREENSHOT above Create v1
    Two variants of the same screenshot, mid-stream, with the original pinned underneath.Watch at 5:00
  3. 9

    Read it three ways: Desktop, Mobile, Code

    The preview pane has three switches — Desktop, Mobile and Code — and Code is the one that matters for hand-off, because it shows the raw markup you can copy. Reset throws the run away, Download exports it, and under the variants sit Update (send another instruction), Regenerate (rerun the same one) and Select and update (draw a box over the region you want changed). This is where screenshot-to-code stops being a demo and becomes an editing loop.

    Rebuilt channel banner page rendered inside the Screenshot to Code preview pane, with Desktop, Mobile and Code switches top right and Reset, Download, Regenerate and Select and update around it
    The rebuilt page sitting next to the controls for iterating on it.Watch at 5:20
  4. 10

    Save the markup as a plain .html file

    Copy the code out of the Code tab into a file — test.html in the mycode folder here — and that is the entire build step. The output is self-contained HTML with Tailwind classes, so there is no package install and no dev server between you and the page. If you want it inside a real component tree, paste it into a React or Vue file instead and re-point the class names there.

    Ubuntu Files window in the mycode folder with a 3.1 kB test.html selected and the right-click menu open on Open With Firefox
    One file, 3.1 kB, right-clicked open in Firefox.Watch at 5:40
  5. 11

    Open it from disk and check what survived

    Loading the file straight from the filesystem proves the output runs with no server behind it. Now compare it honestly against the ORIGINAL SCREENSHOT thumbnail: layout, typography and spacing usually carry over well, while third-party logos and photographs are what gets approximated — which is exactly why the README recommends a Gemini key for asset extraction, reusing the real images from the screenshot, and a Replicate key for image generation and background removal. Anything missing is a follow-up instruction, not a rewrite.

    The generated markup opened as a plain local file at file:///home/Ubuntu/mycode/test.html, showing the rebuilt HELPING YOU BECOME AI CLOUD ENGINEER page with no server behind it
    The converted page running from the local filesystem, banner and channel header rebuilt.Watch at 6:12
  6. 12

    Refine with an update prompt instead of regenerating

    Type the change into the box under the variants — "change the background color to deep blue" here — and the app produces a new version rather than a new page, so Versions keeps both: Create v1 and the update as v2. Ticking "Include screenshot of current version?" sends the current render along with the instruction, which is what stops a refinement from drifting back to a generic layout. This loop is the reason the tool is worth installing at all.

    Screenshot to Code Versions list after one refinement, change the background color to deep blue stored as v2 above Create v1 while new HTML streams into the preview
    One instruction later, the update is stored as v2 with v1 still one click away.Watch at 6:45

Route B: DeepSeek reads the image

  1. 13

    Route B: attach the screenshot to DeepSeek

    If you would rather not run anything, DeepSeek takes the image directly in its chat product: the paperclip adds log.PNG, the composer shows it as a 68.14KB attachment, and the instruction is one sentence — "give me html and css code for this image in a single html file". The chip in this recording reads DeepThink (R1); picker labels move faster than tutorials do, so trust the mechanism rather than the label. What comes back is one file you can paste and open.

    chat.deepseek.com composer holding an attached log.PNG of 68.14KB with the DeepThink chip on and the paperclip button used to add the screenshot
    The screenshot attached in DeepSeek's chat, with the single-file instruction typed underneath.Watch at 1:22
  2. 14

    Read the plan before the code

    The thinking panel is where you can tell whether the model actually looked: it enumerates the "Login" heading, the "User Name" and "Password" labels, the input fields and the Submit button, then chooses flexbox with justify-content and align-items centred at 100vh. When a rebuild comes back wrong this is the step to watch — a model that skipped the labels will hand you a form with none. Expand it, and if the description is off, re-crop the screenshot and send it again.

    DeepSeek Thought for 10 seconds panel working through the attached mockup, naming the Login heading, the User Name and Password labels and the Flexbox centering it plans to write
    Ten seconds of reasoning: the model names each element it intends to reproduce.Watch at 1:45
  3. 15

    Preview it, then take the code out

    DeepSeek renders its own answer in a preview modal — the login card rebuilt with stacked labels, two inputs and a full-width blue Submit button, marked "AI-generated, for reference only". It is a simplification rather than a clone: the mockup's gradient blobs and field icons are gone. Copy the HTML out, save it as index.html and open it, exactly as in steps 10 and 11. Worth stating plainly: DeepSeek's chat product and its API both accept images, but text-only generators — including this site's own artifact generator — do not, so describe the UI in words there instead of expecting it to see your screenshot.

    DeepSeek HTML preview modal showing the rebuilt login card with User Name and Password fields and a full-width blue Submit button, captioned AI-generated for reference only
    The rebuilt card inside DeepSeek's preview — close enough to build on, simplified enough to check.Watch at 2:48

Screenshot to code and DeepSeek vision FAQ

Keep going