Skip to content

Generate well architected monorepo libraries based on Effect and Nx monorepos. Based on design architectures like Repository, Infrastructure Domain Driven Design, Contract, Adapter, and Feature library patterns.

License

Notifications You must be signed in to change notification settings

samuelho-dev/monorepo-library-generator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

32 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@samuelho-dev/monorepo-library-generator

Effect-based monorepo library generator with workspace-agnostic architecture

Generate production-ready TypeScript libraries for Effect-native monorepos with a single command. Supports 5 library types following Effect 3.0+ best practices and works with any monorepo tool (Nx, pnpm, Yarn, Turborepo).

✨ Key Features

  • πŸš€ 5 Library Types: Contract, Data-Access, Feature, Infrastructure, Provider
  • 🎯 Effect 3.0+: Context.Tag, Layer.scoped, Data.TaggedError, Schema.Class
  • πŸ“¦ Workspace Agnostic: Works with Nx, pnpm workspaces, Yarn, Turborepo
  • 🌍 Platform Aware: Generate server/client/edge exports automatically
  • πŸ”§ TypeScript 5.6+: Strict mode, project references, composite builds
  • πŸ§ͺ Testing Ready: Vitest + @effect/vitest integration
  • πŸ›‘οΈ Resource Safe: Layer.scoped pattern prevents resource leaks
  • πŸ“š Self-Documenting: Comprehensive inline docs and CLAUDE.md files
  • πŸ—οΈ Best Practices: Follows Effect-TS patterns and modern monorepo conventions
  • 🌳 Bundle Optimized: Tree-shakeable exports with granular subpath patterns for contract libraries

πŸ“¦ Installation

As Standalone CLI

# Run directly with npx (no installation required)
npx @samuelho-dev/monorepo-library-generator contract product

# Or install globally
npm install -g @samuelho-dev/monorepo-library-generator
mlg contract product

As Nx Generator (in Nx workspace)

# Install as dev dependency
npm install -D @samuelho-dev/monorepo-library-generator

# Use with nx generate
npx nx g @samuelho-dev/monorepo-library-generator:contract product

πŸš€ Quick Start

Generate a Contract Library

# Generate with multiple entities (bundle-optimized)
mlg contract product --entities Product,ProductCategory,ProductReview

# Or generate with CQRS and RPC patterns
mlg contract product --includeCQRS --includeRPC

Creates:

  • Domain entities with Effect Schema (separate files for tree-shaking)
  • Repository interfaces (ports) with Context.Tag
  • Domain errors with Data.TaggedError
  • Domain events
  • Type-only exports for zero-bundle-impact imports
  • Optional: CQRS commands/queries
  • Optional: RPC endpoint definitions

Bundle Optimization: Contract libraries use separate entity files with granular package.json exports:

  • import { Product } from '@repo/contract-product/entities/product' - Tree-shakeable
  • import type { Product } from '@repo/contract-product/types' - Zero runtime overhead
  • import { Product } from '@repo/contract-product' - Convenience (all entities)

Purpose: Define domain boundaries and interfaces (dependency inversion)


Generate a Data-Access Library

mlg data-access product

Creates:

  • Repository implementation (fulfills contract ports)
  • Kysely query builders
  • Data transformations and validation
  • Layer compositions (Live, Test, Dev, Auto)
  • Comprehensive tests with @effect/vitest

Purpose: Database operations and persistence layer


Generate a Feature Library

mlg feature user-management --platform universal --includeRPC

Creates:

  • Business logic service with Context.Tag
  • Server-side service implementation
  • Client-side React hooks (if platform includes client)
  • Edge runtime middleware (if platform includes edge)
  • Layer compositions with dependency injection
  • Optional: RPC router definitions

Purpose: Application features and business logic orchestration


Generate an Infrastructure Library

mlg infra cache --platform node

Creates:

  • Service interface with Context.Tag
  • Multiple provider implementations (Memory, Redis, etc.)
  • Type-safe configuration with Effect Config
  • Server/client/edge layers (platform-dependent)
  • Error types and validation

Purpose: Cross-cutting technical services (caching, logging, storage)


Generate a Provider Library

mlg provider stripe --externalService stripe --platform node

Creates:

  • Effect-based service wrapper with Context.Tag
  • Safe error mapping from SDK errors
  • Layer implementations (Live, Test, Dev, Auto) with proper cleanup
  • Type-safe request/response types
  • Platform-specific exports (server/client/edge)

Purpose: External service integration with consistent Effect interfaces


πŸ“š Library Types & Patterns

1. Contract Libraries (contract-*)

Purpose: Domain boundaries through interfaces and types

Key Patterns:

  • βœ… Interface-before-implementation (dependency inversion)
  • βœ… Effect Schema for entities
  • βœ… Data.TaggedError for domain errors
  • βœ… Context.Tag for repository interfaces
  • βœ… Platform-agnostic (universal exports only)

Generated Structure:

libs/contract/{domain}/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts              # Universal exports
β”‚   └── lib/
β”‚       β”œβ”€β”€ entities.ts       # Schema.Class entities
β”‚       β”œβ”€β”€ errors.ts         # Data.TaggedError types
β”‚       β”œβ”€β”€ events.ts         # Domain events
β”‚       β”œβ”€β”€ ports.ts          # Repository interfaces (Context.Tag)
β”‚       β”œβ”€β”€ commands.ts       # CQRS commands (optional)
β”‚       β”œβ”€β”€ queries.ts        # CQRS queries (optional)
β”‚       └── rpc.ts            # RPC definitions (optional)
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ tsconfig.lib.json
β”œβ”€β”€ tsconfig.spec.json
β”œβ”€β”€ README.md
└── CLAUDE.md                 # AI agent reference

Dependencies: None (pure domain)

Used By: data-access, feature

Learn More: docs/CONTRACT.md


2. Data-Access Libraries (data-access-*)

Purpose: Repository pattern implementation with database operations

Key Patterns:

  • βœ… Implements contract repository interfaces
  • βœ… Kysely query builders for type-safe SQL
  • βœ… Layer.scoped for connection management
  • βœ… Effect.acquireRelease for transaction handling
  • βœ… Repository errors with Data.TaggedError

Generated Structure:

libs/data-access/{domain}/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts              # Universal exports
β”‚   └── lib/
β”‚       β”œβ”€β”€ shared/
β”‚       β”‚   β”œβ”€β”€ errors.ts     # Repository errors
β”‚       β”‚   β”œβ”€β”€ types.ts      # Filter types, pagination
β”‚       β”‚   └── validation.ts # Input validation
β”‚       β”œβ”€β”€ repository.ts     # Repository implementation
β”‚       β”œβ”€β”€ queries.ts        # Kysely query builders
β”‚       └── server/
β”‚           └── layers.ts     # Layer compositions
β”œβ”€β”€ package.json
└── ...

Dependencies:

  • contract-{domain} (implements interfaces)
  • infra-database (database service)
  • provider-kysely (query builder)

Used By: feature

Learn More: docs/DATA-ACCESS.md


3. Feature Libraries (feature-*)

Purpose: Business logic and application feature orchestration

Key Patterns:

  • βœ… Service pattern with Context.Tag
  • βœ… Layer composition for dependency injection
  • βœ… Platform-aware exports (server/client/edge)
  • βœ… React hooks for client-side integration
  • βœ… Edge middleware for CDN edge runtime

Generated Structure:

libs/feature/{name}/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts              # Universal exports
β”‚   β”œβ”€β”€ server.ts             # Server-side exports (Node.js)
β”‚   β”œβ”€β”€ client.ts             # Client-side exports (browser)
β”‚   β”œβ”€β”€ edge.ts               # Edge runtime exports (Vercel/Cloudflare)
β”‚   └── lib/
β”‚       β”œβ”€β”€ shared/
β”‚       β”‚   β”œβ”€β”€ errors.ts     # Feature errors
β”‚       β”‚   β”œβ”€β”€ types.ts      # Shared types
β”‚       β”‚   └── schemas.ts    # Validation schemas
β”‚       β”œβ”€β”€ server/
β”‚       β”‚   β”œβ”€β”€ service.ts    # Business logic (Context.Tag)
β”‚       β”‚   β”œβ”€β”€ layers.ts     # Layer compositions
β”‚       β”‚   └── service.spec.ts
β”‚       β”œβ”€β”€ client/           # React integration (if platform includes browser)
β”‚       β”‚   β”œβ”€β”€ hooks/
β”‚       β”‚   β”œβ”€β”€ atoms/        # Jotai state
β”‚       β”‚   └── components/
β”‚       β”œβ”€β”€ rpc/              # RPC endpoints (optional)
β”‚       β”‚   β”œβ”€β”€ rpc.ts
β”‚       β”‚   └── handlers.ts
β”‚       └── edge/             # Edge middleware (if platform includes edge)
β”‚           └── middleware.ts
β”œβ”€β”€ package.json
└── ...

Dependencies:

  • data-access-{domain} (repositories)
  • contract-{domain} (domain types)
  • infra-* (logging, caching, etc.)
  • provider-* (external services)

Used By: apps (web, api, edge functions)

Learn More: docs/FEATURE.md


4. Infrastructure Libraries (infra-*)

Purpose: Cross-cutting technical services and resource management

Key Patterns:

  • βœ… Service interface with Context.Tag
  • βœ… Multiple provider implementations
  • βœ… Layer.scoped for resource cleanup
  • βœ… Effect Config for type-safe configuration
  • βœ… Platform-specific layers (server/client/edge)

Generated Structure:

libs/infra/{concern}/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts              # Universal exports
β”‚   β”œβ”€β”€ server.ts             # Server-side exports
β”‚   β”œβ”€β”€ client.ts             # Client-side exports (if applicable)
β”‚   β”œβ”€β”€ edge.ts               # Edge exports (if applicable)
β”‚   └── lib/
β”‚       β”œβ”€β”€ service/
β”‚       β”‚   β”œβ”€β”€ interface.ts  # Service interface (Context.Tag)
β”‚       β”‚   β”œβ”€β”€ errors.ts     # Service errors
β”‚       β”‚   └── config.ts     # Effect Config
β”‚       β”œβ”€β”€ providers/
β”‚       β”‚   β”œβ”€β”€ memory.ts     # In-memory implementation
β”‚       β”‚   β”œβ”€β”€ redis.ts      # Redis implementation (example)
β”‚       β”‚   └── ...
β”‚       └── layers/
β”‚           β”œβ”€β”€ server-layers.ts
β”‚           β”œβ”€β”€ client-layers.ts
β”‚           └── edge-layers.ts
β”œβ”€β”€ package.json
└── ...

Common Examples:

  • infra-database - Database connection management
  • infra-cache - Caching (Redis, Memory)
  • infra-storage - File storage (S3, Supabase)
  • infra-logging - Structured logging
  • infra-queue - Job queues

Dependencies: provider-* (external service adapters)

Used By: data-access, feature, apps

Learn More: docs/INFRA.md


5. Provider Libraries (provider-*)

Purpose: Wrap external SDKs with consistent Effect interfaces

Key Patterns:

  • βœ… Effect-based service wrapper (Context.Tag)
  • βœ… Safe error mapping from SDK errors to Effect errors
  • βœ… Layer.scoped with Effect.addFinalizer for cleanup
  • βœ… Mock factories for testing
  • βœ… Platform-specific exports

Generated Structure:

libs/provider/{service}/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts              # Universal exports
β”‚   β”œβ”€β”€ server.ts             # Server-side exports
β”‚   β”œβ”€β”€ client.ts             # Client-side exports (if applicable)
β”‚   β”œβ”€β”€ edge.ts               # Edge exports (if applicable)
β”‚   └── lib/
β”‚       β”œβ”€β”€ service.ts        # Service implementation (Context.Tag)
β”‚       β”œβ”€β”€ errors.ts         # Mapped SDK errors
β”‚       β”œβ”€β”€ types.ts          # Request/response types
β”‚       β”œβ”€β”€ validation.ts     # Input validation
β”‚       β”œβ”€β”€ layers.ts         # Layer.scoped implementations
β”‚       └── service.spec.ts
β”œβ”€β”€ package.json
└── ...

Common Examples:

  • provider-stripe - Stripe payments API
  • provider-supabase - Supabase client
  • provider-kysely - Kysely query builder
  • provider-redis - Redis client
  • provider-sentry - Sentry error tracking

Dependencies: External SDKs (stripe, @supabase/supabase-js, etc.)

Used By: infra, feature

Learn More: docs/PROVIDER.md


🎯 Key Patterns & Best Practices

Effect 3.0+ Patterns

Context.Tag for Dependency Injection

// Service definition
export class UserService extends Context.Tag("UserService")<
  UserService,
  {
    readonly findById: (id: string) => Effect.Effect<User, UserNotFoundError>
    readonly create: (data: CreateUserData) => Effect.Effect<User, ValidationError>
  }
>() {}

// Usage
const program = Effect.gen(function* () {
  const userService = yield* UserService
  const user = yield* userService.findById("123")
  return user
})

Layer.scoped for Resource Management

// βœ… CORRECT: Layer.scoped with cleanup
export const RedisServiceLive = Layer.scoped(
  RedisService,
  Effect.gen(function* () {
    const client = yield* Effect.sync(() => createRedisClient(config))

    // Register cleanup function
    yield* Effect.addFinalizer(() =>
      Effect.sync(() => {
        client.disconnect()
        console.log("[Redis] Connection closed")
      })
    )

    return RedisService.make(client)
  })
)

// ❌ WRONG: Layer.sync without cleanup (causes resource leaks)
export const RedisServiceWrong = Layer.sync(RedisService, () => {
  const client = createRedisClient(config)
  return RedisService.make(client)
  // Client never disconnected! Memory leak!
})

Data.TaggedError for Type-Safe Errors

export class UserNotFoundError extends Data.TaggedError("UserNotFoundError")<{
  readonly message: string
  readonly userId: string
}> {
  static create(userId: string) {
    return new UserNotFoundError({
      message: `User not found: ${userId}`,
      userId
    })
  }
}

Platform-Aware Exports

The generator creates platform-specific export files based on your platform setting:

// Universal libraries (contract, util)
import { User } from '@myorg/contract-user'

// Node.js/Server-side (feature, infra, provider with platform: node)
import { UserService } from '@myorg/feature-user/server'
import { DatabaseService } from '@myorg/infra-database/server'
import { StripeService } from '@myorg/provider-stripe/server'

// Browser/Client-side (feature with platform: universal)
import { useUser } from '@myorg/feature-user/client'
import { userAtoms } from '@myorg/feature-user/client'

// Edge Runtime (feature with platform: edge)
import { authMiddleware } from '@myorg/feature-auth/edge'

Workspace-Agnostic Architecture

The generator works with any monorepo tool:

  • Nx Workspaces: Full integration with project graph and references
  • pnpm Workspaces: Uses workspace protocol and package.json exports
  • Yarn Workspaces: Compatible with Yarn workspace patterns
  • Turborepo: Works with Turborepo's task orchestration

The generator automatically detects your workspace type and adapts:

  • Extracts package scope from root package.json
  • Computes TypeScript project references (with graceful fallback for non-Nx)
  • Uses pnpm workspace protocol for dependencies

πŸ”§ CLI Options

Contract Generator

mlg contract <name> [options]

Options:
  --description <desc>    Library description
  --includeCQRS          Include CQRS patterns (commands, queries, projections)
  --includeRPC           Include RPC endpoint definitions
  --directory <dir>      Custom parent directory
  --tags <tags>          Comma-separated tags

Data-Access Generator

mlg data-access <name> [options]

Options:
  --description <desc>    Library description
  --directory <dir>      Custom parent directory
  --tags <tags>          Comma-separated tags

Feature Generator

mlg feature <name> [options]

Options:
  --description <desc>    Library description
  --platform <platform>   Platform target: node | browser | universal | edge
  --includeClientServer  Generate both client and server exports
  --includeRPC           Include RPC router
  --includeCQRS          Include CQRS structure
  --includeEdge          Include edge runtime support
  --directory <dir>      Custom parent directory
  --tags <tags>          Comma-separated tags

Infrastructure Generator

mlg infra <name> [options]

Options:
  --description <desc>    Library description
  --platform <platform>   Platform target: node | browser | universal | edge
  --includeClientServer  Generate both client and server exports
  --includeEdge          Include edge runtime support
  --directory <dir>      Custom parent directory
  --tags <tags>          Comma-separated tags

Provider Generator

mlg provider <name> --externalService <service> [options]

Options:
  --externalService <service>  External service name (required)
  --description <desc>         Library description
  --platform <platform>        Platform target: node | browser | universal | edge
  --includeClientServer       Generate both client and server exports
  --directory <dir>           Custom parent directory
  --tags <tags>               Comma-separated tags

πŸ“‹ Requirements

  • Node.js 18+ (20+ recommended)
  • TypeScript 5.6+
  • Effect 3.0+
  • Monorepo Tool: Nx, pnpm workspaces, Yarn workspaces, or Turborepo

πŸ—οΈ Architecture Highlights

Recent Improvements (v1.2.3+)

  • βœ… ~700+ lines of duplication eliminated through shared utilities
  • βœ… Layer.scoped pattern prevents resource leaks in providers
  • βœ… Platform exports (server/client/edge) for all library types
  • βœ… Workspace-agnostic architecture supports any monorepo tool
  • βœ… Dynamic scope detection from workspace root package.json
  • βœ… Unified wrapper pattern across all 5 generators
  • βœ… Shared infrastructure generator consolidates file generation
  • βœ… TypeScript project references with graceful non-Nx fallback

Generated Files

All libraries include:

  • package.json with proper exports configuration
  • tsconfig.json extending workspace base
  • tsconfig.lib.json for library compilation (composite mode)
  • tsconfig.spec.json for test compilation
  • README.md with library-specific documentation
  • CLAUDE.md for AI agent reference
  • Comprehensive inline documentation

πŸ“– Documentation

Core Documentation

Implementation & Migration (v2.0)


🀝 Contributing

Contributions welcome! Please read CONTRIBUTING.md for guidelines.

Development Setup

git clone https://github.com/samuelho-dev/monorepo-library-generator
cd monorepo-library-generator
pnpm install
pnpm test

πŸ“ License

MIT Β© Samuel Ho


πŸ”— Links


Made with Effect ⚑️ | Workspace Agnostic 🌍 | Type Safe πŸ›‘οΈ

About

Generate well architected monorepo libraries based on Effect and Nx monorepos. Based on design architectures like Repository, Infrastructure Domain Driven Design, Contract, Adapter, and Feature library patterns.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages