---
title: "CLI"
description: "Commands, options, file selection, exit codes, and output formats of the Stillwind CLI."
image: "https://stillwind.dev/og.png"
---

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

# CLI

`@stillwind/cli` sorts utilities, reports lint findings, applies automatic fixes,
and starts the language server. It reads the same `stillwind.config.ts` as the
build integration and the editor.

```sh
vp i -D @stillwind/cli
```

To run the CLI in CI, see [Checks in the editor and CI](/docs/guides/lint-adoption).

## Commands

| Command          | Action                                               |
| ---------------- | ---------------------------------------------------- |
| `stillwind fmt`  | Sorts utilities                                      |
| `stillwind lint` | Reports lint findings, and can apply automatic fixes |
| `stillwind lsp`  | Starts the language server                           |

`stillwind --help` lists the commands, and `stillwind <command> --help` lists the
options of a command. `stillwind --version` prints the package version. The short
forms of these options are `-h` and `-v`.

## stillwind fmt

```sh
vp exec stillwind fmt
vp exec stillwind fmt --check
```

`fmt` sorts utilities with the configured theme and
[`sort` options](/docs/configuration#sorting), and saves the changed files. It keeps
the source layout and the spelling of each token. Lint severity and suppression
comments do not affect `fmt`.

`fmt` does not change whitespace. To format whitespace too, see
[Formatters](/docs/formatters).

| Option    | Effect                                                  |
| --------- | ------------------------------------------------------- |
| `--check` | Reports the files that need sorting, and saves no files |

`fmt` also accepts the [shared options](#shared-options) and
[globs](#select-files).

Text output shows a status for each listed file and a summary.

## stillwind lint

```sh
vp exec stillwind lint
vp exec stillwind lint --fix
vp exec stillwind lint --max-warnings 0
```

`lint` reports findings and saves no files. Text output shows a `help:` message when
a finding has a suggested edit. Not every suggested edit is an automatic fix.

| Option               | Effect                                                                |
| -------------------- | --------------------------------------------------------------------- |
| `--fix`              | Applies the enabled automatic fixes, and saves the changed files      |
| `--quiet`            | Hides warnings, and keeps their count in the summary                  |
| `--max-warnings <n>` | Fails when the number of warnings exceeds `n`, a non-negative integer |

`lint` also accepts the [shared options](#shared-options) and
[globs](#select-files).

`--fix` respects suppression comments. It sorts utilities only when
[prefer-sorted-utilities](/docs/lints/prefer-sorted-utilities) is enabled. It
repeats until the files stop changing, with at most ten changing passes per file.
Findings and the exit code describe the files after the last pass.

`--max-warnings` counts distinct warnings in each project, including warnings that
`--quiet` hides. When hidden warnings exceed the limit, the CLI still prints the
reason for the failure.

## stillwind lsp

```sh
vp exec stillwind lsp --stdio
```

`lsp` starts the [language server](/docs/editors#other-editors) over stdin and
stdout. `--stdio` is required, and stdout carries only protocol messages. `lsp`
accepts `--config`, but no globs.

## Shared options

`fmt` and `lint` accept these options:

| Option                  | Effect                                              |
| ----------------------- | --------------------------------------------------- |
| `-c`, `--config <path>` | Uses this [configuration file](#select-files)       |
| `--format <format>`     | Selects the [output format](#output-formats)        |
| `--color <mode>`        | Controls [colors](#colors-and-links)                |
| `--hyperlinks <mode>`   | Controls [links to source files](#colors-and-links) |

An unknown option, a missing value, or an unsupported value returns exit code `2`.

## Select files

The CLI searches upward from the working directory for `stillwind.config.*`. In each
directory, it tries the extensions `ts`, `mts`, `cts`, `js`, `mjs`, `cjs`, and `json`
in that order. `--config` selects a file directly.

The CLI checks every file that `files` selects in each project, including files that
your application never imports. It can read other imported files for analysis, but
it does not change them.

Globs narrow this selection to some of these files. A glob is relative to each project
root, and it cannot add files outside `files`. You can pass several globs:

```sh
vp exec stillwind lint 'src/**/*.tsx' 'src/**/*.css'
```

A leading `./` is accepted. An absolute path selects that file when `files` includes
it. When nothing matches, the CLI returns exit code `2`.

## Saving files

`fmt` and `lint --fix` work out the changes for all selected files before they save
the first file. The CLI then saves only the files whose content changed, so
modification times of other files stay the same.

Outside edited ranges, UTF-8 BOMs, line endings, and trailing newlines stay intact.
Files must contain valid UTF-8.

When something fails:

- A file that cannot be read, analyzed, or rewritten stays unchanged. The CLI
  continues with the other files, even after a saving failure.
- A file that changed while the CLI worked is rejected and stays as it is.
- A configuration or CSS failure affects every file that needs that configuration
  or CSS.
- When projects overlap, every project that owns a file must produce the same final
  text.

The CLI reports all failures and all saved files, and it returns exit code `2`.

## Exit codes

| Code | Meaning                                                                                           |
| ---- | ------------------------------------------------------------------------------------------------- |
| `0`  | The command succeeded. `lint` may still report warnings when you set no `--max-warnings` limit    |
| `1`  | `fmt --check` found files to sort, `lint` found errors, or the warnings exceeded `--max-warnings` |
| `2`  | The options were invalid, no files matched, or configuration, analysis, or file access failed     |

Code `2` takes priority over code `1`.

## Output formats

| Format   | Output                                                                                |
| -------- | ------------------------------------------------------------------------------------- |
| `text`   | Messages for reading in a terminal; the default outside GitHub Actions                |
| `github` | Annotations that link findings to files; the default when `GITHUB_ACTIONS=true`       |
| `json`   | [One JSON object](#json-output) for scripts and AI agents                             |
| `files`  | One path per line for each file that `fmt` changes or needs to change; only for `fmt` |

Results use stdout, and execution failures in `text` and `files` formats use stderr.
Configuration logs use stderr in every format. Only `text` output contains colors
and links.

### Positions and paths

`text` and `github` output count lines and columns from one. Columns count UTF-16
code units.

`text` paths are relative to the working directory. `github` paths are relative to
`GITHUB_WORKSPACE`, or to the working directory when that variable is not set.
A path on another filesystem volume stays absolute.

### Source excerpts

A finding at a source range shows a source excerpt, related locations, notes, and
suggestions. Excerpts show tabs as four spaces, and they align wide characters and
emoji. A long range shows its first four lines.

A finding about a whole document has no position or excerpt. The CLI also omits the
excerpt when it cannot read the source, or when the source changed after the
analysis.

## Colors and links

`--color` and `--hyperlinks` accept `auto`, `always`, and `never`. `always` and
`never` ignore the environment.

With `--color auto`, the CLI uses colors in terminals and supported CI logs. It
respects `NO_COLOR`, `FORCE_COLOR`, and `TERM=dumb`.

`--hyperlinks` controls OSC 8 links, which open local source files from the
terminal. With `auto`, the CLI uses them in recognized terminals, including VS Code
and Windows Terminal, and not in CI or redirected output. Terminals without OSC 8
support can still detect the printed `path:line:column` locations.

## JSON output

`--format json` prints one object with the same fields in every case, including
failures:

```json
{
  "command": "lint",
  "config": "/project/stillwind.config.ts",
  "diagnostics": [],
  "failures": [],
  "changed": [],
  "summary": {
    "files": 1,
    "errors": 0,
    "warnings": 0,
    "failures": 0,
    "changed": 0,
    "suggestions": 0,
    "warningLimitExceeded": false
  },
  "exitCode": 0
}
```

| Field         | Value                                                                              |
| ------------- | ---------------------------------------------------------------------------------- |
| `command`     | `"fmt"` or `"lint"`, or `null` when the CLI failed before it selected a command    |
| `config`      | The configuration path, or `null` when the CLI failed before the analysis          |
| `diagnostics` | The findings; `--quiet` removes warnings from this list                            |
| `failures`    | The execution failures                                                             |
| `changed`     | The files that the command changed; with `--check`, the files that it would change |
| `summary`     | Counts for the fields above; `warnings` includes warnings that `--quiet` hides     |
| `exitCode`    | The [exit code](#exit-codes)                                                       |

Each diagnostic contains `project`, a zero-based project index, and `report`. The
report contains the message, its locations, notes, and suggested edits.

Each failure contains `message` and `details`, and it can contain `project` and
`file`. `details` lists the dependency problems that caused the failure.

File paths are absolute. Locations in reports use URIs and zero-based UTF-16
positions, and their ends are exclusive.

Source: https://stillwind.dev/docs/cli/index.mdx
