OXC.Lint (OXC v0.19.0)

Copy Markdown View Source

Lint JavaScript/TypeScript source with oxlint's built-in rules and optional custom Elixir rules.

Combines native Rust performance for 650+ standard rules with the ability to write project-specific rules in Elixir using the same AST that OXC.parse/2 returns.

Examples

{:ok, diags} = OXC.Lint.run("debugger;", "test.js",
  rules: %{"no-debugger" => :deny})

{:ok, []} = OXC.Lint.run("export const x = 1;\n", "test.ts")

Summary

Types

An oxlint plugin name, such as "react" or "jsx-a11y".

Rule severity in lint options. Findings report :error for :deny and :warning for :warn.

Functions

Lint source code with oxlint's built-in rules and optional custom rules.

Like run/3 but raises on errors.

Resolve the type-aware rules that run/2 submits to tsgolint for these options.

Types

diagnostic()

@type diagnostic() :: OXC.Diagnostic.t()

global_access()

@type global_access() :: :readonly | :writable | :off

option()

@type option() ::
  {:rules, %{required(String.t()) => severity()}}
  | {:plugins, [plugin()]}
  | {:env, [String.t()]}
  | {:globals, %{required(String.t()) => global_access()}}
  | {:fix, boolean()}
  | {:custom_rules, [{module(), severity()}]}
  | {:settings, map()}

plugin()

@type plugin() :: String.t()

An oxlint plugin name, such as "react" or "jsx-a11y".

severity()

@type severity() :: :allow | :warn | :deny

Rule severity in lint options. Findings report :error for :deny and :warning for :warn.

Functions

run(files, opts)

@spec run([String.t()], [OXC.Lint.TypeAware.option()]) ::
  {:ok, [diagnostic()]} | {:error, [diagnostic()]}

Lint source code with oxlint's built-in rules and optional custom rules.

Pass a list of files with type_aware: true to run TypeScript type-aware rules through tsgolint headless mode:

OXC.Lint.run(["lib/app.ts"],
  type_aware: true,
  tsgolint: "tsgolint",
  rules: %{"typescript/no-floating-promises" => :deny})

Categories select type-aware rules too, from the enabled :plugins, so rules: %{"correctness" => :deny} runs typescript/no-floating-promises.

Options

  • :rules — map of rule names to severity (:deny, :warn, :allow). Rule names follow oxlint conventions: "eqeqeq", "react/no-danger", "typescript/no-explicit-any", etc. Categories such as "correctness" and "all" select every rule in them. "all" applies first, then categories, then single rules, so a single rule overrides its category.

  • :plugins — oxlint plugin names to enable, such as ["react", "jsx-a11y"], accepting the same names and aliases as an oxlint config file. Default: oxlint's default plugins. Unknown names are errors.

  • :fix — compute fix suggestions. Default: false

  • :env — list of enabled Oxlint environment names, for example ["browser", "node", "mocha"].

  • :globals — map of global names to :readonly, :writable, or :off, for example %{"jQuery" => :readonly}.

  • :custom_rules — list of {module, severity} tuples for Elixir rules. Each module must implement the OXC.Lint.Rule behaviour.

  • :settings — arbitrary map passed to custom rule context.

Examples

# Built-in rules only
{:ok, diags} = OXC.Lint.run("debugger;", "test.js",
  rules: %{"no-debugger" => :deny})

# With specific plugins and rules
{:ok, diags} = OXC.Lint.run(source, "app.tsx",
  plugins: ["react", "typescript"],
  rules: %{"no-console" => :warn, "react/no-danger" => :deny}
)

# With custom Elixir rules
{:ok, diags} = OXC.Lint.run(source, "app.ts",
  custom_rules: [{MyApp.NoConsoleLog, :warn}]
)

run(source, filename, opts \\ [])

@spec run(iodata(), String.t(), [option()]) ::
  {:ok, [diagnostic()]} | {:error, [diagnostic()]}

run!(source, filename, opts \\ [])

@spec run!(iodata(), String.t(), [option()]) :: [diagnostic()]

Like run/3 but raises on errors.

type_aware_rules(opts)

@spec type_aware_rules(keyword()) ::
  {:ok, %{required(String.t()) => severity() | {severity(), term()}}}
  | {:error, [diagnostic()]}

Resolve the type-aware rules that run/2 submits to tsgolint for these options.

all and category filters in :rules select type-aware rules from the enabled :plugins through oxlint's rule registry. Rules named typescript/* keep their options and override their categories. Other rules are syntax rules and are left out.

{:ok, %{"typescript/no-floating-promises" => :deny}} =
  OXC.Lint.type_aware_rules(rules: %{"typescript/no-floating-promises" => :deny})