LPM CLI

lpm exec and source files

Run installed project tools or JavaScript and TypeScript files with the project's runtime and environment.

Run a project-local executable with lpm exec. Run a JavaScript or TypeScript file directly with lpm <FILE>.

lpm exec [OPTIONS] <COMMAND> [ARGS]...
lpm <FILE> [--env <ENV>] [--no-env-check] [--watch] [--plain-node] [-- <ARGS>...]

Quickstart

lpm exec eslint --fix src
lpm exec vitest run
lpm scripts/seed.ts
lpm scripts/report.js -- --format json
ModeUse it for
lpm exec <COMMAND>An executable installed in the project or workspace
lpm <FILE>A JavaScript or TypeScript entrypoint
lpm <FILE> --watchRepeat a finite file after changes to that file

Use lpm install to install project dependencies first. For a package tool outside the project, use lpm dlx.

Configure lpm.json

Runtime and environment configuration apply to both modes.

lpm.json
{
  "runtime": {
    "node": "22.18.0"
  },
  "envSchema": {
    "vars": {
      "DATABASE_URL": {
        "format": "url",
        "required": true,
        "secret": true
      }
    }
  }
}
lpm exec --env staging prisma -- migrate deploy
lpm scripts/seed.ts --env staging
lpm scripts/seed.ts --no-env-check

LPM CLI prepares a missing managed runtime automatically. --env selects the environment for this invocation. --no-env-check skips value checks and schema defaults. Declaration errors in lpm.json always stop the command.

Direct execution does not use tasks.<name>.command, task dependencies, task caching, or package pre/post hooks. For those workflows, define a task and use lpm run. See the configuration reference for runtime selectors and named environments.

Run local executables

lpm exec tsc -- --noEmit
lpm exec --env staging prisma -- migrate deploy
lpm exec eslint -- --format json src

LPM CLI finds the executable in project or workspace node_modules/.bin directories. It does not fetch the package or fall back to an arbitrary executable on the system PATH. The tool runs from the current directory with the project's executable directories on PATH. Unlike lpm run and lpm dev, lpm exec does not switch to the nearest directory with a package.json or an lpm.json. The same applies to source files and shorthand names.

An unknown top-level name can also select a local executable:

lpm eslint --fix src

Built-in commands, source-file paths, package scripts, and configured tasks take precedence over this shorthand. Use lpm exec to select an installed tool directly.

Run source files

lpm scripts/seed.ts
lpm scripts/view.tsx
lpm scripts/report.mjs -- --format json

The file runs from the invocation directory. Its path does not change the working directory or select a different project's configuration.

File extensionRuntime
.js, .mjs, .cjsNode.js
.ts, .mts, .ctsThe TypeScript runtime, Node's type stripping, or a project-local tsx, depending on Node compatibility
.tsxThe TypeScript runtime or a project-local tsx

The TypeScript runtime requires Node 22.18+, 23.6+, or 24+. Node 22.6–22.17 and 23.0–23.5 can use experimental type stripping for files without JSX. If these paths cannot run the file, LPM CLI tries an installed project-local tsx. It does not download tsx during execution.

Runtime selectors follow lpm use and the supported version files. The selected Node version must satisfy applicable engines.node requirements under the project's engine policy. Custom Node wrappers must answer --version within two seconds and return no more than 4 KiB of output.

TypeScript and JSX

The TypeScript runtime transforms the source, provides source maps, and caches transformations. It reads the invocation project's tsconfig.json, including JSON comments and trailing commas.

baseUrl and paths control project-local aliases. Exact aliases take precedence over wildcard aliases. Among matching wildcard aliases, the longest prefix wins. A target array supplies fallback paths for the selected alias. Each target supports at most one *.

tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@app/*": ["src/*"]
    }
  }
}
scripts/report.ts
import { report } from '@app/report';

report();

TSX uses the React automatic JSX runtime by default. jsx, jsxFactory, jsxFragmentFactory, and jsxImportSource can select the supported JSX behavior. The required JSX runtime package must already be available to Node.

Child Node processes from the TypeScript runtime receive the same controlled loader configuration. Inherited NODE_OPTIONS cannot replace that loader.

Plain Node

lpm scripts/seed.ts --plain-node

--plain-node disables the TypeScript loader and its child-process propagation. --no-augment is an alias. Node's own TypeScript support determines which syntax can run. Plain Node mode rejects .tsx.

Environment selection

lpm exec --env staging prisma -- migrate status
lpm scripts/report.ts --env staging

Without a selected mode, LPM CLI reads .env and .env.local. A selected mode also loads .env.<MODE> and .env.<MODE>.local, or the configured named-environment chain.

Later files override earlier files. Safe inherited values take precedence over file values. Project secrets from lpm env override file values. The schema checks effective values and supplies configured defaults.

LPM CLI strips inherited credentials and protected runtime variables before execution. Explicit project secrets remain available. Project files cannot inject protected runtime hooks such as NODE_OPTIONS.

Watch a finite file

lpm scripts/report.ts --watch

Watch mode runs the file, then waits for a change to that entrypoint. It does not watch imported modules as a dependency graph. Each run finishes before another starts. A change during execution schedules a later run. Watch mode follows entrypoint symlinks and updates its scope when their targets change. On macOS, periodic metadata checks recover missed notifications for the entrypoint and its symlink targets.

The runtime selection stays fixed for the watch session. Restart the session after runtime or launch-option changes. For framework servers, use lpm dev. For configured task inputs, use lpm run --watch.

Forward arguments and use CI

lpm exec --env staging tool -- --env production --json
lpm scripts/report.ts -- --env production --json

Put LPM CLI options before --. Put all child arguments after it. This separates flags that both programs recognize, such as --env.

The command preserves the child's exit status during normal execution. Tools and scripts control their own output and prompts. On Unix, SIGINT and SIGTERM stop active execution and end watch mode with exit codes 130 and 143. Commands receive the signal before LPM CLI stops unresponsive descendants. For CI, pass the tool's non-interactive options after --. A child's JSON flag controls its output. Direct execution does not wrap successful output in a task-result object.

Troubleshooting

ProblemRecovery
Local executable is missingRun lpm install, then check the package's executable name
Node does not satisfy the projectSelect a compatible version with lpm use
TypeScript runtime is unavailableSelect a supported Node version or install and pin tsx in the project
JSX runtime import is missingInstall the runtime package selected by jsxImportSource
A child option affects LPM CLIPut the child option after --
Watch does not rerun after an import changesUse configured task inputs with lpm run

Flags

FlagModesEffect
--env <ENV>BothSelect an environment for this invocation
--no-env-checkBothSkip value checks and schema defaults
--watchSource fileRepeat after entrypoint changes
--plain-nodeSource fileDisable the TypeScript runtime and child-loader propagation
--no-augmentSource fileAlias for --plain-node

See also

  • lpm run — scripts, task dependencies, and caching
  • lpm dev — development servers and services
  • lpm dlx — tools outside the project
  • lpm use — runtime selection
  • lpm env — project secrets