monorepo-generator

kjgarza's avatarfrom kjgarza

Generate production-ready monorepo structures for full-stack applications including frontends (Next.js, React), APIs (Hono, Express), and data pipelines. Use when creating new monorepo projects, scaffolding multi-project architectures (web apps, APIs, workers, CLI tools), setting up shared packages, or configuring workspace tooling with Bun, PNPM, or Yarn.

⭐0stars🔀0forks📁View on GitHub🕐Updated Jan 10, 2026

When & Why to Use This Skill

The Monorepo Generator is a specialized Claude skill designed to scaffold production-ready, scalable monorepo architectures for complex full-stack applications. It automates the setup of multi-project workspaces, integrating modern frameworks like Next.js and React for frontends with Hono or Express for APIs. By implementing industry-standard directory structures and shared package patterns, it ensures seamless code sharing (UI, utils, DB schemas) and optimized build pipelines using Turborepo, Bun, PNPM, or Yarn.

Use Cases

  • Initializing a new SaaS platform that requires a web dashboard, a public API, and shared internal utility libraries.
  • Setting up a centralized design system or UI component library (e.g., shadcn/ui) to be consumed by multiple Next.js applications within a single workspace.
  • Architecting a data-intensive system with dedicated background workers, cron jobs, and ETL pipelines that share a common database client and configuration.
  • Standardizing development environments for engineering teams by providing unified TypeScript, ESLint, and Tailwind configurations across all sub-projects.
  • Migrating fragmented repositories into a unified Turborepo-powered workspace to improve dependency management and build performance.
namemonorepo-generator
descriptionGenerate production-ready monorepo structures for full-stack applications including frontends (Next.js, React), APIs (Hono, Express), and data pipelines. Use when creating new monorepo projects, scaffolding multi-project architectures (web apps, APIs, workers, CLI tools), setting up shared packages, or configuring workspace tooling with Bun, PNPM, or Yarn.

Monorepo Generator

Generate scalable monorepo structures for full-stack applications with shared packages.

Quick Start

mkdir my-monorepo && cd my-monorepo
bun init -y  # or: pnpm init / npm init -y

Workflow

Step 1: Gather Requirements

Ask user what project types they need:

Type Examples Common Stack
Frontend Web app, admin dashboard, docs site Next.js 15, React 19, Tailwind
API REST API, GraphQL server Hono, Express, Fastify
Pipeline ETL jobs, cron tasks, workers Node scripts, Python
CLI Developer tools, automation Commander, Yargs
Mobile React Native app Expo, React Native

Step 2: Choose Package Manager

  • Bun (recommended): Fastest, built-in workspaces
  • PNPM: Efficient disk usage, strict dependencies
  • Yarn: Mature ecosystem, plug'n'play option

See Package Manager Guide for configs.

Step 3: Create Directory Structure

/monorepo/
├── apps/                       # Deployable applications
│   ├── web/                    # Next.js frontend
│   ├── api/                    # Hono/Express API
│   ├── admin/                  # Admin dashboard
│   └── docs/                   # Documentation site
│
├── services/                   # Backend services & workers
│   ├── jobs/                   # Scheduled jobs/cron
│   ├── workers/                # Background workers
│   └── pipelines/              # Data pipelines
│
├── packages/                   # Shared libraries
│   ├── ui/                     # React components (shadcn/ui)
│   ├── utils/                  # Shared utilities
│   ├── db/                     # Database client & schemas
│   ├── api-client/             # Generated API client
│   ├── config/                 # Shared configuration
│   ├── eslint-config/          # Shared ESLint
│   └── typescript-config/      # Shared TS configs
│
├── package.json                # Workspace root
├── turbo.json                  # Turborepo config
└── .gitignore

Adapt structure based on needs—not all projects need all directories.

Step 4: Create Root Configuration

Root package.json:

{
  "name": "monorepo",
  "private": true,
  "workspaces": ["apps/*", "services/*", "packages/*"],
  "scripts": {
    "dev": "turbo dev",
    "build": "turbo build",
    "lint": "turbo lint",
    "type-check": "turbo type-check",
    "test": "turbo test"
  },
  "devDependencies": {
    "turbo": "^2.3.0",
    "typescript": "^5.7.0"
  },
  "packageManager": "bun@1.1.0"
}

turbo.json:

{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"]
    },
    "dev": { "cache": false, "persistent": true },
    "start": { "dependsOn": ["build"] },
    "lint": { "dependsOn": ["^lint"] },
    "type-check": { "dependsOn": ["^type-check"] },
    "test": { "dependsOn": ["^build"] }
  }
}

Project Templates

Frontend App (Next.js)

// apps/web/package.json
{
  "name": "web",
  "private": true,
  "scripts": {
    "dev": "next dev --turbopack",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "type-check": "tsc --noEmit"
  },
  "dependencies": {
    "@monorepo/ui": "workspace:*",
    "@monorepo/utils": "workspace:*",
    "next": "^15.0.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  },
  "devDependencies": {
    "@monorepo/typescript-config": "workspace:*",
    "tailwindcss": "^4.0.0",
    "typescript": "^5.7.0"
  }
}
// apps/web/next.config.ts
import type { NextConfig } from 'next';

const config: NextConfig = {
  transpilePackages: ['@monorepo/ui', '@monorepo/utils'],
};

export default config;

API Server (Hono)

// apps/api/package.json
{
  "name": "api",
  "private": true,
  "scripts": {
    "dev": "bun run --hot src/index.ts",
    "build": "bun build src/index.ts --outdir dist --target node",
    "start": "bun run dist/index.js",
    "type-check": "tsc --noEmit"
  },
  "dependencies": {
    "@monorepo/db": "workspace:*",
    "@monorepo/utils": "workspace:*",
    "hono": "^4.6.0",
    "@hono/node-server": "^1.13.0"
  },
  "devDependencies": {
    "@monorepo/typescript-config": "workspace:*",
    "@types/node": "^22.0.0",
    "typescript": "^5.7.0"
  }
}
// apps/api/src/index.ts
import { serve } from '@hono/node-server';
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';

const app = new Hono();

app.use('*', logger());
app.use('*', cors());

app.get('/', (c) => c.json({ status: 'ok' }));
app.get('/health', (c) => c.json({ healthy: true }));

// Routes
app.route('/api/users', usersRouter);
app.route('/api/items', itemsRouter);

serve({ fetch: app.fetch, port: 3001 }, (info) => {
  console.log(`API running on http://localhost:${info.port}`);
});

Background Worker/Job

// services/jobs/package.json
{
  "name": "jobs",
  "private": true,
  "scripts": {
    "dev": "bun run --watch src/index.ts",
    "build": "bun build src/index.ts --outdir dist --target node",
    "start": "bun run dist/index.js",
    "type-check": "tsc --noEmit"
  },
  "dependencies": {
    "@monorepo/db": "workspace:*",
    "@monorepo/utils": "workspace:*",
    "cron": "^3.1.0"
  },
  "devDependencies": {
    "@monorepo/typescript-config": "workspace:*",
    "@types/cron": "^2.4.0",
    "typescript": "^5.7.0"
  }
}
// services/jobs/src/index.ts
import { CronJob } from 'cron';
import { db } from '@monorepo/db';

// Run every hour
const hourlyJob = new CronJob('0 * * * *', async () => {
  console.log('Running hourly job...');
  // Your job logic here
});

// Run daily at midnight
const dailyJob = new CronJob('0 0 * * *', async () => {
  console.log('Running daily cleanup...');
  // Cleanup logic here
});

hourlyJob.start();
dailyJob.start();

console.log('Job scheduler started');

Data Pipeline

// services/pipelines/package.json
{
  "name": "pipelines",
  "private": true,
  "scripts": {
    "etl:users": "bun run src/etl/users.ts",
    "etl:analytics": "bun run src/etl/analytics.ts",
    "build": "bun build src/**/*.ts --outdir dist",
    "type-check": "tsc --noEmit"
  },
  "dependencies": {
    "@monorepo/db": "workspace:*",
    "@monorepo/utils": "workspace:*",
    "zod": "^3.23.0"
  },
  "devDependencies": {
    "@monorepo/typescript-config": "workspace:*",
    "typescript": "^5.7.0"
  }
}
// services/pipelines/src/etl/users.ts
import { db } from '@monorepo/db';
import { z } from 'zod';

const UserSchema = z.object({
  id: z.string(),
  email: z.string().email(),
  createdAt: z.coerce.date(),
});

async function extractUsers() {
  // Extract from source
}

async function transformUsers(raw: unknown[]) {
  return raw.map((r) => UserSchema.parse(r));
}

async function loadUsers(users: z.infer<typeof UserSchema>[]) {
  // Load to destination
}

async function main() {
  console.log('Starting ETL pipeline...');
  const raw = await extractUsers();
  const transformed = await transformUsers(raw);
  await loadUsers(transformed);
  console.log(`Processed ${transformed.length} users`);
}

main().catch(console.error);

Shared Packages

packages/utils

// packages/utils/src/index.ts
export { cn } from './cn';
export { formatDate, parseDate } from './date';
export { sleep, retry } from './async';
export type { Result, AsyncResult } from './types';

packages/db

// packages/db/package.json
{
  "name": "@monorepo/db",
  "private": true,
  "exports": { ".": "./src/index.ts" },
  "dependencies": {
    "drizzle-orm": "^0.36.0",
    "postgres": "^3.4.0"
  },
  "devDependencies": {
    "drizzle-kit": "^0.28.0",
    "@monorepo/typescript-config": "workspace:*"
  }
}

packages/config

// packages/config/src/index.ts
import { z } from 'zod';

const envSchema = z.object({
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  DATABASE_URL: z.string().url(),
  API_URL: z.string().url().optional(),
  LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
});

export const config = envSchema.parse(process.env);
export type Config = z.infer<typeof envSchema>;

TypeScript Configs

// packages/typescript-config/base.json
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "compilerOptions": {
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "declaration": true,
    "declarationMap": true
  }
}
// packages/typescript-config/node.json (for APIs/services)
{
  "extends": "./base.json",
  "compilerOptions": {
    "lib": ["ES2022"],
    "noEmit": true
  }
}
// packages/typescript-config/nextjs.json
{
  "extends": "./base.json",
  "compilerOptions": {
    "lib": ["DOM", "DOM.Iterable", "ES2022"],
    "jsx": "preserve",
    "noEmit": true,
    "plugins": [{ "name": "next" }]
  }
}

Adding New Projects

# New frontend
mkdir -p apps/dashboard && cp -r apps/web/* apps/dashboard/

# New API
mkdir -p apps/gateway && cp -r apps/api/* apps/gateway/

# New service
mkdir -p services/notifications

Update package.json name and dependencies for each new project.


Deployment

Project Type Deployment Options
Frontend Vercel, Netlify, Cloudflare Pages
API Railway, Fly.io, AWS Lambda, Docker
Workers Railway, Render, AWS ECS
Jobs Cron service, GitHub Actions, Temporal

Each project deploys independently from its directory.


Resources