Ship a Next.js + Android product on Firebase without spending your first week deciding auth, quotas, billing and CI.
GreenField is an operating manual for AI coding agents: 104 notes of prescriptive standards, 22 decision records, and 61 copy-ready configuration files. You point an agent at it; the agent builds the product.
Starter kits hand you a running page and leave every expensive decision open:
- How does auth work across a browser and an Android app, from one user record?
- Where are model provider keys allowed to exist, and who enforces the spend limit?
- What happens when a billing webhook is delivered twice?
- Which side owns the schema when the web app and the Android app disagree?
- What has to be true before the Play Store lets you publish at all?
You answer these under deadline pressure, once per product, usually wrong the first time. An AI agent asked to answer them will invent something plausible and different every run.
GreenField answers them once, in writing, and hands the answers to the agent as a contract.
Not a demo app. Not a one-click starter that pretends to ship a finished product.
It is a manual with a materializer: locked architectural decisions, runbooks whose order matters, and templates that write your repository's configuration contract.
| GreenField gives you | Your agent builds next |
|---|---|
| Standards, ADRs, and runbooks | Domain schemas and product UI |
| Materialized config and CI contracts | Web routes, Android modules, tests |
| Security rules, Auth/App Check posture | Capability phases (billing, AI, voice) |
An AGENTS.md the agent must obey |
The product itself |
Materialization writes 61 files. No application source — configuration, contracts, and the agent's instructions:
my-product/
├── AGENTS.md the contract your agent must obey
├── package.json pnpm workspace + Turborepo pipeline
├── packages/contracts/ Zod + JSON Schema — cross-platform source of truth
├── apps/web/ Next.js: middleware, Vitest, Playwright, App Hosting
│ ├── apphosting.yaml production backend config
│ ├── apphosting.staging.yaml staging backend config
│ └── tests/rules/ Firestore rules tests, running against the emulator
├── apps/android/ Gradle multi-module, version catalog, detekt,
│ └── build-logic/ a convention plugin that keeps the domain layer pure
├── firebase/ firestore.rules, storage.rules, indexes, project aliases
├── .github/workflows/ web-checks, android-checks, contract-drift,
│ deploy-rules, release-android
├── .cursor/skills/ add-contract-field, bump-prompt-version, release-android
├── docs/ the manual itself — 104 notes, now yours
└── .greenfield-origin which commit of the manual this product came from
contract-drift.yml is the one worth noticing: contracts are defined once in Zod and generated into TypeScript, Kotlin and JSON Schema, and CI fails when a generated artifact stops matching its source. The two clients cannot silently disagree about a payload shape.
Every choice that constrains the architecture has a record, and every record states its costs. Abridged from ADR-0002:
Decision. The Next.js application's route handlers are the only server. Android is an HTTP client of the same endpoints the web app calls.
Easier. One implementation of every rule — a quota change is one file. One deployment for all server logic, one rollback.
Harder. Android depends on the web app's availability: a web outage is an Android outage. Cold starts affect Android too, which is why production runs
minInstances: 1.Rejected. Cloud Functions as the shared backend; a separate Cloud Run API; Android talking to Firestore directly; duplicating logic in both clients.
That last section is the point. You can disagree with a decision, but you will not rediscover it by accident three months in, and neither will your agent.
One monorepo. Two clients. One backend.
| Layer | Choice |
|---|---|
| Repo | pnpm + Turborepo |
| Web + API | Next.js App Router on Firebase App Hosting — the only backend |
| Android | Kotlin + Jetpack Compose; pure domain layer |
| Backend data | Firebase Auth, Firestore, App Check (staging + production projects) |
| Contracts | Zod schemas → TypeScript, Kotlin, JSON Schema; CI fails on drift |
| AI (optional) | Server-side provider ports, versioned prompts, metered quotas |
| Billing (optional) | Stripe + Play Billing → one entitlement model |
flowchart TB
subgraph repo ["One repository (pnpm + Turborepo)"]
contracts["packages/contracts<br/>Zod + JSON Schema"]
web["apps/web<br/>Next.js App Router"]
android["apps/android<br/>Compose, multi-module"]
end
contracts -->|"codegen TypeScript"| web
contracts -->|"codegen Kotlin"| android
web -->|"push to main"| ah["Firebase App Hosting"]
android -->|"tag + CI"| play["Play Console"]
android -->|"HTTPS bearer ID token"| api["apps/web route handlers<br/>the only server"]
api --> fs["Firestore"]
api --> models["Model providers"]
mkdir my-product && cd my-product
git clone --depth 1 https://github.com/diegoalvarezmgl/greenfield.gitAsk something like:
Read
greenfield/AGENTS.mdand bootstrap this product with GreenField.
That file is the entry contract. The agent follows the bootstrap recipe and runbook; materialization prepares configuration, then later phases create the application code.
Optional — install the bundled skill so you do not even need to name the file:
ln -s "$PWD/skills/greenfield-bootstrap" ~/.agents/skills/greenfield-bootstrapFollow Runbook-Bootstrap-New-Product. Outline:
cp -R greenfield/vault ./docs
# write product.json — name, ids, which optional modules you want, then:
node docs/90-Templates/materialize.mjs --answers product.json --dry-run
node docs/90-Templates/materialize.mjs --answers product.json
rm -rf greenfield
git init--dry-run is mandatory: it reports unresolved placeholders before writing about fifty files. The clone is scaffolding — discard it before git init. Keep .greenfield-origin so advisories against this manual can be matched to your copy later.
- You want a different stack. Android and Firebase are not optional; materialization refuses a web-only product. AI, billing, and realtime voice are the only modules you can decline.
- You want to weigh options. Every note prescribes exactly one way. Alternatives exist only as rejected options inside an ADR.
- You have an existing codebase. This bootstraps a repository from nothing. There is no migration path.
- You want a running feature in five minutes. Materialization produces configuration that builds and checks; the product is what your agent writes afterwards.
| Path | Role |
|---|---|
vault/ |
The manual — an Obsidian vault, 104 notes |
vault/90-Templates/ |
61 config templates + the executable materializer |
vault/91-Runbooks/ |
Ordered procedures (bootstrap, release, incidents) |
vault/12-Decisions/ |
22 ADRs — what was locked, and what was rejected |
AGENTS.md |
Contract for agents working on this repository |
skills/ |
Optional skill to invoke bootstrap from outside |
Shortest path into the vault: How to use this vault.
GreenField describes infrastructure and operating contracts, not products. A note may say "a structured-output endpoint"; it must never name a real product, domain, or application id. CI enforces that, plus link integrity and template agreement.
Version pins live in exactly two notes — Web Stack Baseline and Android Stack Baseline. Re-check them at bootstrap; they age fastest.
A standard and its template must agree. A change that contradicts an ADR must supersede that ADR. Read CONTRIBUTING.md, then:
node tools/check-vault.mjs
node tools/check-baselines.mjs
node tools/check-materialize.mjs
node tools/check-rules.mjs| Scope | License |
|---|---|
| Manual, tools, everything except the template files | MIT — © 2026 Diego Álvarez |
vault/90-Templates/files/** |
CC0 1.0 — copy into products without attribution |
| Copied materializer | MIT — ships with tools/MATERIALIZER-LICENSE |
See LICENSE for the exact split.
Report vulnerabilities through GitHub Private Vulnerability Reporting — SECURITY.md. Do not open a public issue for security findings.