Open source/By GeekyAnts/v0.1
One prompt. Three native apps.
Describe what you want to your coding agent. It builds the same app in SwiftUI, Jetpack Compose and TanStack Start, from one spec, with no cross-platform runtime in between.
npm create geeknative@latest my-app -- --name "My App" --id com.acme.myappBuilt natively with
- SwiftUI
- Jetpack Compose
- TanStack Start
- Navigation 3
- Observation
- Tailwind CSS
- Swift Testing
- Vitest
01The idea
Cross-platform apps, without cross-platform technology.
One spec.
Three native codebases.
Your agent keeps them in step.
Cross-platform frameworks trade native feel for shared code. geeknative keeps the native code and shares everything else: the product spec, the design tokens, the copy and the tests. The agent writes SwiftUI for iOS, Compose for Android and React for the web, and the shared contracts keep the three apps the same product.
- Prompt
- 1
- Native apps
- 3
- Bridges or shared runtimes
- 0
- Framework tests
- 58
02Real apps
The same app, built three times.
These are screenshots of the starter app every project begins with: SwiftUI on iOS, Compose on Android, React in Chrome. Same screens, same copy, same tokens. Native controls everywhere.

iOS 26/SwiftUI

Chrome/TanStack Start

Android 15/Jetpack Compose
03How it works
A prompt becomes a spec. A spec becomes three apps.
AGENTS.md teaches any coding agent the same loop: work out what you asked for, write it down once, then build it natively three times and prove it.
Fig. 03.1 · The loop, carried by the colony
The loop
Every request, every time.
- 01
Update the source of truth
The spec, PRODUCT.md, DESIGN.md or a contract changes first, so every app builds against the same description.
- 02
Regenerate
make gen compiles the contracts into Swift, Kotlin, Android resources and TypeScript. Nobody edits generated code.
- 03
Build on each platform
Each app follows its own AGENTS.md. Agents that support sub-agents build the three apps in parallel.
- 04
Verify
make check builds and tests every app. The agent keeps going until all three pass.
- 05
Record and report
Each platform's status goes into the spec, make parity updates the coverage table, and the agent reports one line per platform.
04Triage
Just talk. The agent sorts it out.
No commands to learn. The agent states how it read your request in one line before it touches anything, so you can correct it early:
Feature: notes list → spec/features/notes.md, strings · iOS, Android, Web
- Product
“Build a habit tracker for runners.”
PRODUCT.md, DESIGN.md, navigation, feature specs
- Feature
“Add a notes list where I can add and delete notes.”
A new spec/features/notes.md
- Behavior
“Sort notes by date instead.”
That feature's spec
- Design
“Make it feel warmer, with rounder corners.”
DESIGN.md and contracts/tokens.json
- Copy
“Rename Save to Done.”
contracts/strings, then make gen
- Bug
“Deleting the last note crashes.”
The spec, only if it was silent or wrong
- Platform-specific
“On iPhone, add a haptic when deleting.”
The spec's Platform notes; iOS only
- Engineering
“Upgrade Compose to the latest BOM.”
Nothing in the spec
- Question
“Why does Android use radio buttons here?”
Nothing: the agent answers
05Contracts
Write it once. Compile it three ways.
App identity, design tokens, copy and icons live in contracts/. make gen turns them into code for each app, so a color, a string or a version number can't drift.
"color": {
"primary": { "light": "#4F46E5", "dark": "#A5B4FC" }
},
"spacing": { "md": 12 },
"typography": {
"title": { "size": 20, "weight": 600,
"ios": "title3", "android": "titleLarge" }
}static let primary = Color(light: 0x4F46E5FF,
dark: 0xA5B4FCFF)
static let md: CGFloat = 12
static let title: Font = .title3.weight(.semibold)primary = Color(0xFF4F46E5),
val md = 12.dp
val title = TextStyle(fontWeight = FontWeight.SemiBold,
fontSize = 20.sp, lineHeight = 26.sp)--color-primary: #4f46e5;
--spacing-md: 12px;
--text-title: 1.25rem;
.dark { --color-primary: #a5b4fc; }Fig. 05 · make gen writes these. Nobody edits them by hand, and make check fails if they drift.
06Parity
Tests carry the spec. Parity is a table, not a hope.
Specs number their acceptance criteria. Each app's tests name the criteria they cover, and make parity turns that into a table. Gaps show up before users find them.
Fig. 06 · The starter app's acceptance criteria, as make parity reports them
$ make check✔ contracts valid, generated files up to date▸ ios building and testing on iPhone 17 Pro (iOS 26.3)…✔ ios build and 4 tests passed (60s)▸ android building and running unit tests…✔ android build and 4 unit tests passed (0s)▸ web type-checking, testing and building…✔ web types, 6 tests and build passed (3s)
Real output from the starter app. Logs land in .geeknative/logs, so agents read a short summary and open the full log only when something fails.
07Agents
Bring the agent you already use.
geeknative is plain files in your repo. The instructions follow the AGENTS.md convention, and Claude Code gets extra wiring on top.
- Claude CodeReads AGENTS.md through one-line CLAUDE.md imports. ios-engineer, android-engineer and web-engineer subagents build in parallel. Hooks regenerate code when a contract changes, and flag a turn that changed only some of the apps.Subagents + hooks
- CodexReads AGENTS.md at the root and in each app, and runs the same make targets.AGENTS.md
- CursorPicks up the root and per-app AGENTS.md files as project rules.AGENTS.md
- GitHub CopilotThe coding agent follows AGENTS.md in pull requests it opens.AGENTS.md
- Gemini CLIThe project setting points Gemini CLI at AGENTS.md instead of GEMINI.md..gemini/settings.json
- Your agentMarkdown instructions, a Makefile, and a CLI with short output and full logs. Nothing to install into the agent.Plain files
Start
Start in a minute.
Create a project, run make doctor and make check, then open it in your coding agent and describe the app you want.
npm create geeknative@latest my-app -- --name "My App" --id com.acme.myapp







