no-mutable-exports
Forbid the use of mutable exports with `var` or `let`
💼 This rule is enabled in the following configs: recommended, typescript.
Rule Details
An exported let or var is a live binding: every importer sees the exporting module's later reassignments, which makes the value's history hard to follow. This rule reports a module-level let / var that the module exports by name:
- inline, also destructured (
export let { a } = obj); - through an export list, also renamed (
export { count as total }); - as the default through a list (
export { count as default }), which exports the binding.
Not reported: const, functions and classes; export default count, which exports the value at that moment, not the binding; a re-export from another module; an imported binding re-exported.
❌ Incorrect
export let count = 0;
var total = 0;
export { total };✅ Correct
export const count = 0;
let total = 0;
export default total;
export function increment() {}Options
[
{
"type": "object",
"properties": {
"allowInFiles": {
"type": "array",
"items": {
"type": "string"
},
"description": "File patterns where mutable exports are allowed"
},
"ignoreExports": {
"type": "array",
"items": {
"type": "string"
},
"description": "Specific export names to ignore"
}
},
"additionalProperties": false
}
]allowInFiles(default[]): file globs (or path substrings) where mutable exports are accepted. A glob matches any run of whole path segments, so**/state/*.tsmatches an absolute filename.ignoreExports(default[]): exported names to skip; the name the module publishes (totalinexport { count as total }).
When Not To Use It
When a module intentionally exposes live bindings, e.g. a state module read by other modules.
Use this rule
npm install -D oxlint-plugin-import-next{ "jsPlugins": ["oxlint-plugin-import-next"], "rules": { "import-next/no-mutable-exports": "error" }}import { defineConfig } from 'vite-plus';export default defineConfig({ lint: { jsPlugins: ['oxlint-plugin-import-next'], rules: { 'import-next/no-mutable-exports': '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.