Skip to content

日本語

@yuu1111/biome-config ​

Shared Biome configuration.

Install ​

bash
bun add -D @yuu1111/biome-config

Usage ​

Extend biome and add the rule layers the project needs:

json
{
  "$schema": "https://biomejs.dev/schemas/2.5.13/schema.json",
  "extends": [
    "@yuu1111/biome-config/biome",
    "@yuu1111/biome-config/plugins/core"
  ]
}

Presets ​

PresetUse case
biomeFormatter, lint rules, and VCS integration
reactbiome plus CSS and Tailwind
plugins/coreSeven general-purpose rule plugins
plugins/networkTwo fetch rule plugins
plugins/discordOne Discord rule plugin

biome and react are complete configurations. The plugins/* presets only add rules, so list them after biome or react; their rules are off until the preset is extended.

biome ​

SettingValue
vcsgit, useIgnoreFile
formatterenabled, indentStyle: "tab"
javascript.formatter.quoteStyledouble
json.formatter.expandalways
assist.source.organizeImportson
linter.rules.recommendedtrue
nursery.noFloatingPromiseswarn
nursery.useImportsFirsterror
performance.noBarrelFile, performance.noReExportAllerror
complexity.noExcessiveCognitiveComplexitywarn
style.noExportedImportserror
style.noNestedTernary, style.useErrorCausewarn
suspicious.noEmptyBlockStatementswarn
json
{
  "$schema": "https://biomejs.dev/schemas/2.5.13/schema.json",
  "extends": ["@yuu1111/biome-config/biome"]
}

react ​

Adds the CSS formatter and linter, with the Tailwind directives enabled.

json
{
  "$schema": "https://biomejs.dev/schemas/2.5.13/schema.json",
  "extends": ["@yuu1111/biome-config/react"]
}

plugins/core ​

RuleSeverityDefaultDetects
no-reexportswarnfalseAn export that only forwards an existing binding, such as export type Alias = Imported or export default imported; export { imported } is caught by the base style.noExportedImports and the export ... from forms by the base barrel-file rules
no-incomplete-implementationerror, warnfalseA placeholder throw, as an error; a catch block that only logs, or a rejected promise or caught error replaced with null, [], or {}, as a warning
no-type-safety-bypasserror, warnfalseas unknown as T, as an error; a Record<string, unknown> assertion, an unchecked JSON assertion, static Reflect.get, or a receiver-free Reflect.apply, as a warning
no-unsafe-errno-assertionwarnfalseReading code through a NodeJS.ErrnoException assertion without validating the caught value
no-meaningless-testerror, warnfalseA toBe, toEqual, or toStrictEqual comparison of an identifier or literal with itself, as an error; an empty test or it callback, as a warning
no-useless-abstractionwarnfalseA named single-argument arrow function that only passes the same argument to another function, including the async form
no-ternary-statementwarnfalseA ternary operator used as a standalone statement, such as flag ? enable() : disable()

The rules stay narrow. A wrapper that validates, transforms, logs, caches, starts a transaction, or performs another operation is not reported as a pass-through wrapper. A test with setup or assertions is not treated as empty.

ts
throw new Error("Not implemented")
request.catch(() => null)

const user = value as unknown as User
const parsed = JSON.parse(text) as User
const code = (error as NodeJS.ErrnoException).code

test("placeholder", () => {})
expect(result).toEqual(result)

const loadUser = (id) => fetchUser(id)

flag ? enable() : disable()

Suppress an intentional exception with a reason:

ts
// biome-ignore lint/plugin: An optional cache miss is an expected fallback
cacheRequest.catch(() => null)

plugins/network ​

RuleSeverityDefaultDetects
require-fetch-abort-signalwarnfalseA fetch call that omits the signal option
require-abort-timeout-cleanupwarnfalseA function that aborts a fetch request from a setTimeout callback but never clears the timer

plugins/discord ​

RuleSeverityDefaultDetects
no-unsafe-dynamic-discord-messagewarnfalseDynamic message content sent without an explicit allowedMentions policy

Scoped rules ​

RuleSeverityDefaultDetects
no-adapter-importerrorfalseAn import of a path that contains integrations/ or adapters/
no-direct-responseerrorfalsenew Response(...), Response.json(...), or Response.redirect(...) in the scoped layer

They need includes to name the layer they protect, so a shared preset cannot carry them. Declare them in the project's own configuration.

no-adapter-import ​

json
{
  "plugins": [
    {
      "path": "./node_modules/@yuu1111/biome-config/plugins/scoped/no-adapter-import.grit",
      "includes": ["**/src/modules/authorization/**"]
    }
  ]
}

The plugin runs only on the files that match includes, so the same import stays valid in the adapters and in the layers that are allowed to reach them. A plugin pattern is matched against the full file path, so it has to start with **/ to match a path such as src/modules/authorization.

Biome resolves a plugin path as a file path, so reference the rule through node_modules as shown above. A package specifier such as @yuu1111/biome-config/plugins/scoped/no-adapter-import.grit is resolved as a plugin package instead.

Leave the layer that is allowed to reach the integration modules out of the pattern. A module that keeps its own adapter implementations under an adapters/ directory has to exclude that directory, or the rule reports the adapters themselves:

json
{
  "includes": [
    "**/src/modules/authorization/**",
    "!**/src/modules/authorization/adapters/**"
  ]
}

no-direct-response ​

json
{
  "plugins": [
    {
      "path": "./node_modules/@yuu1111/biome-config/plugins/scoped/no-direct-response.grit",
      "includes": ["**/src/worker/routes/**"]
    }
  ]
}

The helper module itself stays outside the pattern, so it can still construct responses.