oxc-project/oxc · warning · OxcDiagnostic

Do not rename import, export, or destructured assignments to

Error message

Do not rename import, export, or destructured assignments to the same name

What it means

Diagnostic from the `no-useless-rename` rule. An import, export, or destructuring assignment renames a binding to exactly the same name: `import { foo as foo }`, `export { bar as bar }`, `let { a: a } = obj`. The rename is a no-op. The rule's config includes options (e.g. `allowDestructuringAsRename`... implemented via `NoUselessRenameConfig` with camelCase serde fields) to tolerate destructuring when desired.

Source

Thrown at crates/oxc_linter/src/rules/eslint/no_useless_rename.rs:23

        BindingPattern, BindingProperty, ImportOrExportKind,
    },
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use schemars::JsonSchema;
use serde::Deserialize;

use crate::{
    AstNode,
    context::LintContext,
    fixer::{RuleFix, RuleFixer},
    rule::{DefaultRuleConfig, Rule},
};

fn no_useless_rename_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(
        "Do not rename import, export, or destructured assignments to the same name",
    )
    .with_help("Use the variable's original name or rename it to a different name")
    .with_label(span)
}

#[derive(Debug, Default, Clone, Deserialize)]
pub struct NoUselessRename(Box<NoUselessRenameConfig>);

#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoUselessRenameConfig {
    /// When set to `true`, allows using the same name in destructurings.
    ignore_destructuring: bool,
    /// When set to `true`, allows renaming imports to the same name.
    ignore_import: bool,
    /// When set to `true`, allows renaming exports to the same name.
    ignore_export: bool,
}

View on GitHub (pinned to 36ec0ef2ba)

Solutions

  1. Drop the alias: `import { foo as foo }` -> `import { foo }`.
  2. For destructuring: `const { x: x } = obj` -> `const { x } = obj`.
  3. Set `{ "allowDestructuring": true }` in config if you want same-name destructuring kept.
  4. Apply the autofix; the rule provides a RuleFix that removes the redundant rename text.

Example fix

// before
import { readFile as readFile } from 'node:fs';
const { x: x } = point;

// after
import { readFile } from 'node:fs';
const { x } = point;
Defensive patterns

Strategy: validation

Validate before calling

const hasRedundantRename = /\{\s*[\w$]+\s+as\s+[\w$]+\s*\}/.test(importLine) &&
  importLine.match(/\{\s*([\w$]+)\s+as\s+([\w$]+)/)?.slice(1)?.every(n => n === importLine.match(/as\s+([\w$]+)/)?.[1]);

Prevention

When it happens

Trigger: `import { readFile as readFile } from 'fs'`, `export { default as default }`, `const { x: x } = point`, `import * as ns`-style module renames that repeat the namespace. Fires on ImportSpecifier/ExportSpecifier/ObjectPattern property pairs where imported/exported/local names are identical.

Common situations: Codemods that mechanically add aliases to every specifier; editors auto-completing `x as x`; migration scripts converting CommonJS requires to named imports with redundant aliases.

Related errors


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