Lerna is a fast, modern build system for managing and publishing multiple JavaScript/TypeScript packages from the same repository
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Interactive configuration and optimization tools for monorepo setup.
Create a new Lerna workspace with proper configuration.
# Initialize new Lerna workspace
lerna init
# Initialize with independent versioning
lerna init --independent
# Initialize with Nx integration
lerna init --use-nx
# Initialize in existing workspace
lerna init --exact
# Additional initialization options
lerna init --packages "packages/*,libs/*" # Custom package patterns
lerna init --dry-run # Preview changes without modifying
lerna init --skip-install # Skip dependency installationInitialization creates:
lerna.json configuration filepackage.json with workspace configurationCreate a new lerna-managed package within the workspace.
# Create new package with basic setup
lerna create <name>
# Create package in specific location
lerna create <name> [location]
# Create with additional options
lerna create my-package --description "My package description"
lerna create @myorg/ui-components --private
lerna create my-cli --bin --es-modulePackage Creation Options:
--access - When using a scope, set publishConfig.access value (public, restricted)--bin - Package has an executable. Optionally specify executable name--description - Package description--dependencies - Array of package dependencies to add--es-module - Initialize as a transpiled ES Module--homepage - Package homepage URL--keywords - Array of package keywords--license - SPDX license identifier (default: ISC)--private - Make package private, never published externally--registry - Configure the package's publishConfig.registry--tag - Configure the package's publishConfig.tag--yes / -y - Skip all prompts, accepting default valuesPackage Creation Process:
Usage Examples:
# Create basic package
lerna create utils
# Create scoped private package
lerna create @myorg/internal-utils --private --description "Internal utilities"
# Create CLI package with executable
lerna create my-cli --bin my-cli --keywords cli,tools
# Create ES module package with dependencies
lerna create modern-utils --es-module --dependencies lodash,axios
# Create package in custom location
lerna create special-package ./libs
# Create package non-interactively
lerna create batch-package --yes --license MIT --homepage "https://myorg.com"Interactive configuration generator for Nx task runner caching.
# Configure caching interactively
lerna add-caching
# Available when useNx is enabled in lerna.jsonAdd Caching Process:
nx.json with optimized settings.nx/cache to .gitignoreAutomated migrations to repair workspace state and apply updates.
# Run automated repairs
lerna repair
# Run with verbose output for debugging
lerna repair --verboseRepair operations:
Watch for changes in packages and automatically execute commands when changes occur.
# Watch for changes and run command
lerna watch -- <command>
# Examples
lerna watch -- npm run build
lerna watch -- npm test
lerna watch -- echo "Files changed in $LERNA_PACKAGE_NAME"
# Watch with verbose output
lerna watch --verbose -- npm run build
# Watch specific packages
lerna watch --scope="@myorg/*" -- npm run build
lerna watch --ignore="*-test" -- npm run lintWatch command features:
$LERNA_PACKAGE_NAME and $LERNA_FILE_CHANGESDisplay environment and configuration information for debugging.
# Show environment information
lerna info
# Display Lerna version, Node.js version, npm version
# Show workspace configuration
# List detected packagesPrimary Lerna configuration file:
{
"version": "1.0.0",
"packages": ["packages/*"],
"useNx": true,
"npmClient": "npm",
"registry": "https://registry.npmjs.org",
"command": {
"publish": {
"conventionalCommits": true,
"message": "chore: publish",
"registry": "https://registry.npmjs.org",
"access": "public"
},
"version": {
"allowBranch": ["main", "master"],
"conventionalCommits": true,
"createRelease": "github",
"push": true
},
"bootstrap": {
"npmClientArgs": ["--no-package-lock"]
}
},
"ignoreChanges": [
"**/*.md",
"**/test/**",
"**/__tests__/**"
]
}interface LernaConfig {
/** Workspace version (fixed) or "independent" */
version: string;
/** Package location patterns */
packages: string[];
/** Use Nx task runner for enhanced performance */
useNx?: boolean;
/** npm client (npm, yarn, pnpm) */
npmClient?: 'npm' | 'yarn' | 'pnpm';
/** Default npm registry */
registry?: string;
/** Command-specific configurations */
command?: {
publish?: PublishConfig;
version?: VersionConfig;
bootstrap?: BootstrapConfig;
run?: RunConfig;
exec?: ExecConfig;
};
/** Patterns to ignore for change detection */
ignoreChanges?: string[];
/** Nx-specific configuration */
useWorkspaces?: boolean;
granularPathspec?: boolean;
}
interface PublishConfig {
conventionalCommits?: boolean;
message?: string;
registry?: string;
access?: 'public' | 'restricted';
distTag?: string;
skipNpm?: boolean;
skipGit?: boolean;
yes?: boolean;
verifyAccess?: boolean;
}
interface VersionConfig {
allowBranch?: string | string[];
conventionalCommits?: boolean;
createRelease?: 'github' | 'gitlab';
push?: boolean;
exact?: boolean;
message?: string;
signGitCommit?: boolean;
signGitTag?: boolean;
}
interface BootstrapConfig {
npmClientArgs?: string[];
hoist?: boolean | string[];
nohoist?: string[];
ignore?: string[];
ignorePrepublish?: boolean;
}
interface RunConfig {
npmClient?: string;
stream?: boolean;
parallel?: boolean;
bail?: boolean;
}
interface ExecConfig {
bail?: boolean;
parallel?: boolean;
stream?: boolean;
}Configure workspace in root package.json:
{
"name": "my-workspace",
"private": true,
"workspaces": [
"packages/*"
],
"devDependencies": {
"lerna": "^8.2.4"
},
"scripts": {
"build": "lerna run build",
"test": "lerna run test",
"publish": "lerna publish",
"version": "lerna version"
}
}When useNx: true, configure task runner via nx.json:
{
"targetDefaults": {
"build": {
"dependsOn": ["^build"],
"cache": true,
"outputs": ["{projectRoot}/dist", "{projectRoot}/lib"]
},
"test": {
"cache": true,
"outputs": ["{projectRoot}/coverage"]
},
"lint": {
"cache": true
}
},
"cacheDirectory": ".nx/cache",
"defaultBase": "main"
}Configure npm behavior via .npmrc:
# Registry configuration
registry=https://registry.npmjs.org
@myorg:registry=https://custom-registry.com
# Authentication
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
//custom-registry.com/:_authToken=${CUSTOM_TOKEN}
# Package configuration
save-exact=true
package-lock=falseConfigure git behavior:
# Set commit message template
git config commit.template .gitmessage
# Configure signing
git config commit.gpgsign true
git config tag.gpgsign true
# Set default branch
git config init.defaultBranch mainworkspace/
├── lerna.json
├── package.json
├── nx.json (if useNx: true)
├── packages/
│ ├── package-a/
│ │ ├── package.json
│ │ └── src/
│ └── package-b/
│ ├── package.json
│ └── src/
├── tools/ (optional)
├── docs/ (optional)
└── .github/ (CI/CD)Standard package layout:
packages/my-package/
├── package.json
├── src/
├── lib/ or dist/ (build output)
├── test/ or __tests__/
├── README.md
└── CHANGELOG.md (generated)# Migrate from legacy Lerna configuration
lerna repair
# Update deprecated options
lerna repair --verboseEnable Nx for existing workspace:
{
"useNx": true
}Then run:
# Configure Nx caching
lerna add-caching
# Initialize nx.json if needed
npx nx init# Verify configuration
lerna info
# Check package detection
lerna list --all
# Validate workspace structure
lerna exec -- pwd
# Debug configuration loading
lerna --loglevel=verbose list# Validate lerna.json syntax
node -e "console.log(JSON.parse(require('fs').readFileSync('lerna.json')))"
# Check workspace packages match configuration
lerna list --json | jq '.[].location'
# Verify nx.json syntax (if using Nx)
npx nx show projects# Reset to default configuration
rm lerna.json nx.json
lerna init
# Clean workspace state
lerna clean --yes
npm install
# Repair any issues
lerna repair