@exanderal/stackcraft
v0.9.1
Published
Opinionated full-stack project scaffolding CLI
Maintainers
Readme
stackcraft
Spin up a production-ready monorepo in one command.
Work in progress. The CLI is functional but not polished. Expect breaking changes between versions.
Usage
npx @exanderal/stackcraftFollow the prompts — you'll have an Nx monorepo with deps installed and ready to run.
Add --full to unlock ORM and linter selection:
npx @exanderal/stackcraft --fullNon-interactive mode
Generate a config file with all defaults:
npx @exanderal/stackcraft initThis writes stackcraft.config.json to the current directory:
{
"$schema": "https://unpkg.com/@exanderal/stackcraft/schema.json",
"name": "my-app",
"backend": "nestjs-rest",
"orm": "prisma",
"frontend": "vite",
"mobile": "none",
"database": "postgres",
"packageManager": "pnpm",
"linter": "eslint",
"here": false
}Edit the fields you want, then scaffold:
npx @exanderal/stackcraft --config stackcraft.config.jsonAny field omitted from the config will be prompted interactively. The $schema enables autocomplete and validation in VS Code — hover over any field to see valid values.
Scaffold into the current directory
By default, stackcraft creates a new subdirectory named after your project. If you already have a repository cloned and want to scaffold directly into it, use --here:
npx @exanderal/stackcraft --here
npx @exanderal/stackcraft --config stackcraft.config.json --hereOr set it in the config:
{
"name": "my-app",
"here": true
}name still sets the monorepo package name — it just no longer doubles as the output folder.
What you get
your-project/
├── apps/
│ ├── backend/ # NestJS REST or GraphQL API
│ │ └── CLAUDE.md # coding guidelines for this app (backend + ORM specific)
│ ├── web/ # Vite + React or Next.js
│ │ └── CLAUDE.md # coding guidelines for this app
│ └── mobile/ # Expo (optional)
│ └── CLAUDE.md # coding guidelines for this app
├── packages/
│ └── types/ # auto-generated types shared across all apps
├── tools/
│ └── generators/ # local Nx code generators
├── .github/
│ ├── workflows/
│ │ └── quality.yml # CI: typecheck, lint, test, security audit, build
│ └── dependabot.yml # weekly dependency and Actions version updates
├── .husky/
│ └── pre-commit # auto-format staged files + secret scan before every commit
└── docker-compose.yml # local databaseBackend (apps/backend)
Choose between REST or GraphQL at setup — both share the same structure:
src/
├── modules/ # domain layer — model, repository, service, module
├── api/ # REST controllers
└── resolvers/ # GraphQL resolvers- NestJS
- PostgreSQL or MySQL
- Prisma (default) or Kysely (power user, use
--fullto select) - REST: Swagger UI at
/api, spec written toswagger.jsonon startup - GraphQL: schema auto-generated to
schema.gqlon startup (code-first) .envpre-configured with local database credentialsCLAUDE.mdwith layer responsibilities, generator usage, Swagger/schema rules, and ORM-specific migration workflows
Prisma (default)
prisma/schema.prismawith your chosen database providerPrismaServiceas a global NestJS provider- Generator templates:
generate:moduleoutputs a Prisma-based repository - Single
DATABASE_URLconnection string in.env
Kysely (--full only)
src/database/—database.types.ts,migrations/,seeds/,utils/ReadonlyEntityRepositoryandEntityRepositorybase classesKyselyServiceas a global NestJS providerscripts/migrate.ts— run/revert migrations;scripts/migration-create.ts— generate timestamped migration files- Generator templates:
generate:moduleoutputs a Kysely-based repository - Individual
DB_HOST,DB_PORT,DB_USER,DB_PASSWORD,DB_NAMEvars in.env
Frontend (apps/web)
- Vite + React or Next.js
- Tailwind CSS v4
- TypeScript
- GraphQL projects: Apollo Client pre-configured,
ApolloProvideralready wired at the app root .envpre-configured withVITE_API_URL/NEXT_PUBLIC_API_URLCLAUDE.mdwith component structure conventions, folder organisation rules, services layer boundary, and the 3-usage promotion threshold
Mobile (apps/mobile) — optional
- Expo with Expo Router (file-based navigation)
- React Native
@local/typesalready wired — import shared types directly- GraphQL projects: Apollo Client added automatically
Types (packages/types)
Auto-generated TypeScript types shared across all apps — import from @local/types/rest or @local/types/graphql:
- REST → generated from
swagger.jsonvia@hey-api/openapi-ts - GraphQL → generated from
schema.gql+ your.graphqloperation files via@graphql-codegen/cli, outputs typed Apollo hooks
Quick start
pnpm db:start # start the local database (Docker)
pnpm install
pnpm devEnvironment variables are pre-configured in each app's .env — no manual setup needed to get started locally.
Scripts
pnpm dev # start all apps in parallel
pnpm build # build all apps
pnpm test # run all tests
pnpm lint # lint all apps
pnpm typecheck # TypeScript type-check all apps (no emit)
pnpm db:start # start the local database
pnpm db:stop # stop the local database
pnpm db:logs # tail database logs
pnpm codegen # generate types once
pnpm codegen:watch # watch for schema/spec changes and regenerate automaticallyDatabase scripts
Prisma:
pnpm db:migrate # run pending migrations (prisma migrate dev)
pnpm db:migrate:deploy # deploy migrations in CI/production
pnpm db:seed # run the seeder
pnpm db:studio # open Prisma StudioKysely:
pnpm db:migrate # run pending migrations
pnpm db:rollback # revert the last migration
pnpm db:seed # run the seederCreating a new migration file is a backend-level command:
pnpm --filter backend migration:new <name>
# → creates apps/backend/src/database/migrations/<timestamp>-<name>.tsTypical dev workflow — run both in parallel:
# terminal 1
pnpm dev
# terminal 2
pnpm codegen:watchCode generators
Generate a new domain module (model + repository + service):
pnpm generate:module --name=trainerThe generated repository and service match your chosen ORM — Prisma or Kysely.
Generate a REST controller:
pnpm generate:controller --name=trainer
# → apps/backend/src/api/trainer/trainer.controller.tsGenerate a GraphQL resolver:
pnpm generate:resolver --name=trainer
# → apps/backend/src/resolvers/trainer/trainer.resolver.tsUsing generated types
REST — import types directly:
import type { Trainer } from '@local/types/rest'GraphQL — write .graphql files in apps/web/src/graphql/, run pnpm codegen, then use the generated hooks:
// apps/web/src/graphql/trainer.graphql
query GetTrainers {
trainers { id createdAt updatedAt }
}import { useGetTrainersQuery } from '@local/types/graphql'
const { data, loading } = useGetTrainersQuery()Stack
| Layer | Technology |
|---|---|
| Monorepo | Nx |
| Package manager | pnpm or npm |
| Backend | NestJS |
| ORM | Prisma (default) or Kysely (--full) |
| Database | PostgreSQL or MySQL |
| Frontend | Vite + React or Next.js |
| Mobile | Expo + Expo Router |
| Styles | Tailwind CSS v4 |
| Linter / formatter | ESLint + Prettier or Biome (--full) |
| Pre-commit | husky + lint-staged + secretlint |
| GraphQL client | Apollo Client |
| REST types | @hey-api/openapi-ts |
| GraphQL types + hooks | @graphql-codegen/cli |
| Local database | Docker Compose |
Roadmap
- [x] NestJS REST API with Swagger
- [x] NestJS GraphQL API (code-first)
- [x] Module, controller, and resolver generators
- [x] Auto-generated types in
packages/types - [x]
codegen:watchfor live type generation during dev - [x] Apollo Client pre-configured in GraphQL projects
- [x] Typed Apollo hooks from
.graphqloperation files - [x] Expo mobile with Expo Router
- [x] Interactive
generate:moduleprompt - [x] Biome as an alternative to ESLint + Prettier
- [x] Docker Compose for local database + per-app
.envfiles - [x] Prisma ORM (default)
- [x] Kysely ORM with repository abstraction (
--full) - [x]
stackcraft init+--configfor non-interactive use - [x]
--hereflag to scaffold into the current directory - [x] GitHub Actions quality gate pre-configured (typecheck, lint, test, security audit, build)
- [x] Dependabot pre-configured for weekly dependency and Actions version updates
- [x] Pre-commit hooks — auto-format staged files (Biome or Prettier) + secretlint secret scanning
- [x]
CLAUDE.mdper app — coding guidelines for AI agents baked in at scaffold time - [ ]
stackcraft addaddon system (auth, Supabase, etc.)
License
MIT
