Scaffolding the full stack

Triple + mobile + desktop.

8 minmedium

This course is the kitchen sink: one Go API powering four frontends β€” a public website, an admin panel, a mobile app, and a desktop app. The first job is scaffolding all of them so they can talk to the same database from day one.

What we're building

Four surfaces, one API

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Go API (apps/api) β”‚ β”‚ :8080 β†’ Postgres β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”‚ Web β”‚ β”‚ Admin β”‚ β”‚ Mobile β”‚ β”‚ Desktop β”‚ β”‚ Shared β”‚ β”‚ (3000) β”‚ β”‚ (3001) β”‚ β”‚ (Expo) β”‚ β”‚ (Wails) β”‚ β”‚ types/zod β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Every frontend points at the same Go API. The API is the single source of truth.

Same API, same data, four different surfaces. Each surface owns presentation; nothing owns business logic except the API.

Step 1 β€” Scaffold the triple kit

Triple kit means: API + web + admin in one monorepo. This is the foundation; mobile and desktop bolt on next.

grit new my-saas --kit=triple
cd my-saas
pnpm install

That gives you:

  • apps/api/ β€” Go API
  • apps/web/ β€” Next.js public + dashboard
  • apps/admin/ β€” Next.js admin panel
  • packages/shared/ β€” Zod schemas + TS types

Step 2 β€” Add the mobile app

Mobile lives at apps/mobile/. The Grit CLI knows how to add it on top of an existing project.

grit add mobile
# scaffolds apps/mobile/ as an Expo app
# wires it into pnpm-workspace.yaml
# points API_URL at http://localhost:8080

Now the workspace has 4 frontends. Mobile reads from packages/shared just like the web apps do.

Step 3 β€” Add the desktop app

grit add desktop
# scaffolds apps/desktop/ as a Wails project
# wires it into the workspace
# points API_URL at http://localhost:8080

Wails is Go + React shipped as a single native binary. Same shared types, same API client patterns β€” different runtime.

Why scaffold in this order? Triple first, then add mobile + desktop. Grit's shared package is most battle-tested in the web direction β€” mobile and desktop slot in by reusing it. Doing it the other way around (mobile first, try to retrofit web) usually leads to duplicated types.

What the final tree looks like

my-saas/
β”œβ”€β”€ apps/
β”‚ β”œβ”€β”€ api/ Go API (Gin + GORM)
β”‚ β”œβ”€β”€ web/ Next.js public site + dashboard
β”‚ β”œβ”€β”€ admin/ Next.js admin panel
β”‚ β”œβ”€β”€ mobile/ Expo + React Native
β”‚ └── desktop/ Wails (Go + React)
β”œβ”€β”€ packages/
β”‚ └── shared/ Zod schemas + TS types (shared by web/admin/mobile/desktop)
β”œβ”€β”€ grit.config.ts Project config (kits enabled, etc.)
β”œβ”€β”€ pnpm-workspace.yaml
└── turbo.json

Boot the whole thing

# Terminal 1 β€” infra
docker compose up -d
# Terminal 2 β€” API
cd apps/api && go run cmd/server/main.go
# Terminal 3 β€” web + admin (turbo handles both)
pnpm dev
# Terminal 4 β€” mobile
cd apps/mobile && pnpm start
# Terminal 5 β€” desktop
cd apps/desktop && wails dev

Five terminals feels like a lot β€” and it is. Most days you won't run all five. You boot the ones for the surface you're editing. The point is they ALL CAN run against the same dev DB.

Quick check

Why scaffold mobile + desktop AFTER triple, not as part of one big command?

Try it

For chapter 1's assignment, get all four surfaces up:

  1. Run grit new my-saas --kit=triple.
  2. Run grit add mobile and grit add desktop.
  3. Boot the API, web, admin, mobile, and desktop.
  4. Screenshot each β€” even just the default scaffold pages.
  5. Confirm all 4 frontends list the same seeded user from /api/users.

The point: prove the loop closes. One API, four frontends, one DB.

What's next

Next lesson β€” Monorepo wiring. The boring plumbing that makes four frontends behave like one project: pnpm workspaces, turbo pipelines, the Go module layout.

Spot a typo? Have an idea?

Help us improve this lesson. One click opens a GitHub issue with the lesson URL pre-filled β€” suggest clearer wording, report a bug, or request more depth. The course keeps improving thanks to learners like you.

Suggest an improvement on GitHub