Scaffold flows

Verified facts for every upstream generator β€” flags, output shapes, caveats, sources. Edit on GitHub

Scaffold flows β€” verified generator reference

Last verified: 2026-07-10. Every adapter change must re-verify its section against upstream and update this date, the facts, and the sources. This document is the ground truth groot's adapters are written against.

Drift is watched automatically: e2e.yml re-runs the real generators weekly (behavior), and drift.yml re-checks every pinned series and this document's age (pins & docs) β€” see the maintainer runbook.

Version snapshot at verification: create-turbo 2.10.4 Β· Next.js 16.2.10 Β· sv 0.16.2 (SvelteKit 2.63 / Svelte 5.56 / Vite 8) Β· create-expo-app 4.0.0 (Expo SDK 57) Β· elysia 1.4.29 Β· create-hono 0.19.4 (hono 4.12.28) Β· convex 1.42.1.

Summary matrix

Scaffoldgroot invocation (pinned major)Git-inits?Auto-installs?Non-empty dir behavior
Turborepo (trunk)bunx create-turbo@2 <dir> -m bun --skip-install --no-gityes β†’ suppressedyes β†’ suppressedassume fresh dir required
Next.jsbunx create-next-app@16 … --disable-git --skip-installskips inside existing repo; forced off anywayyes β†’ suppressedrefuses ("could conflict")
SvelteKitbunx sv@0.16 create … --no-install --no-dir-checkneveronly with --installrefuses unless --no-dir-check
TanStack Startbunx @tanstack/cli@0.69 create <name> --framework React --package-manager bun --no-git --no-install --no-examples --no-toolchain --no-intent --yes--no-git--no-installrefuses unless --force
Astrobunx create-astro@5 <name> --template minimal --no-install --no-git --no-ai --skip-houston --yes--no-git--no-install⚠️ silently redirects to a random dir under --yes (see §11)
React Routerbunx create-react-router@8 <name> --package-manager bun --no-git-init --no-install --no-agent-skills --yes--no-git-init--no-installhard-fails on collisions without --overwrite
Nuxtbunx create-nuxt@3 <name> --template minimal --packageManager bun --no-gitInit --no-install --no-modules--no-gitInit--no-install--force to override
Vitebunx create-vite@9 <name> --template react-ts --no-interactive --no-immediatenever--no-immediate--overwrite to clear
Expobunx create-expo-app@4 … --no-installno flag exists (see caveats)yes β†’ suppressed(unverified)
React Native (bare)bunx @react-native-community/cli@20 init <name> --pm bun --skip-install --install-pods false --skip-git-init --replace-directory false--skip-git-init--skip-installprompts unless --replace-directory (groot targets fresh dirs, staged)
Tauribunx create-tauri-app@4 <name> --template react-ts --manager bun --identifier <id> --yesneverneverrefuses unless --force
Electronbunx @quick-start/create-electron@1 <name> --template react-ts --skipneverneveroverwrite prompt nulled by --skip
Elysia(none β€” groot writes files directly)β€”β€”β€”
Honobunx create-hono@0.19 … --template bunneveronly with -iinteractive confirm, no bypass β†’ must target fresh dir
Fastifybunx fastify-cli@8 generate <name> --lang=ts --esmnevernever (but shells out to npm init -y)refuses ("directory already exists")
Convex(files written directly, incl. vendored _generated stubs)β€”β€”β€”
Supabasebunx supabase@2 init (postCommand inside groot's package shell)nevernevererrors on existing config (exit 1; --force exists, groot targets fresh dirs)

1. Turborepo trunk β€” create-turbo

bunx create-turbo@2 my-repo -m bun --skip-install --no-git

2. Web: Next.js β€” create-next-app

bunx create-next-app@16 apps/web \
  --ts --tailwind --eslint --app --src-dir --turbopack \
  --import-alias "@/*" --use-bun --skip-install --disable-git --yes

3. Web: SvelteKit β€” sv create

create-svelte is deprecated; sv is the official CLI (merged create-svelte + svelte-add).

bunx sv@0.16 create apps/web --template minimal --types ts --no-add-ons --no-install --no-dir-check

4. Mobile: Expo β€” create-expo-app

bunx create-expo-app@4 apps/mobile --template default@sdk-57 --no-install --yes

5. API: Elysia β€” files written directly (no generator)

bun create elysia resolves to the npm package create-elysia, which is community-owned (not an elysiajs org package), interactive-prompt-based, and diverges from Elysia's own docs (its template lacks the documented dev script). groot therefore writes the four files from Elysia's official manual setup:

apps/api/
β”œβ”€β”€ src/index.ts       # new Elysia().get("/", …).listen(3001)  ← port patched from default 3000
β”œβ”€β”€ package.json       # dev: bun --watch src/index.ts Β· build: bun build … Β· start Β· test: bun test
β”œβ”€β”€ tsconfig.json      # strict: true
└── README.md

Deps: elysia@^1.4 + @types/bun. Scripts per Elysia's docs: dev: bun --watch src/index.ts, build: bun build src/index.ts --target bun --outdir ./dist, start: NODE_ENV=production bun dist/index.js, test: bun test.

6. API: Hono β€” create-hono

bunx create-hono@0.19 apps/api --template bun --pm bun

7. Backend: Convex β€” files written directly, _generated stubs vendored

No fully-offline official generator exists (create-convex is a degit template copier oriented at full-stack presets). groot writes packages/backend directly, modeled on Convex's own reference monorepo (get-convex/turbo-expo-nextjs-clerk-convex-monorepo):

packages/backend/
β”œβ”€β”€ convex/
β”‚   β”œβ”€β”€ schema.ts          # starter schema (messages table)
β”‚   β”œβ”€β”€ messages.ts        # starter query + mutation matching the schema
β”‚   β”œβ”€β”€ tsconfig.json      # vendored from get-convex/templates
β”‚   └── _generated/        # vendored standard stubs β€” COMMITTED (official recommendation)
β”œβ”€β”€ package.json           # @repo/backend Β· dev: convex dev Β· setup: convex dev --until-success Β· typecheck
└── .env.example           # CONVEX_DEPLOYMENT / CONVEX_URL placeholders

8. Desktop: Tauri β€” create-tauri-app

bunx create-tauri-app@4 desktop --template react-ts --manager bun --identifier com.<workspace>.desktop --yes

9. Desktop: Electron β€” @quick-start/create-electron (electron-vite)

bunx @quick-start/create-electron@1 desktop --template react-ts --skip

10. Web: TanStack Start β€” @tanstack/cli (tanstack create)

bunx @tanstack/cli@0.69 create web --framework React --package-manager bun --no-git --no-install --no-examples --no-toolchain --no-intent --yes

11. Web: Astro β€” create-astro

bunx create-astro@5 web --template minimal --no-install --no-git --no-ai --skip-houston --yes

12. Web: React Router (framework mode) β€” create-react-router

bunx create-react-router@8 web --package-manager bun --no-git-init --no-install --no-agent-skills --yes

13. Web: Nuxt β€” create-nuxt

bunx create-nuxt@3 web --template minimal --packageManager bun --no-gitInit --no-install --no-modules

14. Web: Vite β€” create-vite

bunx create-vite@9 web --template react-ts --no-interactive --no-immediate

15. API: Fastify β€” fastify-cli generate

bunx fastify-cli@8 generate api --lang=ts --esm

16. Mobile: React Native (bare) β€” @react-native-community/cli init

bunx @react-native-community/cli@20 init mobile --pm bun --skip-install --install-pods false --skip-git-init --replace-directory false

17. Backend: Supabase β€” package shell + supabase init

bunx supabase@2 init   # postCommand, cwd = packages/backend (after groot's writeFiles)

Stitching reference

The canonical "what does stitched output look like" spec is the diff between raw generator output and the same app inside Turborepo's official examples (basic, with-svelte, kitchen-sink): package renames, @repo/* deps with workspace:*, shared typescript-config extends, per-app ports in dev scripts, no nested lockfiles. See architecture.md for the full operation list.

Prior-art notes (why groot works this way)