> [Agent navigation index](/llms.txt)

# Linting and formatting

Brix manages Oxfmt, Oxlint, type-aware linting, and Brix-specific rules as one versioned project
policy. Use `brix format` to write formatting changes and `brix check` to verify formatting, lint,
types, and project structure. Do not install or invoke the underlying tools separately.

## Keep native configuration files

A standalone project keeps `oxfmt.config.mts` and `oxlint.config.mts` at its root. They call helpers
from the exact installed Brix version, so command-line checks and the official Oxc editor extension
use the same baseline:

`oxfmt.config.mts`

```ts
import { defineBrixOxfmtConfig } from "brix/config";

export default defineBrixOxfmtConfig();

```

`oxlint.config.mts`

```ts
import { defineBrixOxlintConfig } from "brix/config";

export default defineBrixOxlintConfig();

```

Keep these executable native configs. Do not move formatting or lint options into
`vite.config.ts`, replace the helpers with copied defaults, or add legacy `.oxfmtrc.json` and
`.oxlintrc.json` files. Brix maintains the project-local Oxc declarations needed by editors; select
Oxc as the formatter in personal editor settings rather than committing editor preferences for the
team.

`defineBrixOxfmtConfig` accepts native Oxfmt options, appends project ignores after the managed
`**/dist/**` and `**/.brix/**` ignores, and preserves project overrides. `defineBrixOxlintConfig`
accepts native Oxlint categories and options; project `rules` merge over managed rules, `jsPlugins`
append without removing Brix's plugin, and project ignores and overrides follow the managed ones.

## Understand the managed lint baseline

The baseline enforces ordinary correctness and type-aware checks plus application architecture. It
rejects direct imports of framework-owned dependencies, CommonJS `require()`, Brix test entry points
in production modules, and parent-relative imports from `src/features/**`. Tests may import from
`brix/test`; application code should use the supported `brix/*` facades. `brix doctor` additionally
checks imports, exports, statically known dynamic imports, and `require()` calls, so lint is not a
substitute for diagnosis.

Five Brix rules are errors by default:

- `brix/no-unknown-type-aliases` keeps genuinely untrusted values visibly `unknown` until validated.
- `brix/no-widen-then-assert` prevents erasing a known immutable value's type and asserting it back.
- `brix/no-reflect-get` prefers typed property access over `Reflect.get`.
- `brix/no-reflect-apply` prefers typed calls over `Reflect.apply`.
- `brix/no-module-mocking` prevents Vitest or Jest module replacement, including through
  `brix/test`.

Runtime validation, `unknown` boundary parameters, `typeof`, `vi.fn`, and `vi.spyOn` remain valid.
For tests, exercise routes through the [route harness](/docs/testing-routes), mock HTTP consumed
by clients with MSW, or use an existing dependency-injection seam instead of replacing a module.

Optional project-policy rules use the same `brix/` prefix: `no-chained-type-assertions`,
`no-conditional-empty-object-spread`, `no-known-value-widening`, `no-object-parameters`,
`no-runtime-typeof`, `no-shape-in-symbol-names`, `no-unknown-parameters`, `no-unknown-returns`,
`no-unsafe-dictionary-type`, and `require-safety-comment-for-type-assertion`. They are not managed
defaults; enable only rules that express a deliberate team policy.

## Configure shared policy and scoped exceptions

Pass native options to the helper. Prefer `overrides` when policy applies only to particular code:

`oxlint.config.mts`

```ts
import { defineBrixOxlintConfig } from "brix/config";

export default defineBrixOxlintConfig({
  rules: { "no-console": "error" },
  overrides: [
    {
      files: ["src/domain/**/*.ts"],
      rules: { "brix/no-unsafe-dictionary-type": "error" },
    },
    {
      files: ["scripts/**/*.ts"],
      rules: { "no-console": "off" },
    },
  ],
});

```

Globs are relative to the config file. A genuine one-statement exception should be narrower than an
override and explain the invariant it preserves:

```ts
// eslint-disable-next-line brix/no-reflect-get -- Preserve the receiver supplied to this proxy accessor.
return Reflect.get(target, key, receiver);

```

Keep regression coverage for such exceptions. Avoid blanket file exclusions and comments that only
claim an assertion or mock is safe. A deliberate project-wide rule change is supported, but turning
off a managed rule globally should be rarer than a local, reasoned exception.

Oxfmt options and ignore patterns follow the same root-relative ownership model:

`oxfmt.config.mts`

```ts
import { defineBrixOxfmtConfig } from "brix/config";

export default defineBrixOxfmtConfig({
  singleQuote: true,
  ignorePatterns: ["generated/**"],
});

```

Use the exact option names supported by the Brix-pinned Oxfmt version. Keep generated output ignored
rather than formatting it by hand.

## Configure a workspace at the root

A workspace root owns `.node-version`, `oxfmt.config.mts`, `oxlint.config.mts`, local Oxc tools,
managed skills, and Git hooks. Members inherit them and should not contain generated copies. Put
shared decisions in the root configs and use workspace-relative globs for member-specific policy:

`oxlint.config.mts`

```ts
import { defineBrixOxlintConfig } from "brix/config";

export default defineBrixOxlintConfig({
  overrides: [
    {
      files: ["apps/admin/src/**/*.ts", "apps/admin/src/**/*.tsx"],
      rules: { "no-console": "error" },
    },
    {
      files: ["packages/generated-contracts/src/**/*.ts"],
      rules: { "brix/no-unknown-type-aliases": "off" },
    },
  ],
});

```

Open the workspace root in the editor so it discovers the shared configs and binaries. Add a member
config only when a tool genuinely needs a separate boundary. A local config replaces ancestor
discovery; it does not automatically extend the root. Keep the Brix helper and explicitly compose
any root options the member must retain. Member `brix init` and workspace upgrades remove only
unchanged generated member configs and matching Node pins; customized files remain untouched.

Git hook policy likewise belongs only at the Git root under `.brix-hooks/`. `brix hooks enable` and
`brix hooks disable` control dispatch for the current clone. The standard pre-commit hook runs
`brix staged` against the exact index without rewriting unstaged work.

## Run and repair checks

```sh
brix format
brix check
brix doctor
brix hooks status
brix staged

```

Format first, review the diff, and stage the intended result. `brix check` never applies formatter or
linter fixes. In a workspace, root commands cover all members; focused commands such as
`brix check#checkout-bff` select one project while still preparing its shared libraries. Hooks are
early feedback only—`brix verify` and CI remain authoritative.

Continue with [project structure](/docs/project-structure), [testing](/docs/testing), and
[workspaces](/docs/workspaces).
