oxc-project/oxc · warning · OxcDiagnostic

Prefer `addEventListener()` over their `on`-function counter

Error message

Prefer `addEventListener()` over their `on`-function counterparts.

What it means

Lint diagnostic from oxlint's `unicorn/prefer-add-event-listener` rule. Assigning to `on<event>` properties (`el.onclick = ...`) silently replaces any previously registered handler and cannot use options like `{ once: true }`. The rule requires `addEventListener()` so multiple handlers can coexist and options are available.

Source

Thrown at crates/oxc_linter/src/rules/unicorn/prefer_add_event_listener.rs:9

use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;

use crate::{AstNode, context::LintContext, rule::Rule};

fn prefer_add_event_listener_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Prefer `addEventListener()` over their `on`-function counterparts.")
        .with_help(
            "`addEventListener()` can register multiple handlers and accepts options such as `{ once: true }`; assigning to `on<event>` replaces any previously registered handler.",
        )
        .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct PreferAddEventListener;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Enforces the use of `.addEventListener()` and `.removeEventListener()` over their `on`-function counterparts.
    ///
    /// For example, `foo.addEventListener('click', handler);` is preferred over `foo.onclick = handler;` for HTML DOM Events.
    ///
    /// ### Why is this bad?
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Replace the assignment with `el.addEventListener('click', handler)` (and `removeEventListener` where you previously set `onX = null`).
  2. Use options when useful: `el.addEventListener('click', handler, { once: true })`.
  3. If the overwrite behavior is intentional (guaranteeing a single handler), keep the assignment but suppress with `// oxlint-disable-next-line unicorn/prefer-add-event-listener` and leave a comment why.
  4. Disable the rule in `.oxlintrc.json` for DOM-light codebases where it adds noise.

Example fix

// before
button.onclick = () => submit();

// after
button.addEventListener('click', () => submit());
Defensive patterns

Strategy: validation

Validate before calling

// oxlint --filter unicorn/prefer-add-event-listener src/
// CI gate: oxlint --deny-warnings src/

Prevention

When it happens

Trigger: Any assignment to an `on`-prefixed DOM event handler property found in the AST: `button.onclick = handleClick;`, `window.onload = init;`, `document.body.onkeydown = onKey;` (also `on(` setter forms like jQuery-style `$(el).on(...)` variants the rule recognizes). Fires during oxlint runs when the rule is enabled.

Common situations: Legacy tutorial code using `window.onload`, HTML attributes ported to JS (`onclick=`), or refactors that add a second listener and accidentally clobber the first because `onX =` overwrites. Common when a codebase adopts oxlint's unicorn category and old page scripts get flagged in bulk.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/b2be01c3fe1beab7. Report an issue: GitHub.