Monorepo Support

Speck automatically detects monorepo workspaces and provides cross-workspace coordination similar to multi-repo support. Use shared specifications across workspace packages while maintaining independent implementation plans per package.

What is a Monorepo?

A monorepo is a single repository containing multiple related projects (packages/workspaces). Common monorepo tools include:

  • pnpm workspaces - Fast, disk-efficient package manager
  • Yarn workspaces - Yarn’s built-in workspace support
  • npm workspaces - Native npm workspace support (v7+)
  • Lerna - Monorepo management tool
  • Nx - Smart build system for monorepos

Automatic Detection

Speck detects monorepo mode by checking for workspace configuration files:

pnpm:

# pnpm-workspace.yaml
packages:
  - 'packages/*'
  - 'apps/*'

Yarn/npm:

// package.json
{
  "workspaces": [
    "packages/*",
    "apps/*"
  ]
}

Lerna:

// lerna.json
{
  "packages": [
    "packages/*"
  ]
}

When detected, Speck treats each workspace as a separate context similar to multi-repo children.

Monorepo vs Multi-Repo

MonorepoMulti-Repo
StructureSingle repo, multiple workspacesMultiple separate repos
DetectionAutomatic (workspace config)Manual (symlinks via /speck:link)
Shared specsOptional (same as multi-repo)Yes (via root directory)
Version controlSingle git repositorySeparate git repositories
DependenciesInternal workspace dependenciesExternal package dependencies

Using Speck in Monorepos

Workspace-Level Specifications

Create specifications at the workspace level for features spanning multiple packages:

my-monorepo/
├── pnpm-workspace.yaml
├── packages/
│   ├── ui/           # Workspace package
│   ├── api/          # Workspace package
│   └── shared/       # Workspace package
└── specs/            # Shared specifications (root level)
    └── 001-user-auth/
        ├── spec.md
        └── contracts/

Each package generates its own plan:

# From UI package
cd packages/ui
/speck:plan

# From API package
cd packages/api
/speck:plan

Package-Level Specifications

Alternatively, create specifications within individual packages for package-specific features:

my-monorepo/
├── pnpm-workspace.yaml
└── packages/
    ├── ui/
    │   └── specs/
    │       └── 001-button-component/
    │           ├── spec.md
    │           └── plan.md
    └── api/
        └── specs/
            └── 001-rest-endpoints/
                ├── spec.md
                └── plan.md

This approach works for features that don’t require cross-package coordination.

Use both workspace-level and package-level specs:

  • Workspace-level: Cross-package features (user auth, payment processing)
  • Package-level: Package-specific features (UI components, API utilities)
my-monorepo/
├── specs/                    # Shared cross-package features
│   └── 001-user-auth/
└── packages/
    ├── ui/
    │   └── specs/            # UI-specific features
    │       └── 002-button-component/
    └── api/
        └── specs/            # API-specific features
            └── 003-rate-limiting/

Shared Specifications in Monorepos

To use shared specs across workspaces (similar to multi-repo), create a root spec directory and link packages to it:

Option 1: Root-Level Shared Specs

# Create shared specs at monorepo root
cd /monorepo-root
mkdir shared-specs

# In Claude Code, from shared-specs/
/speck:specify "User authentication"

# Link packages to shared specs
cd packages/ui
/speck:link ../../shared-specs

cd ../api
/speck:link ../../shared-specs

Now both packages read from the same shared specification.

Option 2: Dedicated Specs Package

Create a workspace package just for specifications:

// pnpm-workspace.yaml
packages:
  - 'packages/*'
  - 'specs'
my-monorepo/
├── pnpm-workspace.yaml
├── specs/              # Workspace package for specs
│   └── 001-user-auth/
└── packages/
    ├── ui/
    └── api/

Link other packages to the specs workspace:

cd packages/ui
/speck:link ../../specs

cd ../api
/speck:link ../../specs

Common Monorepo Patterns

Frontend + Backend Monorepo

my-monorepo/
├── pnpm-workspace.yaml
├── specs/                      # Shared specifications
│   └── 001-user-auth/
│       ├── spec.md
│       └── contracts/api.md    # API contract
├── apps/
│   ├── web/                    # Next.js frontend
│   │   ├── .speck/root → ../../specs
│   │   └── specs/001-user-auth/
│   │       ├── plan.md         # Next.js implementation
│   │       └── tasks.md
│   └── api/                    # Express backend
│       ├── .speck/root → ../../specs
│       └── specs/001-user-auth/
│           ├── plan.md         # Express implementation
│           └── tasks.md
└── packages/
    └── shared/                 # Shared types/utils

Component Library Monorepo

design-system/
├── pnpm-workspace.yaml
└── packages/
    ├── components/
    │   └── specs/
    │       ├── 001-button/
    │       ├── 002-input/
    │       └── 003-modal/
    ├── icons/
    │   └── specs/
    │       └── 001-icon-set/
    └── themes/
        └── specs/
            └── 001-dark-theme/

Each package manages its own specifications independently.

Workspace Commands

Run commands from any package or the monorepo root:

# From package directory
cd packages/ui
/speck:plan       # Generates plan for current package

# From monorepo root
cd /monorepo-root
/speck:env --all  # Shows status across all workspaces

Best Practices

1. Consistent Structure

Maintain consistent spec directory structure across all workspaces:

packages/*/specs/NNN-feature-name/
  ├── spec.md
  ├── plan.md
  └── tasks.md

2. Shared Contracts

For cross-package features, define contracts at the root level:

specs/001-user-auth/
  └── contracts/
      ├── api.md        # API endpoints (for backend)
      ├── types.md      # TypeScript types (for frontend)
      └── events.md     # Event payloads (for both)

3. Package Boundaries

Respect workspace boundaries when implementing features:

Good:

# UI package plan.md
- Implement login form component
- Call API via shared types contract
- Handle auth state in React context

Bad:

# UI package plan.md
- Implement login form component
- Directly import backend database models (crosses boundary)

4. Version Control

# .gitignore at monorepo root
.speck/root       # Symlinks are local to workspace
node_modules/

Commit all specs:

git add specs/
git add packages/*/specs/
git commit -m "Add user auth specification"

Troubleshooting

Common monorepo issues:

  • Workspace not detected → Check for pnpm-workspace.yaml or workspaces in package.json
  • Cross-package imports failing → Configure workspace:* dependencies
  • Plans identical across packages → Create per-package constitutions

For detailed solutions, see Monorepo Issues in the Troubleshooting Guide.

Performance

Monorepo detection is automatic and adds minimal overhead:

  • Detection: <5ms (checks for workspace config files)
  • Per-package operations: Same performance as single-repo
  • Aggregate commands: <1s for 10+ workspaces

Migration from Multi-Repo

Converting multi-repo setup to monorepo:

  1. Move repos into monorepo structure:
mkdir my-monorepo
cd my-monorepo
git init

# Move existing repos as packages
mv /old/frontend packages/frontend
mv /old/backend packages/backend
  1. Configure workspaces:
# pnpm-workspace.yaml
packages:
  - 'packages/*'
  1. Move shared specs to root:
mkdir specs
mv /old/shared-specs/* specs/
  1. Update symlinks (if using shared specs):
cd packages/frontend
rm .speck/root
/speck:link ../../specs

cd ../backend
rm .speck/root
/speck:link ../../specs
  1. Verify:
cd packages/frontend
/speck:env  # Should show monorepo context

Next Steps