Skip to content

A CLI tool to orchestrate scripts across monorepo workspaces (Bun, pnpm, npm) with parallel execution and dependency-aware builds.

License

Notifications You must be signed in to change notification settings

TorstenDittmann/workspace-utils

Repository files navigation

πŸ“¦ workspace-utils

A universal CLI tool for orchestrating scripts across monorepo workspaces (Bun, pnpm, npm) with parallel execution, dependency-aware builds, and real-time log streaming.

✨ Features

  • πŸš€ Parallel script execution across multiple packages
  • πŸ“Š Dependency-aware builds with topological sorting
  • 🎨 Color-coded, prefixed logs for easy identification
  • πŸ” Package filtering with glob patterns
  • ⚑ Configurable concurrency limits
  • πŸ—οΈ Smart build ordering respecting package dependencies
  • πŸ“Ί Real-time log streaming with timestamps
  • πŸ’Ύ Smart build caching - skip unchanged packages automatically
  • 🎯 Zero configuration - works with any workspace setup
  • 🌐 Universal support - works with Bun, pnpm, and npm workspaces

πŸ› οΈ Installation

# Install as dev dependency with npm
npm install --save-dev workspace-utils

# Install as dev dependency with pnpm
pnpm add -D workspace-utils

# Install as dev dependency with bun
bun add -d workspace-utils

πŸš€ Quick Start

First, add workspace-utils scripts to your root package.json:

{
	"scripts": {
		"dev": "wsu dev",
		"build": "wsu build",
		"test": "wsu run test",
		"lint": "wsu run lint --filter '@myorg/*'"
	}
}

Then run them:

# Run tests across all packages (parallel by default)
npm run test

# Build packages in dependency order
npm run build

# Start all dev servers with live logs
npm run dev

# Run linting on specific packages
npm run lint

πŸ“– Commands

run <script>

Run a script across multiple packages with support for parallel or sequential execution.

wsu run <script> [options]

Add to your package.json scripts and run with your package manager:

{
	"scripts": {
		"test": "wsu run test",
		"test:sequential": "wsu run test --sequential"
	}
}

Options:

  • -c, --concurrency <number> - Maximum concurrent processes (default: 4)
  • -f, --filter <pattern> - Filter packages by glob pattern
  • --sequential - Run scripts sequentially (default is parallel)

Examples:

# Run tests across all packages (parallel by default)
npm run test

# Run build sequentially
npm run test:sequential

# Run dev only for frontend packages (parallel by default)
npm run dev:frontend

# Run with custom concurrency
npm run lint

Example package.json scripts:

{
	"scripts": {
		"test": "wsu run test",
		"test:sequential": "wsu run test --sequential",
		"dev:frontend": "wsu run dev --filter '@myorg/frontend-*'",
		"lint": "wsu run lint --concurrency 8"
	}
}

build

Build packages in dependency order, ensuring dependencies are built before dependents.

wsu build [options]

Options:

  • -f, --filter <pattern> - Filter packages by pattern
  • -c, --concurrency <number> - Max concurrent builds per batch (default: 4)
  • --no-skip-unchanged - Build all packages (disable caching)

Examples:

# Build all packages in dependency order
npm run build

# Build only specific scope
npm run build:backend

# Build with higher concurrency per batch
npm run build:fast

Example package.json scripts:

{
	"scripts": {
		"build": "wsu build",
		"build:backend": "wsu build --filter '@myorg/backend-*'",
		"build:fast": "wsu build --concurrency 8"
	}
}

dev

Start development servers with live log streaming and graceful shutdown.

wsu dev [options]

Options:

  • -f, --filter <pattern> - Filter packages by pattern
  • -c, --concurrency <number> - Max concurrent dev servers (default: 4)

Examples:

# Start all dev servers
npm run dev

# Start only frontend dev servers
npm run dev:apps

# Limit concurrent dev servers
npm run dev:limited

Example package.json scripts:

{
	"scripts": {
		"dev": "wsu dev",
		"dev:apps": "wsu dev --filter 'apps/*'",
		"dev:limited": "wsu dev --concurrency 2"
	}
}

cache

Manage the build cache. View status or clear cached builds.

wsu cache [command]

Commands:

  • status - Show cache status (default)
  • clear - Clear all cached builds

Examples:

# View cache status
wsu cache

# Clear all cached builds
wsu cache clear

πŸ” Package Filtering

Use glob patterns to target specific packages:

{
	"scripts": {
		"test:scope": "wsu run test --filter '@myorg/*'",
		"build:backend": "wsu build --filter '@myorg/backend-*'",
		"dev:apps": "wsu dev --filter 'apps/*'",
		"lint:packages": "wsu run lint --filter 'packages/*'",
		"test:utils": "wsu run test --filter '*-utils' --sequential",
		"build:frontend": "wsu run build --filter '*frontend*'"
	}
}

Then run with:

npm run test:scope     # Scope-based filtering
npm run build:backend  # Build backend packages
npm run dev:apps       # Start app dev servers
npm run lint:packages  # Lint package directories
npm run test:utils     # Test utilities sequentially
npm run build:frontend # Build frontend packages

πŸ“Š Dependency Management

The tool automatically:

  1. Parses your workspace from package.json workspaces or pnpm-workspace.yaml
  2. Builds a dependency graph from package.json files
  3. Calculates build order using topological sorting
  4. Detects circular dependencies and reports them
  5. Executes in batches where each batch can run in parallel

Example Dependency Resolution

Given this structure:

β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ shared-utils/     (no dependencies)
β”‚   β”œβ”€β”€ ui-components/    (depends on shared-utils)
β”‚   └── api-client/       (depends on shared-utils)
└── apps/
    └── web-app/          (depends on ui-components, api-client)

Build order will be:

  1. Batch 1: shared-utils (parallel with others in batch)
  2. Batch 2: ui-components, api-client (parallel with each other)
  3. Batch 3: web-app

🎨 Log Output

Logs are color-coded and prefixed for easy identification:

[shared-utils] Building shared utilities...
[ui-components] Starting component library build...
[web-app] Compiling application...
[shared-utils] βœ… Completed in 1,234ms
[ui-components] βœ… Completed in 2,456ms
[web-app] βœ… Completed in 3,789ms

πŸ“ Workspace Requirements

Your project must have one of the following workspace configurations:

npm/Bun workspaces (package.json):

{
	"name": "my-monorepo",
	"private": true,
	"workspaces": ["packages/*", "apps/*"],
	"scripts": {
		"build": "wsu build",
		"dev": "wsu dev",
		"test": "wsu run test"
	}
}

pnpm workspaces (pnpm-workspace.yaml):

packages:
    - "packages/*"
    - "apps/*"

🌐 Package Manager Support

This tool works seamlessly with:

  • npm workspaces - Uses standard package.json workspaces
  • pnpm workspaces - Supports pnpm-workspace.yaml configuration
  • Bun workspaces - Works with Bun's workspace implementation
  • Auto-detection - Automatically detects your package manager and workspace setup

⚑ Performance Tips

  1. Use filtering to target only the packages you need
  2. Adjust concurrency based on your system resources (default: 4)
  3. Parallel by default - most scripts benefit from parallel execution
  4. Use --sequential only when order matters or for resource-intensive tasks
  5. For builds, dependency ordering ensures correct execution even in parallel batches
  6. For dev servers, use reasonable concurrency limits to avoid resource exhaustion

πŸ› Troubleshooting

"No workspaces configuration found"

Ensure your project has one of the following:

  • Root package.json with a workspaces field
  • pnpm-workspace.yaml file with package patterns

"Circular dependencies detected"

Check your package dependencies for circular references:

# This will show the circular dependency chain
npm run build

"No packages found with script"

Verify your packages have the required script in their package.json:

# Check which packages have the script
npx wsu run nonexistent-script

πŸ›£οΈ Roadmap

  • Watch mode - Restart processes on file changes
  • Interactive mode - Focus on specific package logs
  • Custom log formatters - Configurable output styles
  • Dry run mode - Preview execution plan
  • Yarn workspaces support - Add support for Yarn workspaces

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

πŸ“„ License

MIT License - see LICENSE file for details.

πŸ™ Acknowledgments

  • Built for the modern JavaScript ecosystem
  • Inspired by the need for universal monorepo tooling
  • Thanks to the communities behind npm, pnpm, and Bun for creating excellent package managers

Made with ❀️ for the JavaScript monorepo community

About

A CLI tool to orchestrate scripts across monorepo workspaces (Bun, pnpm, npm) with parallel execution and dependency-aware builds.

Resources

License

Stars

Watchers

Forks

Packages

No packages published