---
title: "How to check and build Hem from the command line"
description: "Gate CI on hem check, emit siblings without Vite, keep them fresh while you work, and format in a pre-commit hook."
image: "https://hem.run/social/hem.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://hem.run/llms.txt
> Use this file to discover all available pages before exploring further.

# How to check and build Hem from the command line

The CLI runs the same compile and emit engine as the Vite plugin, so a project that builds under Vite produces identical output here. Use it for CI, for non-Vite builds, and for anything that has to happen before a dev server starts.

## Gate CI on type errors

```sh
hem check
```

With no file arguments this discovers every `.hem` root covered by the nearest `tsconfig.json`, compiles the project, and reports diagnostics without writing anything. A non-zero exit fails the job.

Run it alongside your existing TypeScript check rather than in place of it. `hem check` covers the Hem sources and the boundary where they meet TypeScript; your `tsc` run still covers everything else.

To check only part of a monorepo, name files or directories. Explicit inputs may span more than one nearest-tsconfig project.

## Emit siblings in a build pipeline

```sh
hem build
```

This writes the `.ts` and `.tsx` siblings, refuses collisions with handwritten files, removes stale generated output whose source has moved or disappeared, and refreshes `.hem/generated-files.json`.

Run it before any step that consumes the emitted TypeScript: a bundler that is not Vite, `tsc`, a declaration build, or a publish step.

## Keep siblings fresh while you work

```sh
hem build --watch
```

Watch mode does one full build, then rebuilds when Hem sources, handwritten TypeScript or JavaScript sidecars, package manifests, or the tsconfig change. It also watches inherited configs, including those outside the project directory. Sidecar edits refresh Hem diagnostics without a restart; generated sibling writes and unrelated `node_modules` changes are ignored. The command keeps running until you interrupt it.

Use this when your dev server is not Vite. If you already run the Vite plugin, it does the same work inside the dev server and you do not need this.

To start discovery somewhere other than the current directory, pass the directory as the first positional argument.

## Enforce formatting

```sh
hem fmt --check
```

Writes nothing and exits non-zero when a file needs formatting or fails to parse. This is the CI form.

Drop `--check` to rewrite changed files and print their paths. That is the pre-commit form.

For editor integrations and other tools that pipe source through a formatter, `hem fmt --stdin` reads stdin and writes the formatted result to stdout. It cannot be combined with `--check` or with file arguments.

The formatter has no width flag. The CLI and the language server both use the same default, so formatting never depends on who ran it.

## Look up a diagnostic you hit

```sh
hem explain HEM2005
```

Prints that code's title and explanation. `hem explain --all` prints the whole catalog, which is also published as the [diagnostics reference](/reference/diagnostics).

## A minimal CI job

```sh
hem fmt --check
hem check
hem build
```

Checking formatting first provides the fastest feedback with the lowest computational cost. Checking before building means a broken project never writes siblings that a later step might pick up.

For the full option list, see the [CLI reference](/reference/cli).

Source: https://hem.run/guides/use-the-cli/index.mdx
