workspace-utils
v2.1.3
Published
A CLI tool to orchestrate scripts across monorepo workspaces (Bun, pnpm, npm) with parallel execution and dependency-aware builds.
Maintainers
Readme
📦 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
- 📁 Artifact restoration inferred from package metadata (
files, exports, entry points) - 🎯 Affected package detection from Git changes and downstream dependents
- 🔗 Relationship filters for dependencies and dependents
- 🧭 Dry runs and dependency graph output for CI planning
- 🎯 Zero configuration - works with any workspace setup
- 🌐 Universal support - works with Bun, pnpm, and npm workspaces
- 🧶 Yarn Berry support with explicit modern Yarn detection
🛠️ 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)--topological- Run dependencies before dependents--affected/--since <ref>- Run only packages affected by Git changes--dry-run- Print the plan without starting scripts--fail-fast,--continue-on-error,--retry,--timeout- Control failures
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 lintExample 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:fastExample 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:limitedExample 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 clearPersist .wsu/ between CI runs to reuse metadata and restorable build artifacts. See the
caching guide
for output declarations, cache-key guidance, and a complete GitHub Actions example.
🔍 Package Filtering
Filters are repeatable and support package names, paths, exclusions, dependencies, and dependents:
wsu run test --filter 'app...' # app and its dependencies
wsu run test --filter '...core' # core and all dependents
wsu run test --filter './apps/*' # packages by directory
wsu run test --filter '@scope/*' --filter '!@scope/docs'Changed packages, plans, and graphs
wsu run test --affected
wsu build --since origin/main
wsu build --dry-run
wsu graph --format text
wsu graph --format json
wsu graph --format dot
wsu --output json run test --affected # newline-delimited JSON eventsBuild artifacts are inferred exclusively from package metadata. Packages without declared output paths still build normally but are not artifact-cached.
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:
- Parses your workspace from
package.jsonworkspaces orpnpm-workspace.yaml - Builds a dependency graph from
package.jsonfiles - Calculates build order using topological sorting
- Detects circular dependencies and reports them
- 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:
- Batch 1:
shared-utils(parallel with others in batch) - Batch 2:
ui-components,api-client(parallel with each other) - 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.jsonworkspaces - pnpm workspaces - Supports
pnpm-workspace.yamlconfiguration - Bun workspaces - Works with Bun's workspace implementation
- Auto-detection - Automatically detects your package manager and workspace setup
⚡ Performance Tips
- Use filtering to target only the packages you need
- Adjust concurrency based on your system resources (default: 4)
- Parallel by default - most scripts benefit from parallel execution
- Use --sequential only when order matters or for resource-intensive tasks
- For builds, dependency ordering ensures correct execution even in parallel batches
- 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.jsonwith aworkspacesfield pnpm-workspace.yamlfile 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
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - 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
