Screenshot to Code turns a picture of an interface into front-end code. Upload a screenshot, a Figma export or a screen recording of a site in use, choose a stack (HTML with Tailwind or CSS, React, Vue, Bootstrap or Ionic), and vision models from OpenAI, Anthropic or Google write the page. With a Gemini key it reuses the real logos and images from your screenshot, with a Replicate key it can generate or edit images, and with Chromium installed the agent renders its own output in a headless browser to check its work. You can compare variants from several models side by side and keep iterating in chat.
Abi Raja built it in November 2023, when a demo of it recreating sites from screenshots went viral on X, and it has stayed popular since, with about 80,000 stars. It is MIT-licensed, made of a FastAPI backend and a React frontend, and sits beside a hosted product at screenshottocode.com run by the same author.
- Repository: github.com/abi/screenshot-to-code
- Licence: MIT (MIT License)
- Language: Python. Stars: 79.9K. Forks: 9,769. Last push: Sep 29, 2026.
- Scan: safe, Jul 30, 2026, commit d026163
Who it is for
Front-end developers who want a head start on a layout, designers who want to see a mockup as real HTML, and anyone cloning the look of a page for a prototype.
Getting started
1. Docker: add at least one model key, then build and start (open http://localhost:5173)
echo "OPENAI_API_KEY=sk-your-key" > .env && docker-compose up -d --build2. Or run the backend with Poetry, after putting your keys in backend/.env
cd backend && poetry install && poetry run playwright install chromium && poetry run uvicorn main:app --reload --port 70013. Then the frontend, in a second terminal
cd frontend && pnpm install && pnpm devYou need an OpenAI, Anthropic or Gemini API key, and the author strongly recommends Gemini plus Replicate for best results; every generation is billed by those providers. Ollama works with a community workaround, though the README warns the results are poor.
Safety scan
We cloned abi/screenshot-to-code at commit d026163 on Jul 30, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.
- No secrets, no pattern hits, no committed binaries and no install hooks across 315 files and about 42,000 lines of Python and TypeScript.
- We read the third-party calls. Plausible analytics and the email sign-up form (posting to buildpicoapps.com) are only included when VITE_IS_DEPLOYED is set, which is the hosted screenshottocode.com build; a self-hosted copy does not load them. Screenshot capture of a URL uses ScreenshotOne only if you add its key.
- backend/main.py allows CORS from any origin and the API has no login, so any page open in your browser could reach a backend on localhost:7001 and spend your model keys. Run it only while you use it, and do not publish the Docker port beyond your machine.
- 150 known advisories across 947 packages (3 critical, 69 high). In the backend's poetry.lock (90 packages, 94 advisories), Pillow 10.4.0 carries a long list of out-of-bounds and decompression-bomb issues, and the app does parse the images you upload; anyio and h11 add the two criticals. The frontend's critical is Vitest, a test runner.
- No workflows and no tagged releases; the scanned commit is from July 2026. Licence present; no security policy, Dependabot, CodeQL or contributing guide.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | None found. |
| Suspicious code | None found. |
| Install-time code | None: nothing runs at install beyond the package manager itself. |
| Committed binaries | None. |
| CI workflows | No GitHub Actions workflows. |
| Network hosts | 24 distinct hosts referenced from source; most often replicate.delivery, cdn.jsdelivr.net, unpkg.com, cdn.tailwindcss.com. No URLs to bare IP addresses. |
| Known vulnerabilities | 150 advisories across 947 pinned packages: 3 critical, 69 high, 60 moderate, 18 low. backend/poetry.lock: 90 packages, 94 advisories; frontend/pnpm-lock.yaml: 857 packages, 56 advisories. |
| Project hygiene | Has licence file. Missing security policy, automated dependency updates, CodeQL, contributing guide. |
| OpenSSF Scorecard | Not scored: the project is not in Scorecard's weekly index. |
The raw findings
Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.
Worst known vulnerabilities (24 of 150)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-82r6-8w77-94w6 | critical | anyio@4.9.0 | AnyIO: TLSStream IDNA 2003 host name encoding enables potential TLS certificate spoofing |
| GHSA-vqfr-h8mv-ghfj | critical | h11@0.14.0 | h11 accepts some malformed Chunked-Encoding bodies |
| GHSA-5xrq-8626-4rwp | critical | vitest@1.6.1 | When Vitest UI server is listening, arbitrary file can be read and executed |
| GHSA-6mq8-rvhq-8wgg | high | aiohttp@3.11.11 | AIOHTTP's HTTP Parser auto_decompress feature is vulnerable to zip bomb |
| GHSA-cq5v-8q36-5273 | high | aiohttp@3.11.11 | AIOHTTP: Out-of-bounds heap read in C HTTP response parser error path (malformed chunked response) |
| GHSA-47fr-3ffg-hgmw | high | click@8.1.7 | |
| GHSA-45hq-cxwh-f6vc | high | pillow@10.4.0 | Pillow `BdfFontFile`: `Image.new()` called without `_decompression_bomb_check()` - bomb protection bypass via font loadi… |
| GHSA-5x94-69rx-g8h2 | high | pillow@10.4.0 | Pillow: `FontFile.compile()`: `Image.new()` called without `_decompression_bomb_check()` |
| GHSA-62p4-gmf7-7g93 | high | pillow@10.4.0 | Pillow: Out-of-bounds read via attacker-controlled row stride on Pillow's mmap path (McIdas AREA files) |
| GHSA-6r8x-57c9-28j4 | high | pillow@10.4.0 | Pillow: Heap out-of-bounds write `Image.paste()` / `Image.crop()` via signed coordinate overflow |
| GHSA-8v84-f9pq-wr9x | high | pillow@10.4.0 | Pillow `PcfFontFile._load_bitmaps()`: `Image.frombytes()` called without `_decompression_bomb_check()` - bomb protection… |
| GHSA-9hw9-ch79-4vh6 | high | pillow@10.4.0 | Pillow: Controlled heap out-of-bounds write in Pillow `ImageCmsTransform.apply()` via output mode mismatch |
| GHSA-cfh3-3jmp-rvhc | high | pillow@10.4.0 | Pillow affected by out-of-bounds write when loading PSD images |
| GHSA-jjj6-mw9f-p565 | high | pillow@10.4.0 | Pillow: Decompression Bomb DoS via PdfParser.PdfStream.decode() |
| GHSA-phj9-mv4w-65pm | high | pillow@10.4.0 | Pillow `GdImageFile._open()`: image dimensions accepted without `_decompression_bomb_check()` |
| GHSA-pwv6-vv43-88gr | high | pillow@10.4.0 | Pillow has an OOB Write with Invalid PSD Tile Extents (Integer Overflow) |
| GHSA-vjc4-5qp5-m44j | high | pillow@10.4.0 | Pillow JPEG2000 tiled decode retains a growing scratch buffer and can be used for denial of service |
| GHSA-whj4-6x5x-4v2j | high | pillow@10.4.0 | FITS GZIP decompression bomb in Pillow |
| GHSA-xj96-63gp-2gmr | high | pillow@10.4.0 | Pillow: Heap out-of-bounds write in `ImageFilter.RankFilter` via integer overflow in `ImagingExpand` |
| GHSA-7gcm-g887-7qv7 | high | protobuf@5.29.5 | protobuf affected by a JSON recursion depth bypass |
| GHSA-63vm-454h-vhhq | high | pyasn1@0.6.1 | pyasn1 has a DoS vulnerability in decoder |
| GHSA-8ppf-4f7h-5ppj | high | pyasn1@0.6.1 | pyasn1: Quadratic complexity in OBJECT IDENTIFIER and RELATIVE-OID processing allows denial of service |
| GHSA-hm4w-wwcw-mr6r | high | pyasn1@0.6.1 | pyasn1: Uncontrolled resource consumption when converting decoded REAL values |
| GHSA-jr27-m4p2-rc6r | high | pyasn1@0.6.1 | Denial of Service in pyasn1 via Unbounded Recursion |
By the numbers
| Stars | 79.9K |
|---|---|
| Forks | 9,769 |
| Contributors | 29 |
| Commits | 1,455 |
| Open issues | 126 |
| Open pull requests | 22 |
| Releases | 0 |
| Latest release | none tagged |
| Licence | MIT |
| Main language | Python |
| Project age | 2 years |
| Last push | Sep 29, 2026 |
| Tracked files | 315 |
| Lines of code | 42.2K |
| Checkout size | 3 MB |
Lines by language: Python 21.5K, TypeScript 18.3K, Markdown 1,375, HTML 239, JSON 238, CSS 238.
Questions
Is Screenshot to Code free?
The self-hosted app is MIT-licensed and free, but it calls paid model APIs with your own keys, so each generation costs a little. The hosted version at screenshottocode.com is a separate commercial service with its own pricing that needs no keys or setup.
How good is the code it produces?
Good for a starting point: layout, spacing, colours and text usually land close to the original, especially with the strongest models. It produces static front-end code, so interactions, data loading and accessibility still need a developer, and complex apps come out as approximations.
Can it copy any website?
Technically it can reproduce the look of most pages from a screenshot. Legally, copying another company's design, logos or content for your own product can infringe copyright or trademarks, so use it for your own designs, prototypes and learning.
This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.
