Configurable stack defaults

nanostack ships with battle-tested defaults. Override per project or globally.

Default stack

When you run /nano-run or start your first sprint, nanostack applies these defaults unless your project already has a stack configuration:

Category          Default              Why
───────────────────────────────────────────────────────────────────
Language          TypeScript           Most common in agent-built projects
Runtime           Node.js 20+         LTS, broad ecosystem
Framework         Next.js 14+         App router, server components
Styling           Tailwind CSS         Utility-first, no CSS file sprawl
Testing           Vitest               Fast, ESM-native, Jest-compatible API
Linting           ESLint + Prettier    Catches bugs, enforces formatting
Package manager   pnpm                 Strict, fast, disk-efficient
Database          Postgres             Battle-tested, works everywhere
Deployment        Vercel               Zero-config for Next.js

These are not prescriptions. They are starting points. If your project uses Go and SQLite, override them.

Auto-detection

Before applying defaults, bin/init-stack.sh scans your project for existing configuration. If it finds known files, it infers the stack instead of applying defaults:

# init-stack.sh detection logic (simplified)

# Language
[ -f "tsconfig.json" ]       && LANG="typescript"
[ -f "go.mod" ]              && LANG="go"
[ -f "Cargo.toml" ]          && LANG="rust"
[ -f "requirements.txt" ]    && LANG="python"
[ -f "pyproject.toml" ]      && LANG="python"
[ -f "Gemfile" ]             && LANG="ruby"

# Framework
[ -f "next.config.js" ] || [ -f "next.config.mjs" ] && FRAMEWORK="nextjs"
[ -f "nuxt.config.ts" ]     && FRAMEWORK="nuxt"
[ -f "svelte.config.js" ]   && FRAMEWORK="sveltekit"
[ -f "angular.json" ]       && FRAMEWORK="angular"

# Package manager
[ -f "pnpm-lock.yaml" ]     && PKG="pnpm"
[ -f "yarn.lock" ]          && PKG="yarn"
[ -f "bun.lockb" ]          && PKG="bun"
[ -f "package-lock.json" ]  && PKG="npm"

# Testing
[ -f "vitest.config.ts" ]   && TEST="vitest"
[ -f "jest.config.js" ] || [ -f "jest.config.ts" ] && TEST="jest"
[ -f "playwright.config.ts" ] && TEST="playwright"

# Database
grep -rql "prisma" package.json 2>/dev/null && DB="postgres"
[ -f "drizzle.config.ts" ]  && DB="postgres"
grep -rql "better-sqlite3" package.json 2>/dev/null && DB="sqlite"

Auto-detection runs once during /nano-run and writes the result to .nanostack/stack.json. After that, the file is the source of truth.

Override per project

Create or edit .nanostack/stack.jsonin your project root. You only need to specify the fields you want to change — everything else falls through to defaults.

{
  "language": "go",
  "runtime": "go1.22",
  "framework": "none",
  "testing": "go test",
  "linting": "golangci-lint",
  "package_manager": "go mod",
  "database": "sqlite",
  "deployment": "fly.io"
}

Every skill reads this file. When /review runs, it knows to check for Go idioms instead of TypeScript patterns. When /nano generates a plan, it scopes the implementation to Go conventions.

Override globally

If you work mostly in one stack, set a global default at ~/.nanostack/stack.json. This applies to every project that does not have its own stack file.

# ~/.nanostack/stack.json
{
  "language": "rust",
  "runtime": "stable",
  "framework": "axum",
  "testing": "cargo test",
  "linting": "clippy",
  "package_manager": "cargo",
  "database": "postgres",
  "deployment": "shuttle"
}

Priority order

When resolving the stack, nanostack checks three locations in order. The first match wins for each field:

  • Project.nanostack/stack.json in the project root. Highest priority.
  • User~/.nanostack/stack.json in your home directory. Applies to all projects without a project-level override.
  • Defaults— the built-in defaults table above. Lowest priority. Used only when neither project nor user config specifies a value.

Each field is resolved independently. If your project sets language: go but not testing, the testing framework falls through to your user config or the default (Vitest).

# Resolution example:
# Project stack.json: { "language": "go", "database": "sqlite" }
# User stack.json:    { "testing": "go test", "deployment": "fly.io" }
# Defaults:          { everything else }
#
# Resolved stack:
# language: go           ← project
# database: sqlite       ← project
# testing: go test       ← user
# deployment: fly.io     ← user
# runtime: Node.js 20+   ← default (no Go-specific default yet)
# framework: Next.js 14+ ← default
# styling: Tailwind CSS  ← default
# linting: ESLint        ← default
# package_manager: pnpm  ← default
PreviousCustom phasesNextConductor