Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
oxc-project avatar

Performance Lint Rules

  • 145 installs
  • 22.2k repo stars
  • Updated August 5, 2026
  • oxc-project/oxc

Performance Lint Rules is an agent skill that gives performance tips for writing Oxc linter rules in Rust under crates/oxc_linter/src/rules/.

About

Performance Lint Rules is a narrow meta skill for contributors working on the Oxc linter in Rust. It applies only when editing rule implementations under crates/oxc_linter/src/rules/, explicitly not parser, formatter, or unrelated crates. Solo maintainers and indie OSS contributors use it to keep rules fast on large JavaScript and TypeScript codebases: hoist node-kind filters, run inexpensive predicates before semantic analysis, avoid building diagnostics until needed, and prefer the smallest iterable scope including run_once when a full-file pass suffices. The skill encodes how most files are clean and most nodes never match a given rule, so micro-optimizations at the hot path matter at scale. It pairs with general Rust performance practice but is opinionated for Oxc’s lintgen-generated runners. Advanced complexity is appropriate because readers must understand AST shape, rule traits, and allocator costs. Do not invoke for greenfield app features or non-Oxc lint authoring.

  • Scoped strictly to Rust under crates/oxc_linter/src/rules/
  • Prefer top-level AST node kind checks so lintgen can skip unrelated nodes
  • Order checks cheapest-first with early returns before semantic lookups and allocations
  • Defer diagnostic and fix construction until a violation is confirmed
  • Use run_once for whole-file passes when per-node visitation is unnecessary

Performance Lint Rules by the numbers

  • 145 all-time installs (skills.sh)
  • +5 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #59 of 121 Rust skills by installs in the Skillselion catalog
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/oxc-project/oxc --skill performance-lint-rules

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs145
repo stars22.2k
Security audit3 / 3 scanners passed
Last updatedAugust 5, 2026
Repositoryoxc-project/oxc

What it does

Optimize Rust implementations of Oxc linter rules so they run cheaply on real-world repos under crates/oxc_linter/src/rules/.

Who is it for?

Oxc contributors implementing or tuning rules in the official linter rules directory who care about linter throughput.

Skip if: General JavaScript lint configuration, oxc formatter/parser work, tests outside rules/, or application Rust services outside this path.

When should I use this skill?

Editing Rust rule implementations under crates/oxc_linter/src/rules/ and need performance guidance for Oxc linter rules.

What you get

You refactor the rule with cheaper ordering, selective node matching, and lazy diagnostics so lint passes stay fast on typical repos.

  • Performance-optimized rule implementation
  • Cheaper check ordering and visitation strategy

Files

SKILL.mdMarkdownGitHub ↗

Performance Guidelines

Prefer top-level node kind checks

Put node kind checks at the rule entry point. If a rule only handles a few syntactic forms, start run with an AstKind match and return for all other nodes, even when a helper filters again internally. This lets lintgen derive narrower NODE_TYPES and avoids dispatching the rule on unrelated AST nodes.

After changing the relevant node kinds for a rule, regenerate the rule runner with cargo lintgen and consider adding or updating assert_rule_runs_on_node_types coverage in crates/oxc_linter/src/rule.rs.

Implement only the needed entry point. If a rule is a whole-file pass over semantic indexes, use run_once by itself. Implementing both run and run_once prevents useful node-type narrowing.

Do cheaper checks first

Order checks from cheapest and most selective to most expensive. Return quickly for common non-matches before doing semantic lookups, allocations, or deeper traversal.

  • Matching a small fixed string set with matches! before semantic checks.
  • Rejecting lowercase identifiers before global-object checks when only constructors can match.
  • Checking whether a JSX attribute starts with aria- before lowercasing it.
  • Checking for required syntax such as a key prop before looking up callback parameter symbols.
  • Checking source_range(span).contains("this") before running a visitor that only finds this.

Delay expensive context

Most files do not contain lint errors. Do not prepare diagnostics, labels, help text, fix data, ancestors, symbols, JSX element types, or replacement strings until the rule has found a syntactic candidate that could actually report.

Iterate over the smallest set possible

  • Use run_once when the rule only needs a whole-file pass and does not need to run on every node.
  • Iterate over symbols instead of AST nodes when looking for references to specific names.
  • Prefer targeted lists or semantic data over broad AST traversal when available.
  • For name-based binding checks, use ctx.scoping().get_binding(scope_id, name) instead of scanning every binding in get_bindings(scope_id).
  • For global or unresolved identifier checks, start from ctx.scoping().root_unresolved_references().get(name) for the small set of relevant names instead of visiting every IdentifierReference.
  • When iterating unresolved references, still verify the reference is the right kind: skip references with a symbol, type-only references, and nodes whose AstKind is not the expected identifier or member access.
  • When checking imported specifiers or exported names, iterate the concrete specifiers or precomputed export set rather than scanning all root bindings for every item.

Use precomputed FxHashSets only when many symbols need the same membership test. Prefer keyed semantic lookup when each lookup already has an exact name.

Avoid unnecessary regular expressions

Avoid regular expressions when byte or string checks are enough: contains, starts_with, ends_with, or matching a small fixed set.

For hot comment or string scanning paths, prefer a cheap memchr or byte search to reject most inputs, then parse only candidates. Preserve regex semantics when replacing one, especially identifier boundaries, optional prefixes, and multiline whitespace.

Avoid heap allocations

  • Use copy-on-write utilities when a value usually does not need to change.
  • Avoid intermediate Vecs and Strings when iteration or borrowed data is enough.
  • Keep temporary data on the stack when practical.
  • Delay allocation until a diagnostic, fix, or transformed value is actually needed.
  • Use allocation-free ASCII comparisons such as starts_with_ignore_case before calling cow_to_ascii_lowercase.
  • Use byte scans such as as_bytes().array_windows() for simple ASCII patterns like escape sequences.
  • Reserve hash maps or sets when the final size is known.
  • Avoid building a HashSet just to check names that can be looked up directly in scoping data.

Related skills

How it compares

Meta performance guidance for Oxc rule authors, not an end-user ESLint replacement skill or a generic Rust perf audit.

FAQ

Who is performance-lint-rules for?

Rust developers contributing to Oxc who implement linter rules and need lintgen-aware performance patterns.

When should I use performance-lint-rules?

Only while editing files under crates/oxc_linter/src/rules/ when optimizing or authoring a rule implementation.

Is performance-lint-rules safe to install?

It guides local Rust edits in a known repo path; review the Security Audits panel on this Prism page for the skill package provenance.

Rustbackendtesting

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.