You point your coding agent at a folder of screenshots. It works out the screens, the navigation, and the design system, then writes a runnable Expo / React Native project that reproduces them.
Todoist, Google Keep, and Spendee, rebuilt from screenshots and running on the iOS simulator. The lists persist on the device. They are not static mockups.
A website hands you its source. Open the dev tools and the DOM, the CSS, the fonts, and the asset URLs are all sitting right there. A phone app gives you none of that. There is no markup to read and no stylesheet to copy, only the pixels on the screen.
So screenshots are the input, because they are the one thing you can capture from any app without jailbreaking it, decompiling it, or installing anything. The same folder of PNGs works whether the app runs on iOS or Android.
The hard part is that an image has no numbers in it. You cannot read "16px padding" off a screenshot. That is why the core of the tool is a diff loop: it builds a screen, renders it, screenshots its own output, compares that against your screenshot, and fixes the differences. It repeats until the two match. That loop is doing the measuring the DOM would have handed you for free on the web.
git clone https://github.com/Birkenpapier/ai-app-cloner
cd ai-app-cloner
npm install
npx playwright install chromium # one-time, used by npm run verify
npm run web # the blank template should boot in a browser tab
git checkout -b my-clone # the clone builds into this repo, so keep main pristine
Then, inside your coding agent (Claude Code is the reference setup):
- Connect a browser automation MCP (Chrome, Playwright, or Puppeteer). The diff loop cannot run without it, since it is how the agent screenshots the clone while it builds.
- Drop screenshots into
docs/screenshots/
. Seefor what to capture and how to name files so the agent can tell one screen from another.docs/screenshots/README.md
- Run
/clone-app
.
Want to see a finished result first? Each demo/*
branch holds a complete clone:
git checkout demo/todoist
(or demo/keep
, demo/spendee
).
The /clone-app
skill is generated for every major AI coding agent from one source
of truth (.claude/skills/clone-app/SKILL.md
for the command, AGENTS.md
for the
project rules). After editing the source, run node scripts/sync-skills.mjs
and
bash scripts/sync-agent-rules.sh
to regenerate the per-agent files.
| Agent | How it runs |
|---|---|
| Claude Code | /clone-app (reference implementation) |
| Codex CLI | /clone-app |
| Cursor | /clone-app command |
| Windsurf | /clone-app workflow |
| Gemini CLI | /clone-app |
| GitHub Copilot | .github/ skill + instructions |
| Cline | reads .clinerules |
| Roo Code | reads AGENTS.md |
| Continue | /clone-app command |
| OpenCode | /clone-app |
| Amazon Q | clone-app agent |
| Augment Code | /clone-app command |
| Aider | reads AGENTS.md |
Claude Code is the only one verified end to end so far. The rest use each agent's documented config format, generated from the same source. Reports from other agents are welcome.
The repo you clone is a blank Expo app. Running /clone-app
fills it in:
- screens go into
src/app/
(Expo Router) - components go into
src/components/
- the design tokens go into
tailwind.config.js
andsrc/lib/tokens.ts
- the agent's analysis (screen map, navigation graph, per-screen specs) goes into
docs/research/
So the output is this project, now holding your clone. There is no separate export
step. If you would rather see a finished result before running anything, each
demo/*
branch contains one complete clone.
screenshots/ βββΆ cluster into βββΆ infer navigation βββΆ app-spec.json
(app states) screens & states graph (tabs/stack) (the IR)
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΌ
foundation per-screen spec visual-diff loop assembled
(tokens, nav) βΆ + builder agents βΆ renderβshotβdiffβfix βΆ Expo app
(parallel, worktrees) (until it matches)
The whole engine is one file written in plain English: .claude/skills/clone-app/SKILL.md.
Partway through, it writes app-spec.json
, a description of the app (tokens, navigation, screens, states) that never mentions React Native. That is on purpose. The RN generator reads it today; the native targets on the roadmap will read the same file. Its shape is documented in docs/research/app-spec.schema.json, with a worked
The three clones at the top are built from screenshots of real apps, so you can judge the output against something you already know:
| Clone | Original | What it shows off |
|---|---|---|
| Todoist | ||
Google KeepSpendeeThey exist to demonstrate the tool, not to be shipped. See Legal and ethics.
| Mode | Input | Fidelity | Notes |
|---|---|---|---|
| Screenshots (the main use) | |||
| a folder of app-state screenshots | visual parity via the diff loop | any app, iOS or Android, nothing to install | |
| Web β RN (bonus) | |||
| a web app URL | exact, from the DOM and real assets | for turning a web app into React Native |
Expo SDK 56, Expo Router (file-based screens), React Native 0.85, NativeWind (Tailwind syntax), TypeScript strict.
Each stage reads the same app-spec.json
, so a new target is a new code generator, not a new pipeline.
| Version | Input | Output | Status |
|---|---|---|---|
| v1 | |||
| screenshots of an app | Expo / React Native | β shipping now | |
| v1 | |||
| a web app URL | Expo / React Native | β bonus mode | |
| v2 | |||
| screenshots of an app | native SwiftUI and Jetpack Compose | π next | |
| v3 | |||
| a decompiled APK | native, with exact values recovered | π§ planned |
This reverse-engineers an app from its pixels, and the README is not going to pretend otherwise:
Screenshot mode has no exact values. Spacing and colors are best-effort, and the diff loop is what closes the gap. Web mode gets exact values from the DOM.Assets are baked into the pixels. Logos, app icons, and photos are re-created (icons via lucide) or cropped as raster, never recovered as real files. Web mode can download the real assets.Coverage equals what you capture. A screen or state you never screenshotted cannot be cloned.No backend. Data is mocked or kept on device. Every server call is a typed stub marked// TODO: wire backend
.
Clone apps you own, apps you have permission to clone, or clone for learning and prototyping. Do not pass a clone of someone else's app off as your own product, and respect trademarks, app-store rules, and the original's terms. What you build with this is on you.
The tool reproduces layout and behavior, not brand assets. Icons are re-created rather than copied, and it never redistributes an app's original image or logo files. Reproducing a specific commercial app's look pixel-for-pixel can still raise copyright, trade-dress, and design-patent questions, so clone responsibly and get legal advice before publishing a clone of a named product.
The demos here are for demonstration only. This project is not affiliated with, endorsed by, or sponsored by any app or company shown. All product names, logos, and trademarks belong to their respective owners.
MIT, see LICENSE. Made by Birkenpapier.