# lpm check (/docs/dev/check)



```bash
lpm check [--engine tsc|tsgo] [-- args...]
```

Runs `tsc --noEmit` against the project by default. Pass `--engine tsgo` to run `tsgo --noEmit` instead. LPM CLI forwards any trailing arguments to the selected engine.

`lpm check` now has two engine paths:

* `tsc` stays project-local. LPM CLI resolves it from `node_modules/.bin` via the same PATH-injection it uses for `lpm run`, then falls back to the system `PATH`.
* `tsgo` is a managed engine. LPM CLI downloads the pinned platform package on first use, verifies the tarball integrity, preserves the full extracted layout, and caches it under `~/.lpm/engines/tsgo/<version>/<platform>/`.

## Examples [#examples]

```bash
lpm check                          # type-check the whole project
lpm check --engine tsgo            # opt into tsgo for this run
lpm check -- --pretty              # forward tsc flags
lpm check -- -p tsconfig.test.json # type-check a different tsconfig
lpm check --all                    # workspace: every member
lpm check --filter web             # workspace: one member
lpm check --filter './apps/*'      # workspace: path glob
lpm check --affected               # workspace: only affected members
```

## Engine installation [#engine-installation]

```bash
lpm install -D typescript
```

Use `typescript` for the default `tsc` engine.

For `tsc`, the project-local install is the right answer: editor IntelliSense (`tsserver` from `node_modules/typescript`) and CI run the same version, and your `tsconfig.json` references resolve against the same `@types/*` packages.

For `tsgo`, no project dependency is required. The first `lpm check --engine tsgo` run installs the managed engine into `~/.lpm/engines`, and later runs reuse that verified cache.

### Preflight [#preflight]

Before spawning the selected engine, `lpm check` verifies setup and surfaces specific errors:

| Condition                                                                                | Error                                                                                  |
| ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `tsconfig.json` is missing                                                               | `no tsconfig.json found in <dir>. Add one (or pass -p <path>) to use a different one.` |
| `typescript` declared in `package.json` but not installed and `--engine tsc` is selected | `typescript declared in package.json but not installed. Run: lpm install`              |
| `typescript` not declared and no `tsc` on `PATH` while `--engine tsc` is selected        | `typescript not installed. Run: lpm install -D typescript`                             |
| Managed `tsgo` install or reuse fails                                                    | `engine error: ...` or a network/HTTP error naming the managed engine download         |

The preflight is **argument-aware**: when you pass `-p <path>`, `--project <path>`, or a positional file argument, the tsconfig check is skipped and the selected engine decides — `lpm check -- -p tsconfig.test.json` and `lpm check src/foo.ts` both work without a root `tsconfig.json`.

### `lpm doctor` reports the same signal [#lpm-doctor-reports-the-same-signal]

`lpm doctor` emits one TypeScript check per `tsconfig.json` in the workspace, with stable codes:

| Code                              | Severity | Meaning                                                                                                                                                            |
| --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `typescript_healthy`              | pass     | `tsc` resolves through the project-local `node_modules/.bin` chain. Editor + CI parity holds.                                                                      |
| `typescript_missing_for_tsconfig` | warn     | `tsc` runs only via the system `PATH`. The project lacks a local install — editor and CI may use a different version. Run `lpm install -D typescript` to converge. |
| `typescript_unavailable`          | fail     | `tsc` cannot run at all. Run `lpm install` if `typescript` is already declared, or `lpm install -D typescript` to add it.                                          |

Doctor performs only the cheap reachability + dep-declaration check; the type-check itself belongs to `lpm check`.

## Workspaces [#workspaces]

```bash
lpm check --all                              # every member
lpm check --filter web                       # exact name
lpm check --filter '@scope/*'                # glob
lpm check --filter './apps/*'                # path glob
lpm check --filter-prod ...shared            # prod graph closure
lpm check --affected --base develop          # affected vs a non-main branch
lpm check --filter web --fail-if-no-match    # exit non-zero on typo'd filter
```

Members run in topological levels, with packages inside each level executing in parallel up to the available CPU count.

Filter grammar is documented in [Workspaces](/docs/packages/workspaces#filter-grammar).

`--all` and `--affected` are mutually exclusive; filters compose with `--affected` (the affected set is unioned with the filter result). `--filter-prod` uses the same grammar as `--filter`, but closure operators ignore `devDependencies`.

## Flags [#flags]

| Flag                                    | Effect                                                                                                                 |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `--engine <name>`                       | Select the type-check engine for this run: `tsc` or `tsgo` (default: `tsc`)                                            |
| `--all`                                 | Run in every workspace member                                                                                          |
| `--filter <expr>`                       | Select workspace members by the [filter grammar](/docs/packages/workspaces#filter-grammar) (repeatable; entries union) |
| `--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 (recommended in CI)                                                  |

Anything after `--` (or trailing) is forwarded to the selected engine. `--noEmit` is always passed.

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

## `--json` in workspace mode [#--json-in-workspace-mode]

Single-package mode (`lpm check`) preserves the selected engine's stdout — LPM CLI does not wrap it. Workspace mode emits a single LPM CLI envelope on stdout; per-member stdout/stderr is captured and surfaced inside the envelope only on failure. See [`lpm lint`](/docs/dev/lint#json-in-workspace-mode) for the exact envelope shape.

## See also [#see-also]

* [`lpm lint`](/docs/dev/lint) — Oxlint
* [`lpm fmt`](/docs/dev/fmt) — Biome formatter
* [`lpm plugin`](/docs/dev/plugin) — for tools that ARE lazy-downloaded
