Skip to content

Instantly share code, notes, and snippets.

@nautilytics
Last active June 3, 2026 00:28
Show Gist options
  • Select an option

  • Save nautilytics/a1e932b926fb1255c3de40b3c21d1066 to your computer and use it in GitHub Desktop.

Select an option

Save nautilytics/a1e932b926fb1255c3de40b3c21d1066 to your computer and use it in GitHub Desktop.
Bootstrap a new iOS + Firebase app the right way

Bootstrap a new iOS + Firebase app the right way

Paste this into Claude Code (or your coding agent of choice) in an empty git repo on day one, before writing any features. The goal isn't to scaffold features — it's to install the conventions, guardrails, and written standards that keep an AI-assisted codebase clean as it grows. Fill in the bracketed parts first.


You are helping me bootstrap a new iOS app called [APP NAME]. In one sentence, it does: [ONE-SENTENCE PRODUCT DESCRIPTION]. Primary users: [WHO]. It is a [FREE / PAID / FREEMIUM] app and the non-negotiable values are: [e.g. no tracking, kid-safe, privacy-first].

Do NOT start building features yet. First, set up the foundation. Work in this order and stop after each numbered step to let me review before continuing.

1. Monorepo + git hygiene.

  • Create this structure: ios/ (SwiftUI app, latest iOS target), functions/ (Firebase Cloud Functions v2, TypeScript, latest LTS Node), admin/ (optional internal dashboard), marketing/ (optional public site), infra/ (Firestore rules, indexes, Storage rules), docs/.
  • Enforce Conventional Commits (type(scope): lowercase subject) via commitlint. Scopes: ios, functions, admin, infra, docs.
  • Add Husky pre-commit hooks: SwiftLint/SwiftFormat for iOS, ESLint + Prettier for TS. Never bypass with --no-verify.
  • Rule: never commit to main — always a feat/, fix/, or chore/ branch + PR.

2. Write the instruction files BEFORE any code. These are the most important files in the repo — they are what you (the agent) read every session.

  • AGENTS.md — repo layout, core data flow, the Firestore schema, how to run/test each package, and the build/verify commands.
  • CLAUDE.md — a pointer to AGENTS.md plus a "Project gotchas" section (start it empty; we will append a written rule every time we hit a bug, so the same mistake never recurs).
  • PRODUCT.md — users, brand personality, explicit anti-references (the looks/patterns to avoid), accessibility target (WCAG 2.2 AA).
  • DESIGN.md — color palette, type hierarchy, spacing/radius tokens, component list, do's/don'ts.

3. Firebase + iOS skeleton.

  • iOS: SwiftUI with @Observable + @Environment dependency injection (no ObservableObject). A single AppEnvironment root container. Services own Firestore reads/writes; repositories are protocol-backed query abstractions; views never call Firestore directly. A DesignSystem/ folder with color/spacing/typography tokens and a few reusable components — no hard-coded values.
  • Functions: TypeScript, all functions exported from index.ts, secrets via defineSecret(), admin callables gated by a requireAdminAuth helper. Validate request.data shape at the trust boundary — never pass unknown straight through. Mutation callables return the canonical persisted values, not the client's payload.
  • infra/: Firestore rules (default deny; reads/writes explicitly allowed), firestore.indexes.json (every composite-index query must be declared here, even ones created via the console URL), Storage rules.

4. The testing harness, early. Set up Firebase emulators with a committed seeded-data snapshot, and a single command (npm run test:ui or similar) that boots the emulators from the seed, waits for auth to be ready, runs the integration/UI suite against them, and tears everything down pass-or-fail. Also wire iOS unit tests that run fully offline. Rule: run the whole suite before pushing, not just the file you touched.

5. CI/CD + automated review.

  • GitHub Actions: lint + test on every PR; deploy on push to the release branch.
  • Add an automated PR-review Action (e.g. Claude Code Action) scoped to this stack's real risks: Firestore rules correctness, callable auth + input validation, and write atomicity.

Standing rules for the whole project (apply these unprompted):

  • After we hit any non-obvious bug, append a one-paragraph rule to CLAUDE.md's "Project gotchas" — the specific trap and the fix — so it never recurs.
  • Security lives in the rules, not the UI. A field hidden in the client but writable by the rules is not protected. Gate admin-only fields with isAdmin() server-side.
  • Prefer on-device / cheap paths for the common case; fall back to paid APIs only on uncertainty.
  • For remote images in lists, cache + downsample — never plain AsyncImage.
  • Keep heavy work (filtering, sorting, formatting) out of SwiftUI body.

Start with step 1. Show me the structure and the commit/hook config, then stop.

@solar-flare99

Copy link
Copy Markdown

This is awesome! the AI guardrails part was spot on, and we use immunity-agent which sits between claude code and your prompts for secure coding

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment