A Claude Code agent that turns a natural-language spec — something as informal as "a walk-in queue for a barbershop" — into a working three-platform implementation:
- Rails 8.1 API
- native SwiftUI iOS
- native Jetpack Compose Android
Coherent across all three, in under an hour.
Status: Hackathon build. Developed during Built with Opus 4.7: a Claude Code Hackathon (April 21–27, 2026). Active development in progress — expect breaking changes through the end of April.
Most "AI builds an app" tools stop at a single web frontend. The real pain for anyone shipping a mobile product is that the same domain has to be implemented three times — multi-tenant Rails API, native iOS, native Android — each with its own idioms, and keeping them consistent is where weeks disappear.
Classic mobile boilerplates sell "save 12–16 weeks of setup." AI coding tools have compressed that value to 2–3 weeks of AI-assisted work. The durable problem that remains — even with AI — is cross-platform coherence: keeping a Rails API, a native iOS client, and a native Android client all consistent under iteration, with no contract drift, no forgotten rename, no divergent localized copy.
This agent is an answer to that: turn a boilerplate into a generator that produces coherent three-platform implementations on demand, with structural and semantic validation built in.
Point the agent at a natural-language spec:
a walk-in clinic queue for small veterinary practices
It will:
- Parse the spec into a structured domain (entities, fields, relationships, state machines).
- Copy the free-edition substrate (three MIT-licensed repos covering Rails + iOS + Android) into
./out/<spec-slug>/{rails,ios,android}/. - Rename the skeleton —
Shop → Clinic,Shopkeeper → Vet, etc. — consistently across Ruby migrations, Swift models, Kotlin data classes, policies, tests, and localized copy. - Adapt or replace the domain module — keep
ItemTagfor walk-in queue variants; strip and insert a new resource for non-queue SaaS. - Drive the build green —
bin/rails test,xcodebuild test,./gradlew testmust all pass before the agent exits. - Validate the output across three layers (structural, runtime, semantic). Details in
docs/SPEC.mdsection 6.
Three demo specs, both adapt and replace paths, all four validation layers green end-to-end:
| Spec | Domain entity (post-rename) | Path | Result |
|---|---|---|---|
"a walk-in clinic queue for small veterinary practices" |
ItemTag → Patient, Shop → Clinic, Shopkeeper → Vet |
adapt | Layer 1 3/3 · Layer 2 3/3 · Layer 3 2/2 · Reviewer PASS |
"a restaurant waitlist for casual dining" |
Shop → Restaurant, Shopkeeper → Host |
adapt | Layer 1 3/3 · Layer 2 3/3 · Layer 3 2/2 · Reviewer PASS |
"a personal task tracker with due dates" |
ItemTag → Todo (replaces queue entry entirely) |
replace | Layer 1 3/3 · Layer 2 3/3 · Layer 3 2/2 · Reviewer PASS |
Layer 2 ran in build mode — real xcodebuild build and ./gradlew assembleDebug, full app builds installed on iPhone 17 simulator and Android emulator. Layer 3 captured the home-screen via xcrun simctl io booted screenshot / adb exec-out screencap and judged against the rubric using Opus 4.7 vision (median of 3 samples per criterion).
The agent works on either the free (MIT) edition or the paid edition without code changes — the same pipeline handles both substrates; multi-tenant features (org switching, invitations, role permissions) survive the rename pipeline when targeting paid.
![]() iOS — Vet Clinic Queue welcome screen |
![]() Android — Vet Clinic Queue welcome screen |
Both screenshots are real captures from the booted iOS Simulator and Android emulator post-./gradlew assembleDebug / xcodebuild build, after the agent installed and launched the generated app.
flowchart LR
Spec["Natural-language spec<br/>(e.g. walk-in clinic queue)"] --> Agent
subgraph Agent["Claude Code Agent · Opus 4.7"]
Planner --> Workers
Workers --> Reviewer
Reviewer --> Judge
end
Substrate[("Free-edition substrate<br/>Rails · iOS · Android<br/>READ-ONLY")] -. copy .-> Out
Agent --> Out["./out/[slug]/<br/>rails / ios / android"]
Out --> L1["Layer 1 — Structural"]
L1 --> L2["Layer 2 — Runtime + mobile-mcp"]
L2 --> L3["Layer 3 — Vision judge"]
The agent operates on the free, MIT-licensed edition of NativeAppTemplate — three public repos:
| Repo | Stack | LOC |
|---|---|---|
nativeapptemplateapi |
Rails 8.1, PostgreSQL, devise_token_auth, pundit, acts_as_tenant |
7,687 (Ruby) |
NativeAppTemplate-Free-iOS |
100% SwiftUI, @Observable, MVVM, Liquid Glass design, iOS 26.2+ |
15,311 (Swift) |
NativeAppTemplate-Free-Android |
100% Kotlin, 100% Jetpack Compose, Hilt, Retrofit2, API 26+ | 19,521 (Kotlin) |
Combined ~42.5k LOC. Extracted from MyTurnTag Creator, a walk-in queue-management SaaS live on both app stores since 2024.
Not yet functional — hackathon build in progress. The interface below is the target;
npxwon't work until v0.1 ships at the end of hackathon week.
# Standalone CLI — must-have for the hackathon demo
npx nativeapptemplate-agent "a walk-in clinic queue for small veterinary practices"
# Stretch specs the agent is also designed to handle
npx nativeapptemplate-agent "a restaurant waitlist for casual dining"
npx nativeapptemplate-agent "a personal task tracker with due dates"
# Generated output appears under ./out/<slug>/
tree ./out/clinic-queue/
# ├── rails/ ← Rails 8.1 API, git-initialized, buildable
# ├── ios/ ← SwiftUI iOS project, buildable
# └── android/ ← Jetpack Compose Android project, buildableThe agent will also be available as a Claude Code plugin.
- Node.js 22+
- Claude Agent SDK v0.2.111 or later (needed for Opus 4.7)
- An Anthropic API key with access to
claude-opus-4-7, exported asANTHROPIC_API_KEY:The Anthropic SDK reads this env var automatically; no other config is required. See Security below for storage recommendations.export ANTHROPIC_API_KEY="sk-ant-..."
- Local checkouts of the three substrate repos, referenced via environment variables:
A starter
export NATIVEAPPTEMPLATE_API="/path/to/nativeapptemplateapi" export NATIVEAPPTEMPLATE_IOS="/path/to/NativeAppTemplate-Free-iOS" export NATIVEAPPTEMPLATE_ANDROID="/path/to/NativeAppTemplate-Free-Android"
/.env.examplelists all the variables in one place. - For runtime validation (Layer 2 onwards): Xcode 26.3+ with iOS 26.2+ simulator, Android SDK with API 26+ emulator
- For UI automation:
mobile-next/mobile-mcp(installed automatically as a Claude Code MCP server)
NATIVEAPPTEMPLATE_VISUAL=1— opts the run into Stage 1 visual judging (Layer 3). When set, Layer 2 runs in build mode instead of fast mode (fullxcodebuild build+./gradlew assembleDebug), then for each platform the agent installs the app on the booted sim/emulator, captures the home screen, and judges it with Opus 4.7 vision againstDEFAULT_STAGE1_RUBRIC. Adds 60-180s per platform depending on cold-build time. Requires a sim/emulator booted for each platform you want judged. Off by default —npm run devkeeps the existing fast path.NATIVEAPPTEMPLATE_AGENT_ANTHROPIC_KEY— dedicated workspace key, see Security.ANDROID_SERIAL— when more than one Android device/emulator is attached (e.g. a physical device plus a running emulator),adbstandard practice is to setANDROID_SERIAL=<serial>to disambiguate. The agent honors this transparently because it runsadbdirectly. Runadb devicesto list serials. Visual-judge runs with multiple Android targets attached will error withmore than one device/emulatorif this isn't set.
The agent resolves adb to a known-good binary in this priority order: $ANDROID_HOME/platform-tools/adb, $ANDROID_SDK_ROOT/platform-tools/adb, ~/Library/Android/sdk/platform-tools/adb (Android Studio default), /Applications/android-sdk-macosx/platform-tools/adb, /opt/homebrew/bin/adb, /usr/local/bin/adb, then PATH. This avoids surprises like a stale ~/.apportable/SDK/bin/adb (i386, won't exec on Apple Silicon) shadowing a working adb on PATH.
The agent doesn't just generate code and exit — it validates the output.
- Structural.
ripgrepfor leftover domain tokens; OpenAPI contract parity check between Rails, iOS networking, and Android repository layers. A silent rename inconsistency fails the run before any tests execute. - Runtime. Boot the generated Rails server; build and launch iOS and Android apps; drive a scripted CRUD scenario via
mobile-next/mobile-mcp. Any 4xx/5xx or unhandled client error fails the run. - Semantic. Opus 4.7 as judge — scores whether the generated code and rendered UI actually express the intended domain. Vision judges read simulator/emulator screenshots directly.
See docs/SPEC.md for the full design.
ANTHROPIC_API_KEY is the only sensitive secret the agent needs.
Workspace isolation (optional but recommended). If you also use Claude Code or other Anthropic SDK apps, create a dedicated workspace with its own key + spend cap and export it as NATIVEAPPTEMPLATE_AGENT_ANTHROPIC_KEY. The agent prefers that var over ANTHROPIC_API_KEY when set, so a runaway loop hits the workspace cap instead of your overall tier limit, and revoking it doesn't break Claude Code login.
Recommended storage (best to most convenient):
- macOS Keychain via 1Password CLI —
op read "op://Personal/Anthropic/key"resolved at session start; no key on disk in plaintext. direnv— per-project.envrc, loaded only when youcdin. Keep.envrcoutside any git-tracked dotfiles repo, or.gitignoreit.- A gitignored secrets file sourced from your shell rc — e.g.
[ -r ~/.config/zsh/secrets.zsh ] && source ~/.config/zsh/secrets.zsh. Setchmod 600on the file. .envnext to the project — copy.env.exampleto.env(already gitignored along with.env*.local) and the agent loads it on startup. Shell exports take precedence over.env, so you can override per-run withFOO=x npm run dev. Lowest friction; easiest to leak — avoid in shared repos.chmod 600 .envon shared machines.
Don't paste a real key into shell history (HISTFILE captures it), commit a .env, or echo the key into a non-private channel.
The agent strips ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, and NATIVEAPPTEMPLATE_AGENT_ANTHROPIC_KEY from the environment of every subprocess it spawns — Ruby scripts, git, psql, xcodebuild, gradlew, the future mobile-mcp client. Keys are only seen by the Anthropic SDK in the Node process. Set spend limits on your API workspace as a backstop, and rotate the key if you suspect leak.
docs/SPEC.md— full technical specificationROADMAP.md— where this project is headed, OSS vs hosted, what stays out of scopeCLAUDE.md— Claude Code project instructions (read if you're running Claude Code against this repo)
During hackathon week (April 21–27, 2026) the repository moves quickly and breaking changes are expected. After that, contributions are welcome via standard GitHub issues and PRs. A CONTRIBUTING.md with detailed guidelines will land once the hackathon dust settles.
If you spot something broken before then, feel free to open an issue — just don't be surprised if the fix lands as part of a larger rewrite.
MIT. See LICENSE.
- Anthropic for Claude Opus 4.7 and Claude Code
- Cerebral Valley for running the hackathon
mobile-next/mobile-mcpfor making mobile UI automation actually workable from an agent- MyTurnTag Creator users, whose real-world queue management taught me which abstractions survive and which don't
Built solo in Tokyo.

