# lpm <file> and lpm exec (/docs/dev/exec)



```bash
lpm <file> [--env <mode>] [--watch] [--plain-node] [args...]
lpm exec [--env <mode>] [--no-env-check] <bin> [args...]
```

LPM CLI has two execution lanes:

* `lpm <file>` runs a JavaScript or TypeScript source file directly.
* `lpm exec <bin>` runs a project-local binary from `node_modules/.bin`, matching npm/pnpm muscle memory.

`lpm exec` does not run source files. Use `lpm scripts/seed.ts`, not `lpm exec scripts/seed.ts`.

There is also a shorthand: `lpm <bin>` tries a project-local binary only after the name does not match a built-in command, a source-file/path invocation, a `package.json` script, or an `lpm.json` task. Use `lpm exec <bin>` when you want the local-bin lane explicitly.

## Source Files [#source-files]

```bash
lpm scripts/seed.ts
lpm scripts/view.tsx
lpm scripts/migrate.js
lpm scripts/seed.ts --env staging
lpm scripts/seed.ts --watch
lpm scripts/seed.ts --plain-node
lpm scripts/seed.ts -- --env=staging
```

Runs a single JavaScript or TypeScript file without adding a `scripts` entry to `package.json`. `.js` / `.mjs` / `.cjs` go through plain `node`; `.ts` / `.tsx` / `.mts` / `.cts` use LPM CLI's OXC-backed TypeScript runtime on supported Node versions. If no safe runtime is available, LPM CLI fails with a fix-it message instead of downloading `tsx` through `npx`.

Human progress goes to stderr and names the selected runtime before the file starts:

```bash
› Executing scripts/seed.ts with Node.js v22.18.0 + LPM CLI TS runtime
✓ Done · exited 0 in 412ms
```

## Local Binaries [#local-binaries]

```bash
lpm exec eslint --fix src
lpm exec vitest run
lpm exec --env staging prisma migrate deploy
lpm jest --watch  # shorthand when no script/task named "jest" exists
```

`lpm exec <bin>` resolves `<bin>` only from project `node_modules/.bin` directories, walking upward through the workspace. It loads project env, injects the same local-bin PATH used by `lpm run`, strips inherited runtime-hook env like `NODE_OPTIONS` and `LD_PRELOAD`, then spawns the binary directly without a shell.

It does not fetch packages and does not fall back to system PATH. The bare shorthand uses the same local-bin lookup, but only after scripts/tasks miss. Use [`lpm dlx`](/docs/dev/dlx) when you want to run a package binary without adding it to the project.

## Runtime Selection [#runtime-selection]

| Extension             | Runtime                                                                                                                                                |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `.js`, `.mjs`, `.cjs` | `node` - direct spawn, no shell, no LPM CLI TS preload                                                                                                 |
| `.ts`, `.mts`, `.cts` | Node 22.18+ / 23.6+ / 24+ with the LPM CLI TS runtime -> Node 22.6-22.17 / 23.0-23.5 with `--experimental-strip-types` -> project-local `tsx`          |
| `.tsx`                | Node 22.18+ / 23.6+ / 24+ with the LPM CLI TS runtime's OXC JSX transform -> project-local `tsx` when the Node version cannot load the LPM CLI runtime |

The effective PATH includes project `node_modules/.bin`, any matching managed Node that LPM CLI resolved for the project, and then your existing system PATH.

LPM CLI source-file execution does not fall back to `npx tsx`. That fallback can download and execute npm code outside LPM CLI's install-policy/security model. If TypeScript execution cannot use the LPM CLI runtime, Node's built-in strip-types path, or a project-local `tsx`, use `lpm use node@22.18+` or add and pin `tsx` in the project explicitly.

The LPM CLI TS runtime is LPM CLI-owned: it writes LPM CLI's bundled loader into the LPM CLI cache, calls LPM CLI's Rust/OXC transformer without fetching npm packages, executes `.ts`, `.tsx`, `.mts`, and `.cts`, reads `tsconfig.json` `baseUrl` / `paths` mappings for project-local imports, emits source maps, and caches transforms by source content, runtime version, Node version, platform, architecture, file path, tsconfig fingerprint, and transform options. Cache entries are validated before reuse.

TSX uses OXC's JSX transform. By default it emits the React automatic JSX runtime (`react/jsx-runtime`). `jsx: "react"` or explicit `jsxFactory` / `jsxFragmentFactory` selects the classic runtime, `jsx: "react-jsxdev"` enables development JSX output, and `jsxImportSource` changes the automatic-runtime import source. JSX runtime packages still need to be present in the project or otherwise resolvable by Node; LPM CLI does not download them during execution.

## Plain Node Mode [#plain-node-mode]

`--plain-node` disables the LPM CLI TS runtime preload and child Node propagation for `lpm <file>`. `--no-augment` is an alias.

Use it when you need to check what Node itself can run without LPM CLI augmentation:

```bash
lpm scripts/seed.ts --plain-node
```

In plain mode, `.ts` / `.mts` / `.cts` use Node's built-in TypeScript support when available. `.tsx` is refused because plain Node does not support TSX.

## Child Node Processes [#child-node-processes]

When a TypeScript entrypoint runs with the LPM CLI TS runtime, child processes spawned as `node child.ts` inherit a controlled LPM CLI `NODE_OPTIONS` preload. That lets TypeScript child scripts use the same loader and `tsconfig.json` path mappings without invoking `npx` or a project-local wrapper.

Inherited parent `NODE_OPTIONS` is stripped before execution, so a developer shell or CI environment cannot silently replace the LPM CLI loader. `--plain-node` / `--no-augment` disables this child propagation.

## Environment Loading [#environment-loading]

Both execution lanes load the project's env files and env secrets before spawn. Pass `--env <mode>` to load the same mode-specific files as [`lpm run`](/docs/dev/run), such as `.env.staging` and `.env.staging.local`.

`--no-env-check` skips env-schema validation only; it does not disable env loading.

Before spawning, LPM CLI strips inherited runtime-hook env like `NODE_OPTIONS`, `LD_PRELOAD`, `LD_AUDIT`, `BASH_ENV`, and `DYLD_INSERT_LIBRARIES`. Project env files, env secrets, and env-schema defaults are filtered for the same runtime-hook names before they are applied, so those keys are ignored when they come from project env. LPM CLI-controlled runtime env is added after that filtering.

## Watch Mode [#watch-mode]

`--watch` re-runs the same source-file execution plan when the target file changes:

```bash
lpm scripts/seed.ts --watch
```

It watches the requested file only; dependency-graph watching is not part of direct source-file execution yet.

## Argument Forwarding [#argument-forwarding]

For source files, put LPM CLI flags after the file and use `--` when the script arg starts with `-`:

```bash
lpm scripts/seed.ts --env staging -- --verbose --env=prod
```

For local binaries, flags for LPM CLI belong before the binary name. Everything after the binary name is passed to the binary:

```bash
lpm exec --env staging eslint --fix src/index.ts
```

## Flags [#flags]

| Lane         | Flag             | Effect                                                            |
| ------------ | ---------------- | ----------------------------------------------------------------- |
| Both         | `--env <mode>`   | Load env files and secrets for the selected mode                  |
| Both         | `--no-env-check` | Skip env-var schema validation before execution                   |
| Source files | `--watch`        | Re-run the same plan when the target file changes                 |
| Source files | `--plain-node`   | Disable the LPM CLI TS runtime preload and child Node propagation |
| Source files | `--no-augment`   | Alias for `--plain-node`                                          |

Plus the [global flags](/docs/commands#global-flags).

## See Also [#see-also]

* [`lpm run`](/docs/dev/run) - run named scripts from `package.json`
* [`lpm dlx`](/docs/dev/dlx) - run a binary from a registry package without installing it
* [`lpm dev`](/docs/dev/dev) - full dev server with HTTPS, tunnel, services
