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:
import { defineBrixOxfmtConfig } from "brix/config";
export default defineBrixOxfmtConfig();
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-aliaseskeeps genuinely untrusted values visiblyunknownuntil validated.brix/no-widen-then-assertprevents erasing a known immutable value's type and asserting it back.brix/no-reflect-getprefers typed property access overReflect.get.brix/no-reflect-applyprefers typed calls overReflect.apply.brix/no-module-mockingprevents Vitest or Jest module replacement, including throughbrix/test.
Runtime validation, unknown boundary parameters, typeof, vi.fn, and vi.spyOn remain valid.
For tests, exercise routes through the route harness, 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:
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:
// 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:
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:
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
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, testing, and workspaces.