no-useless-path-segments
Forbid unnecessary path segments in import and require statements
💼 This rule is enabled in the following configs: recommended, typescript.
🔧 This rule is automatically fixable by the --fix CLI option.
Rule Details
Reports a relative specifier that a shorter relative specifier names the same module with, and fixes it to the shorter one. Node resolves a relative specifier against the importing file's directory, so these are the same module by construction:
./lib/./dep,./lib/../dep,./lib//depand././dep(lexical normalisation);- a path that leaves the file's directory and comes back into it: from
src/app.ts,../src/depis./depand./../src/depis./dep.
With noUselessIndex: true, an extensionless trailing /index is useless too
(./lib/index becomes ./lib, ./index becomes .), but only when both
paths resolve to the same file. ./both/index beside a both.ts is not
reported: ./both names both.ts. A path that does not resolve proves
nothing and is not reported.
Not reported:
./lib/index.js: a written extension, which ESM / NodeNext requires (a directory import does not load there);- a trailing slash (
./lib/), which only matches a directory and can name a different module than./lib; - package and absolute specifiers.
Every static spelling is checked: import, import type, side-effect
import './x', export { a } from, export * from and import('./x').
require('./x') and TS import x = require('./x') are checked while
commonjs is true (the default).
// ❌ Incorrect (in src/app.ts)
import a from './lib/../dep';
export * from '../src/dep';
const b = require('./lib//dep');
// ✅ Correct
import a from './dep';
export * from './dep';
const b = require('./lib/dep');Options
[
{
"type": "object",
"properties": {
"noUselessIndex": {
"type": "boolean",
"default": false
},
"commonjs": {
"type": "boolean",
"default": true
}
},
"additionalProperties": false
}
]Implementation
OWASP Foundation
- Category: A00:2021 - General Security
Use this rule
npm install -D oxlint-plugin-import-next{ "jsPlugins": ["oxlint-plugin-import-next"], "rules": { "import-next/no-useless-path-segments": "error" }}import { defineConfig } from 'vite-plus';export default defineConfig({ lint: { jsPlugins: ['oxlint-plugin-import-next'], rules: { 'import-next/no-useless-path-segments': 'error', }, },});oxlint-plugin-import-next re-exports eslint-plugin-import-next/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.
Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.