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
- Replace the assignment with `el.addEventListener('click', handler)` (and `removeEventListener` where you previously set `onX = null`).
- Use options when useful: `el.addEventListener('click', handler, { once: true })`.
- 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.
- 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
- Default to addEventListener/removeEventListener; treat `onX =` as legacy API only.
- Where a single guaranteed handler is required, document it next to an inline suppression comment.
- Codemod old pages once: search `\.on[a-z]+\s*=` and convert.
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
- Invalid `removeEventListener` call.
- Prefer `Blob#{good_method}()` over `FileReader#{bad_method}(
- Prefer `classList.toggle()` over `classList.add()` and `clas
- Avoid calls to the `Array` constructor
- `{name}` is never reassigned.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/b2be01c3fe1beab7.
Report an issue: GitHub.