StackKit LogoStackKit
Concepts

How StackKit Works

A technical look at how StackKit generates projects and integrates modules under the hood.

StackKit is built around a simple idea: take a base template and layer optional modules on top of it. Understanding how this process works helps you predict what StackKit will do and makes it easier to customize the output if you need to.

Repository structure

The StackKit monorepo is organized into three main areas:

stackkit/
├── apps/
│   ├── stackkit/     # The CLI tool (published to npm as "stackkit")
│   └── docs/         # This documentation site
├── modules/          # Integration code for each optional module
│   ├── auth/         # Better Auth configuration
│   ├── database/     # Prisma and Mongoose setup
│   ├── storage/      # Cloudinary integration
│   ├── ui/           # Shadcn UI initialization
│   └── components/   # Pre-built UI components
└── templates/        # Base project structures
    ├── nextjs/        # Next.js App Router template
    ├── express/       # Express REST API template
    └── react/         # React + Vite SPA template

How stackkit create works

When you run stackkit create my-app, here's what happens step by step:

  1. Collect preferences — The CLI shows interactive prompts (or reads flags) to determine which framework, database, auth, and other modules you want.

  2. Copy the template — The matching template folder is copied into a new directory with your project name. This gives you the base project structure.

  3. Apply modules — Each selected module has a set of files and configuration changes associated with it. StackKit reads these from the modules/ directory and merges them into your project.

  4. Write environment variables — All variables needed by selected modules are appended to .env.example with clear comments.

  5. Install dependencies — StackKit runs your chosen package manager to install everything at once.

  6. Initialize git — A git repository is created with an initial commit (unless you opted out).

All of this happens in one shot. There's no intermediate state where your project is "partially configured" — StackKit either completes successfully or rolls back on failure.

How stackkit add works

The add command is designed for projects that were created without certain modules, or potentially created without StackKit at all.

  1. Detect framework — StackKit reads your package.json to figure out whether you're in a Next.js, Express, or React project. It uses the presence of specific packages as signals.

  2. Filter available modules — Only modules compatible with your detected framework are shown.

  3. Generate integration files — The selected module's files are written into your project, following the same paths as if you'd created the project with that module from the start.

  4. Update package.json — Required packages are added and installed.

  5. Update .env.example — New environment variable entries are appended (existing ones are never overwritten).

Module structure

Each module in the modules/ directory contains a generator.json file that describes how to apply it. This file defines:

  • Which files to copy and where
  • What conditions apply (e.g., only do X when using PostgreSQL)
  • Which npm packages to install
  • What environment variables to document

This declarative approach means adding new modules or updating existing ones is straightforward — you don't need to modify CLI source code.

Compatibility rules

Compatibility is enforced at two levels:

  1. Prompt filtering — When you run stackkit create, you'll only see options that make sense for your current selections. For example, if you select React as your framework, the database prompt won't appear because React projects are frontend-only.

  2. stackkit add filtering — Only modules that work with your detected framework are shown. This prevents mistakes like trying to add Prisma to a React project.

Package manager detection

StackKit detects your package manager by looking for lockfiles in the project root:

LockfilePackage manager
pnpm-lock.yamlpnpm
yarn.lockYarn
bun.lockbBun
package-lock.jsonnpm

If no lockfile is found, it falls back to npm. You can always override this with the --package-manager flag.

Want to contribute?

The architecture is designed to make contributions straightforward. If you want to add a new module or template, see the Contributing guide.

On this page