lpm bench
Auto-detect and run the project's benchmark runner.
lpm bench [-- args...]Detects whether the project uses vitest bench and runs it, forwarding any trailing arguments verbatim.
Examples
lpm bench
lpm bench src/parser.bench.ts
lpm bench -- --reporter=verboseDetection
If vitest is in dependencies or devDependencies, lpm bench runs vitest bench with whatever args you pass. Otherwise, if package.json has a bench script, lpm bench runs that script via the shell. The script fallback is only consulted when vitest is not declared. Use it for non-vitest benchmark frameworks (mitata, tinybench standalone, hyperfine).
Argument forwarding
Anything after the command (or after --) is forwarded to the runner:
lpm bench -- --reporter=json --outputFile=bench.jsonWorkspaces
lpm bench --all # every member
lpm bench --filter web # exact name
lpm bench --filter '@scope/*' # glob
lpm bench --filter-prod ...shared # prod graph closure
lpm bench --affected --base develop
lpm bench --filter './packages/*' --workspace-concurrency 2Detection runs per member. A workspace member with no installed bench runner and no scripts.bench becomes a per-member detection failure in the JSON envelope rather than aborting the whole run. --all is mutually exclusive with filters and --affected.
--filter and --filter-prod compose with --affected the same way as lpm test: the affected set is unioned with the filter result. --filter-prod uses the same grammar as --filter, but closure operators ignore devDependencies.
--workspace-concurrency <N> caps how many selected workspace members run at once within each topological level.
Forwarding runner flags with the same names
The workspace flags (--all, --filter, --filter-prod, --affected, --base, --fail-if-no-match, --workspace-concurrency) are claimed by LPM. To pass any of them through to the bench runner itself, put them after --:
lpm bench -- --filter pattern # forwards --filter to vitest bench
lpm bench --filter web -- --reporter=json # workspace + forwarded argsWatch with a workspace selector
Same gating as lpm test: watch is allowed when the selection resolves to exactly one member, rejected when it resolves to two or more (would start N watchers) or zero (nothing to watch).
lpm bench --filter web --watch # ✓ one member, one watcher
lpm bench --all --watch # ✗ rejected: N watchers
lpm bench --filter typo --watch # ✗ rejected: nothing to watchWhen the filter resolves to exactly one member, lpm bench runs against that member's directory as if you'd cd-ed in.
Flags
| Flag | Effect |
|---|---|
--all | Run in every workspace member |
--filter <expr> | Select workspace members by the filter grammar (repeatable) |
--filter-prod <expr> | Select workspace members with production-only dependency closures |
--affected | Run only in members affected by changes vs --base |
--base <REF> | Git base ref for --affected (default: main) |
--changed-files-ignore-pattern <glob> | Ignore matching git-diff paths for --affected / [git-ref] filters |
--test-pattern <glob> | Treat matching git-diff paths as test-only for --affected / [git-ref] fan-out decisions |
--fail-if-no-match | Exit non-zero if no member matches the filter set |
--workspace-concurrency <N> | Limit concurrent workspace members for --all, --filter, or --affected runs |
Anything after -- (or trailing) is forwarded to the bench runner.
Plus the global flags.
--json in workspace mode
Single-package mode (lpm bench) preserves the runner's stdout. Workspace mode emits a single LPM envelope on stdout; per-member stdout/stderr is captured and surfaced inside the envelope only on failure. See lpm lint for the exact envelope shape.
See also
lpm test— same auto-detection, for tests- Test & bench runners — how detection works