Rules governing module imports, exports, and dependency management for better module organization.
Rules for consistent import patterns and module loading.
/**
* Enforces consistent import style patterns
*/
'unicorn/import-style': 'error' | 'warn' | 'off' | [
'error' | 'warn',
{
checkImport?: boolean; // Default: true
checkDynamicImport?: boolean; // Default: false
checkExportFrom?: boolean; // Default: false
checkRequire?: boolean; // Default: false
extendDefaultStyles?: boolean; // Default: true
styles?: Record<string, {
named?: 'camelCase' | 'kebabCase' | 'pascalCase' | false;
default?: 'camelCase' | 'kebabCase' | 'pascalCase' | false;
namespace?: 'camelCase' | 'kebabCase' | 'pascalCase' | false;
unassigned?: boolean;
}>;
}
];
/**
* Prefers node: protocol for Node.js built-in modules
*/
'unicorn/prefer-node-protocol': 'error' | 'warn' | 'off';
/**
* Requires specific module specifiers for imports
*/
'unicorn/require-module-specifiers': 'error' | 'warn' | 'off' | [
'error' | 'warn',
{
patterns?: Record<string, string>;
}
];Usage Examples:
// ❌ Bad - inconsistent import style
import * as fs from 'fs';
import { readFile } from 'fs';
// ✅ Good - consistent import style (prefer named imports)
import { readFile, writeFile } from 'node:fs';
// ❌ Bad - missing node: protocol
import fs from 'fs';
import path from 'path';
import util from 'util';
// ✅ Good - using node: protocol
import fs from 'node:fs';
import path from 'node:path';
import util from 'node:util';
// ❌ Bad - bare module specifier when specific version needed
import lodash from 'lodash';
// ✅ Good - specific module specifier (if configured)
import lodash from 'lodash-es';Rules for consistent export patterns and module structure.
/**
* Prevents anonymous default exports
*/
'unicorn/no-anonymous-default-export': 'error' | 'warn' | 'off';
/**
* Prefers export-from syntax for re-exports
*/
'unicorn/prefer-export-from': 'error' | 'warn' | 'off' | [
'error' | 'warn',
{
ignoreUsedVariables?: boolean; // Default: false
}
];
/**
* Prevents named default imports and exports
*/
'unicorn/no-named-default': 'error' | 'warn' | 'off';Usage Examples:
// ❌ Bad - anonymous default export
export default function() {
return 'helper';
}
// ✅ Good - named default export
export default function helper() {
return 'helper';
}
// ❌ Bad - manual re-export
import { utility } from './utils.js';
export { utility };
// ✅ Good - export-from syntax
export { utility } from './utils.js';
// ❌ Bad - named default import
import { default as React } from 'react';
// ✅ Good - regular default import
import React from 'react';Rules for consistent module system usage and patterns.
/**
* Prefers ES modules over CommonJS
*/
'unicorn/prefer-module': 'error' | 'warn' | 'off' | [
'error' | 'warn',
{
checkDefaultCase?: boolean; // Default: false
}
];
/**
* Prefers import.meta properties over alternatives
*/
'unicorn/prefer-import-meta-properties': 'error' | 'warn' | 'off';Usage Examples:
// ❌ Bad - CommonJS patterns in ES modules
const path = require('path');
module.exports = { helper };
// ✅ Good - ES module patterns
import path from 'node:path';
export { helper };
// ❌ Bad - __dirname in ES modules
const currentDir = __dirname;
// ✅ Good - import.meta.url
const currentDir = new URL('.', import.meta.url).pathname;
// ❌ Bad - __filename alternative
const currentFile = __filename;
// ✅ Good - import.meta.url for filename
const currentFile = new URL(import.meta.url).pathname;Rules for proper dynamic import usage.
/**
* Import style rules also apply to dynamic imports when configured
*/
'unicorn/import-style': [
'error',
{
checkDynamicImport: true, // Enable dynamic import checking
}
];Usage Examples:
// ❌ Bad - inconsistent dynamic import (if configured to prefer named)
const module = await import('lodash');
// ✅ Good - consistent with static import style
const { debounce } = await import('lodash');
// Dynamic imports with proper error handling
try {
const { processData } = await import('./data-processor.js');
await processData(input);
} catch (error) {
console.error('Failed to load data processor:', error);
}Rules for package.json and module resolution patterns.
/**
* Requires specific patterns in package.json imports/exports
* (This would be configured through require-module-specifiers)
*/
'unicorn/require-module-specifiers': [
'error',
{
patterns: {
'lodash': 'lodash-es', // Prefer ES module version
'react-dom': 'react-dom/client', // Prefer specific entry point
}
}
];Usage Examples:
// ❌ Bad - using CommonJS version when ES module preferred
import _ from 'lodash';
// ✅ Good - using ES module version
import _ from 'lodash-es';
// ❌ Bad - using legacy entry point
import { render } from 'react-dom';
// ✅ Good - using modern entry point
import { createRoot } from 'react-dom/client';Rules for handling conditional module loading.
/**
* Import style rules can be configured for different environments
*/
'unicorn/import-style': [
'error',
{
styles: {
'node:fs': {
named: 'camelCase',
default: false, // Discourage default import
},
'react': {
default: 'pascalCase',
named: 'camelCase',
}
}
}
];Usage Examples:
// Environment-specific imports
if (typeof window !== 'undefined') {
// Browser-specific imports
const { browserUtil } = await import('./browser-utils.js');
} else {
// Node.js-specific imports
const { readFile } = await import('node:fs/promises');
}
// Conditional exports in package.json would be:
// {
// "exports": {
// "node": "./dist/node.js",
// "default": "./dist/browser.js"
// }
// }Rules specific to TypeScript import patterns.
/**
* Import style rules for TypeScript-specific patterns
*/
'unicorn/import-style': [
'error',
{
styles: {
'@types/*': {
default: false, // Types should use named imports
named: 'camelCase',
}
}
}
];Usage Examples:
// ❌ Bad - default import for types
import Express from '@types/express';
// ✅ Good - named imports for types
import { Request, Response } from '@types/express';
// Type-only imports
import type { User } from './types.js';
import type { ApiResponse } from './api-types.js';
// Mixed imports
import { processUser, type UserConfig } from './user-utils.js';export default [
{
plugins: {
unicorn: eslintPluginUnicorn,
},
rules: {
// Import style consistency
'unicorn/import-style': [
'error',
{
checkImport: true,
checkDynamicImport: true,
styles: {
'node:fs': { named: 'camelCase', default: false },
'node:path': { named: 'camelCase', default: false },
'lodash': { named: 'camelCase', default: false },
'react': { default: 'pascalCase' },
}
}
],
// Module system preferences
'unicorn/prefer-node-protocol': 'error',
'unicorn/prefer-module': 'error',
'unicorn/prefer-import-meta-properties': 'error',
// Export patterns
'unicorn/no-anonymous-default-export': 'error',
'unicorn/prefer-export-from': 'error',
'unicorn/no-named-default': 'error',
// Module specifiers
'unicorn/require-module-specifiers': [
'error',
{
patterns: {
'lodash': 'lodash-es',
'react-dom': 'react-dom/client',
}
}
],
},
},
];export default [
{
plugins: {
unicorn: eslintPluginUnicorn,
},
rules: {
// Require node: protocol for all built-ins
'unicorn/prefer-node-protocol': 'error',
// Prefer ES modules
'unicorn/prefer-module': 'error',
'unicorn/prefer-import-meta-properties': 'error',
// Node.js import style
'unicorn/import-style': [
'error',
{
styles: {
'node:fs': { named: 'camelCase' },
'node:fs/promises': { named: 'camelCase' },
'node:path': { named: 'camelCase' },
'node:url': { named: 'camelCase' },
'node:util': { named: 'camelCase' },
}
}
],
},
},
];export default [
{
plugins: {
unicorn: eslintPluginUnicorn,
},
rules: {
// React-friendly import styles
'unicorn/import-style': [
'error',
{
styles: {
'react': { default: 'pascalCase' },
'react-dom/client': { named: 'camelCase' },
'@types/react': { named: 'pascalCase' },
}
}
],
// Export patterns for components
'unicorn/no-anonymous-default-export': 'error',
'unicorn/prefer-export-from': ['error', { ignoreUsedVariables: true }],
// Modern module patterns
'unicorn/prefer-module': 'error',
'unicorn/require-module-specifiers': [
'error',
{
patterns: {
'react-dom': 'react-dom/client'
}
}
],
},
},
];