@block65/shared-config

v0.4.0

Published

Shared configuration defaults for Block65 projects

Readme

@block65/shared-config

Block65 configs for oxlint, oxfmt and fallow. Block65 internal.

Use

pnpm add -D @block65/shared-config oxlint oxfmt fallow

oxlint

// oxlint.config.ts
import { defineConfig } from "@block65/shared-config/oxlint";

export default defineConfig({
	groups: { vitest: "on", comments: "error", pilot: "warn" },
	categories: { perf: "error" },
	rules: { "no-console": "error" },
});

Block65's helper applies standard first. groups selects any of the groups below by name. "on" enables a group at the severities it was written with; "warn" or "error" flattens its enabled rules to that level, and "off" disables them. Options and deliberately disabled rules stay intact either way. Omitted groups keep the standard defaults, and optional groups stay off. Build output is ignored without listing it.

Everything else is an ordinary Oxlint config and passes through, categories included. Precedence is standard, selected groups, your extends, then your rules. File-specific overrides keep Oxlint's normal precedence; use your own matching override to change a group's file-specific exception.

Groups instead of standard:

// oxlint.config.ts
import { defineConfig } from "oxlint";
import { clarity, imports, modern, react } from "@block65/shared-config/oxlint";

export default defineConfig({ extends: [clarity, imports, modern, react] });

| Group | In standard | Purpose | | ---------------- | ------------- | ---------------------------------------------------------------------- | | clarity | yes | Readable control flow and export shape; fits any project | | unicorn | yes | Unicorn's recommended set, as far as oxlint ports it | | imports | yes | Imports that load the same way under every tool and runtime | | comments | yes | Comment prose policy; decline it where prose conventions already exist | | modern | yes | Platform APIs over their legacy equivalents; needs a current runtime | | http | yes | HTTP handler conventions; assumes the project is off Express 4 | | i18n | yes | react-intl message typing; decline it off react-intl | | baseline | no | Keeps browser-bound code to Baseline widely available APIs | | react | no | React 19 conventions | | vitest | no | Tests that cannot pass without running | | valibot | no | Valibot schema conventions | | vanillaExtract | no | vanilla-extract style authoring; additive, and needs no design system | | designSystem | no | A migration worklist toward the design-system layout primitives | | pedantic | no | Plugin rules the standard leaves off, for projects that want them all | | pilot | no | Candidates for the standard, taken early to judge them on real code |

baseline takes { baseline: "widely" | "newly", allow: [...] }.

Pilot

Enable with groups: { pilot: "warn" }, or import pilot and include it in extends. Its rules are under evaluation: they run at warn so they cost nothing, and a rule that earns its place moves to the standard while one that does not is dropped.

Warnings use ordinary Oxlint fix behavior. --fix applies available safe fixes; suggestions and dangerous fixes require their respective flags.

Types and additional plugins

A misspelt rule name fails typecheck, and native Oxlint rules keep their option types. Additional plugins can extend RuleRegistry through declaration merging:

import { defineConfig } from "@block65/shared-config/oxlint";

declare module "@block65/shared-config/oxlint" {
	interface RuleRegistry {
		"example/check"?: "off" | "warn" | "error";
	}
}

export default defineConfig({
	jsPlugins: ["eslint-plugin-example"],
	rules: { "example/check": "warn" },
});

Augmentation supplies types; register the plugin with jsPlugins as usual. Import defineConfig from oxlint for its unrestricted rule map and compose our exported groups directly when desired.

Output and warning thresholds

Use default output locally, --format=agent for agent commands (just lint-agent in this repository), and --format=github in GitHub Actions. Output format belongs to the command, not the shared configuration.

options: { maxWarnings: 0 } makes any warning fail the command, including pilot warnings. It does not limit diagnostic output. The helper leaves that threshold to each project; it does not hide warnings or change fix behavior.

Turn a rule off after extends:

export default defineConfig({
	extends: [standard],
	rules: { "block65/max-comment-lines": "off" },
});

Type-aware linting is on. It needs the Block65 builds of oxlint and oxlint-tsgolint (Linux only); a project opts out with options: { typeAware: false }:

// package.json
"devDependencies": {
	"oxlint": "^1.82.0",
	"oxlint-tsgolint": "^7.0.2001"
}
# pnpm-workspace.yaml
overrides:
  oxlint: npm:@block65/oxlint@>=1.82.0
  oxlint-tsgolint: npm:@block65/oxlint-tsgolint@>=7.0.2001

Keep the npm: prefix. Without it pnpm reads the value as a path.

oxfmt

// oxfmt.config.ts
import { defineConfig } from "@block65/shared-config/oxfmt";

export default defineConfig({ printWidth: 100 });

fallow

// .fallowrc.json
{
	"extends": ["npm:@block65/shared-config/fallow.jsonc"]
}

The config lives at npm:@block65/shared-config/fallow.jsonc. A config extending npm:@block65/shared-config/lib/fallow/fallow.jsonc, the path 0.3.2 exported, still resolves in 0.4.0 and reads the same rules. That path goes in the next minor, and fallow reports nothing when an extends path is missing, so move it while it still works.

Exports

| Subpath | Provides | | ---------------- | -------------------------------------------------------- | | ./oxlint | defineConfig, the groups, standard, standardGroups | | ./oxfmt | defineConfig | | ./fallow.jsonc | The fallow base config |