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).
- π 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
# 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# 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# Generate with multiple entities (bundle-optimized)
mlg contract product --entities Product,ProductCategory,ProductReview
# Or generate with CQRS and RPC patterns
mlg contract product --includeCQRS --includeRPCCreates:
- 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-shakeableimport type { Product } from '@repo/contract-product/types'- Zero runtime overheadimport { Product } from '@repo/contract-product'- Convenience (all entities)
Purpose: Define domain boundaries and interfaces (dependency inversion)
mlg data-access productCreates:
- 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
mlg feature user-management --platform universal --includeRPCCreates:
- 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
mlg infra cache --platform nodeCreates:
- 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)
mlg provider stripe --externalService stripe --platform nodeCreates:
- 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
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
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
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
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 managementinfra-cache- Caching (Redis, Memory)infra-storage- File storage (S3, Supabase)infra-logging- Structured logginginfra-queue- Job queues
Dependencies: provider-* (external service adapters)
Used By: data-access, feature, apps
Learn More: docs/INFRA.md
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 APIprovider-supabase- Supabase clientprovider-kysely- Kysely query builderprovider-redis- Redis clientprovider-sentry- Sentry error tracking
Dependencies: External SDKs (stripe, @supabase/supabase-js, etc.)
Used By: infra, feature
Learn More: docs/PROVIDER.md
// 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
})// β
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!
})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
})
}
}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'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
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 tagsmlg data-access <name> [options]
Options:
--description <desc> Library description
--directory <dir> Custom parent directory
--tags <tags> Comma-separated tagsmlg 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 tagsmlg 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 tagsmlg 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- Node.js 18+ (20+ recommended)
- TypeScript 5.6+
- Effect 3.0+
- Monorepo Tool: Nx, pnpm workspaces, Yarn workspaces, or Turborepo
- β ~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
All libraries include:
package.jsonwith proper exports configurationtsconfig.jsonextending workspace basetsconfig.lib.jsonfor library compilation (composite mode)tsconfig.spec.jsonfor test compilationREADME.mdwith library-specific documentationCLAUDE.mdfor AI agent reference- Comprehensive inline documentation
- Architecture Overview - System architecture and design
- Effect Patterns - Effect-TS patterns and standardized layers β¨ UPDATED
- Export Patterns - Platform export conventions
- Contract Libraries - Contract generator guide
- Examples - End-to-end examples β¨ UPDATED
- Implementation Complete - Effect layer standardization summary β¨ NEW
- Migration Guide - Upgrade guide for naming changes β¨ NEW
- Layer Naming Standards - Official naming conventions β¨ UPDATED
- Data-Access Libraries - Data-access generator guide
- Feature Libraries - Feature generator guide
- Infrastructure Libraries - Infrastructure generator guide
- Provider Libraries - Provider generator guide
- Nx Standards - Workspace conventions
Contributions welcome! Please read CONTRIBUTING.md for guidelines.
git clone https://github.com/samuelho-dev/monorepo-library-generator
cd monorepo-library-generator
pnpm install
pnpm testMIT Β© Samuel Ho
Made with Effect β‘οΈ | Workspace Agnostic π | Type Safe π‘οΈ