Skip to main content
interlace
Plugin: import-nextRules

no-unresolved

Ensures imports point to resolvable modules

💼 This rule is enabled in the following configs: recommended, typescript. 💡 This rule is manually fixable by editor suggestions.

Rule Details

Reports a static module specifier that resolves to no file. Resolution follows Node and TypeScript: relative paths with or without an extension, index files, the NodeNext .js spelling of a .ts file, node_modules packages (scoped too), a package's exports map (a subpath it does not export does not resolve), the package.json imports map (#util) and tsconfig paths aliases.

Not reported:

  • Node builtins (fs, fs/promises, node:fs);
  • a specifier with a URL scheme (virtual:routes, bun:test, https://...): a module a bundler or runtime provides, which a file resolver cannot judge;
  • a computed specifier (import(name), require(path));
  • a specifier listed in ignore (exactly, or as a path prefix; * matches any run of characters);
  • anything, when allowUnresolved is true.

extensions replaces the file extensions tried for an extensionless relative specifier (default .ts, .tsx, .js, .jsx, .d.ts, .json).

Every spelling is checked: import, import type, side-effect imports, export { a } from, export * from, import('x'), require('x') and TS import x = require('x').

// ❌ Incorrect
import { dep } from './missing';
import feature from 'pkg/not-exported-subpath';

// ✅ Correct
import { dep } from './dep'; // dep.ts
import { readFile } from 'node:fs/promises';
import routes from 'virtual:routes';

Options

[
  {
    "type": "object",
    "properties": {
      "extensions": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "description": "File extensions to consider when resolving imports."
      },
      "ignore": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "description": "Modules/patterns to ignore during resolution."
      },
      "allowUnresolved": {
        "type": "boolean",
        "default": false,
        "description": "Allow unresolved imports in certain contexts."
      }
    },
    "additionalProperties": false
  }
]

Implementation

OWASP Foundation

  • Category: A03:2021 - Injection

Use this rule

npm install -D oxlint-plugin-import-next
.oxlintrc.json
{  "jsPlugins": ["oxlint-plugin-import-next"],  "rules": {    "import-next/no-unresolved": "error"  }}
vite.config.ts
import { defineConfig } from 'vite-plus';export default defineConfig({  lint: {    jsPlugins: ['oxlint-plugin-import-next'],    rules: {      'import-next/no-unresolved': '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.