@williamthorsen/nmr
v0.5.0
Published
Context-aware script runner for PNPM monorepos
Maintainers
Readme
@williamthorsen/nmr
Context-aware script runner for PNPM monorepos. Ships an nmr (node-monorepo run) binary that provides centralized, consistent script execution across workspace packages and the monorepo root.
Installation
pnpm add -D @williamthorsen/nmrCLI usage
nmr <command> # Context-aware: root vs package
nmr -F, --filter <pattern> <command> # Run in matching packages
nmr -R, --recursive <command> # Run in all packages
nmr -w, --workspace-root <command> # Force root script registry
nmr -?, --help # Show available commands
nmr --int-test <command> # Use integration test scriptsExamples
# From a package directory
nmr test # Runs workspace test script
nmr build # Runs compile && generate-typings
# From the monorepo root
nmr test # Runs root test + recursive workspace tests
nmr ci # Runs check:strict && build
# Targeting specific packages
nmr -F core test # Test only the core package
nmr -R lint # Lint all workspace packages
# Force root context from anywhere
nmr -w check # Run root check from a package dirConfiguration
Create .config/nmr.config.ts in the monorepo root to add or override scripts:
import { defineConfig } from '@williamthorsen/nmr';
export default defineConfig({
workspaceScripts: {
'copy-content': 'tsx scripts/copy-content.ts',
},
rootScripts: {
'demo:catwalk': 'pnpx http-server --port=5189 demos/catwalk/',
},
});Three-tier override system
- Package defaults — built-in scripts shipped with this package
- Repo-wide config — additions/overrides in
.config/nmr.config.ts - Per-package overrides — in a package's
package.jsonscriptsfield
Per-package overrides take highest precedence. Set a script to "" in package.json to skip it for that package.
Script values can be string or string[]. Arrays expand to chained nmr invocations:
// "build": ["compile", "generate-typings"]
// expands to: nmr compile && nmr generate-typingsAdditional subcommands
These commands are available as nmr subcommands and as standalone nmr--prefixed binaries (for use in lifecycle hooks).
report-overrides
Report any active pnpm.overrides in the root package.json. Useful as a postinstall hook to remind developers of active overrides that may need cleanup.
nmr report-overridessync-pnpm-version
Synchronize the pnpm version from the root package.json packageManager field into the GitHub code-quality.yaml workflow file.
nmr sync-pnpm-versionStandalone utilities
ensure-prepublish-hooks
Verify that all publishable workspace packages have a prepublishOnly script. Exits non-zero if any are missing.
ensure-prepublish-hooks # Check only
ensure-prepublish-hooks --fix # Add missing hooks (default: "npm run build")
ensure-prepublish-hooks --dry-run # Preview what --fix would do
ensure-prepublish-hooks --command "pnpm build" # Use a custom hook commandConsumer migration
After installing, a consuming repo's root package.json scripts shrink to lifecycle hooks:
{
"prepare": "lefthook install",
"postinstall": "nmr report-overrides"
}Per-package package.json files no longer need script entries. Run nmr <command> directly.
Consistency tests
Export structural consistency checks for use in your test suite:
// __tests__/consistency.test.ts
import { runConsistencyChecks } from '@williamthorsen/nmr/tests';
runConsistencyChecks();This verifies:
- pnpm version matches between
package.jsonand GitHub workflow - Node.js version matches between
.tool-versionsand GitHub workflow
