oxc-project/oxc · warning · OxcDiagnostic

All 'var' declarations must be at the top of the function sc

Error message

All 'var' declarations must be at the top of the function scope.

What it means

oxlint's `vars-on-top` rule enforces the style where every `var` declaration in a function (or program) scope precedes all other statements — matching what hoisting actually does at runtime. The diagnostic fires on any var declaration that follows a non-var statement in its scope; ambient TypeScript contexts are exempted via `has_ambient_typescript_ancestor`.

Source

Thrown at crates/oxc_linter/src/rules/eslint/vars_on_top.rs:10

use oxc_ast::AstKind;
use oxc_ast::ast::{Declaration, Expression, Program, Statement, VariableDeclarationKind};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};

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

fn vars_on_top_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("All 'var' declarations must be at the top of the function scope.")
        .with_help("Consider moving this to the top of the functions scope or using let or const to declare this variable.")
        .with_label(span)
}

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

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Enforces that all `var` declarations are placed at the top of their containing scope.
    ///
    /// ### Why is this bad?
    ///
    /// In JavaScript, `var` declarations are hoisted to the top of their containing scope. Placing `var` declarations at the top explicitly improves code readability and maintainability by making the scope of variables clear.
    ///
    /// ### Examples
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Replace var with let/const declared where the value is first needed (preferred modern fix)
  2. Or move the var declarations to the top of the function scope
  3. Disable or downgrade `vars-on-top` if the team has fully adopted let/const and the rule is pure noise

Example fix

// before
function process(input) {
  validate(input);
  var results = [];
  for (var item of input) results.push(transform(item));
  return results;
}

// after
function process(input) {
  validate(input);
  const results = [];
  for (const item of input) results.push(transform(item));
  return results;
}
Defensive patterns

Strategy: validation

Validate before calling

// .oxlintrc.json
{ "rules": { "vars-on-top": "warn" } }
// pre-commit: npx oxlint --fix src/legacy/

Prevention

When it happens

Trigger: `function f() { doFirst(); var x = 1; }` — a VariableDeclaration of kind var appearing after expression or other statements within the same function scope (or top-level program scope).

Common situations: Legacy ES5 codebases; incremental migrations where pockets of var remain; merge conflicts that move statements above existing var declarations.

Related errors


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