@alfredmouelle/create-stack
v0.8.1
Published
Framework-agnostic, deterministic installer that bootstraps a real, fully-wired app for your favorite framework (Next.js and TanStack Start today) and strips it to your selection.
Downloads
2,322
Maintainers
Readme
Framework-agnostic by design: pick your framework, get a real app. create-stack forks a
fully-wired base app and strips it to exactly what you pick (database, tRPC, better-auth, a
mailer, optional capabilities), then stamps identity, writes .env, inits git and verifies
(typecheck + Biome). No template guesswork: the output is a real, buildable app from day one.
Next.js App Router and TanStack Start are supported today, with more frameworks on the way.
Open source (MIT). Source and issues live at github.com/alfredmouelle/create-stack.
Quick start
pnpm dlx @alfredmouelle/create-stack@latest my-app
# or the create-* convention (npm / yarn create also work):
pnpm create @alfredmouelle/stack@latest my-appNo flags → an interactive wizard. Any selection flag → non-interactive (CI / scriptable).
Requires Node ≥ 22, a package manager (pnpm / npm / yarn / bun, auto-detected and
used by the generated project), and git on PATH.
Commands
create-stack [project] [flags] # scaffold a new project
create-stack add [capability] [adapter] # add a capability to the current project
create-stack component [name] # vendor a standalone UI componentproject is the target dir (and default package name), must be empty or not exist.
<command> --help prints its flags; --version prints the version.
Scaffold flags
| Flag | Values | Default | Notes |
| --- | --- | --- | --- |
| --framework | tanstack | next | tanstack | Base app to fork. |
| --monorepo | turbo | nx | standalone | Scaffold into a monorepo (app in apps/web) orchestrated by Turborepo or Nx. Bare --monorepo = turbo; omit for a standalone app. |
| --pm | pnpm | npm | yarn | bun | auto-detected | Package manager for the generated project. |
| --alias | prefix, e.g. @ | # | ~ | Import alias; rewrites <alias>/* → src/* everywhere. |
| --database | drizzle | prisma | convex | none | drizzle | Data layer. prisma = Prisma 7; convex = realtime db + API (replaces tRPC, Clerk/none auth only); none = database-less vitrine. |
| --auth | better-auth | clerk | none | better-auth | Auth provider. clerk is hosted (needs no db/mailer); none = no auth. |
| --foundations | csv of trpc | all | Foundations to keep; the rest are stripped. |
| --mailer | resend | brevo | ses | none | resend | Mailer provider. |
| --storage | s3 | r2 | gcs | local | s3 | Object storage (omit to skip). |
| --cache | redis | upstash | memory | redis | Key/value cache (omit to skip). |
| --jobs | inngest | trigger | memory | inngest | Background jobs (omit to skip). |
| --logger | pino | console | pino | Structured logging (omit to skip). |
| --analytics | posthog | plausible | noop | posthog | Product analytics (omit to skip). |
| --error-tracking | sentry | console | sentry | Error reporting (omit to skip). |
| --no-install | - | install on | Skip install + verification. |
| --yes, -y | - | - | Non-interactive with all defaults. |
Capability flags are optional; pass one (bare = default adapter) to vendor it, omit to
skip. Any selection flag switches to non-interactive mode; --pm/--alias are modifiers,
not triggers. Selections are normalized: trpc and better-auth need a database (fall
back to drizzle) and better-auth forces a real mailer, while clerk is hosted and
frees both, so --auth clerk --database none is a valid authenticated vitrine. convex
is its own API layer, so it drops tRPC and pairs with Clerk or no auth (better-auth off).
# everything, defaults, no questions
pnpm dlx @alfredmouelle/create-stack my-app --yes
# Prisma instead of Drizzle, full stack
pnpm dlx @alfredmouelle/create-stack my-app --database prisma
# Clerk instead of better-auth
pnpm dlx @alfredmouelle/create-stack my-app --auth clerk
# Convex (realtime db + API) with Clerk auth
pnpm dlx @alfredmouelle/create-stack my-app --database convex --auth clerk
# Next.js, just tRPC, no auth, don't install
pnpm dlx @alfredmouelle/create-stack api --framework next --auth none --mailer none --no-install
# inside an Nx monorepo (app lands in apps/web)
pnpm dlx @alfredmouelle/create-stack my-app --monorepo nx
# vitrine: no database, no auth, no mailer
pnpm dlx @alfredmouelle/create-stack site --database none --auth none --foundations '' --mailer none
# with capabilities: R2 storage, Redis cache, Inngest jobs, Sentry errors
pnpm dlx @alfredmouelle/create-stack my-app --storage r2 --cache --jobs --error-trackingWhat you get
- Framework: Next.js App Router or TanStack Start, fully wired (SSR, routing).
- Structure: standalone app or a Turborepo/Nx monorepo (app in
apps/web) with workspace, task caching, delegated scripts and hoisted git hooks. - Database: Drizzle or Prisma 7 (Postgres, driver adapter, schema, seed, keyset pagination), or Convex (realtime db + API, subsumes tRPC), or none.
- tRPC v11: typed API, SSR/RSC integration, health router.
- Auth: better-auth (email+password + verification, Google OAuth, auth pages) or Clerk (hosted: provider, middleware, sign-in/up +
UserButton), or none. - Mailer: Resend / Brevo / SES behind one port; React Email templates.
- Baseline: Tailwind v4 + shadcn, Geist, theme toggle, strict Biome, typed
env.ts, Dockerfile, git hooks, a GitHub Actions CI workflow (install + typecheck + Biome), generated.gitignore+.env.
Unselected pieces are removed cleanly (files, deps, env, wiring); the project is left bootable and green.
Capabilities
Swappable integrations, each copied behind a port into src/server/<capability>/ with a
generated composition root that reads typed env and constructs the adapter lazily (so the
app boots before you fill the keys). Deps + env keys are wired into package.json and
env.ts automatically.
| Capability | Adapters |
| --- | --- |
| storage | s3, r2, gcs, local |
| cache | redis, upstash, memory |
| jobs | inngest, trigger, memory (inngest also scaffolds the serve route) |
| logger | pino, console |
| analytics | posthog, plausible, noop |
| error-tracking | sentry, console |
Add more later with create-stack add (same engine, merged incrementally). Re-adding with
a different adapter swaps it (--keep keeps both). Targets also include mailer,
email-kit (React Email primitives) and http (fetch helpers).
create-stack add # interactive picker
create-stack add storage r2 # one capability + adapter
create-stack add cache upstash # swap redis → upstashComponents
Opt-in UI kept out of the base bundle (its heavier deps too). Vendor one into a generated
project: files copied, deps merged, imports realigned to your alias. Existing files are
never overwritten (--force to override).
| Component | Vendors | Deps |
| --- | --- | --- |
| date-picker | ui/date-picker, ui/date-range-picker (+ calendar, popover, lib/date) | react-day-picker, date-fns |
| datatable | data-table, infinite-data-table, sortable-header, use-data-table | @tanstack/react-table |
create-stack component # interactive picker
create-stack component date-picker # one componentAfter scaffolding
cd my-app
pnpm install # only if you passed --no-install
# edit .env # already generated with placeholders
pnpm devThe generated project is a fresh git repo with an initial commit (skipped, files left
staged, if git user.name/user.email aren't set). The published package is
self-contained: pnpm dlx needs nothing else.
Credits
Inspired by create-t3-app and the work of Theo Browne. Not affiliated with or endorsed by the T3 project.
Author
Alfred MOUELLE, FullStack Developer
