Rules for consistent code formatting, naming conventions, and stylistic preferences that improve code readability.
Rules enforcing consistent naming patterns across the codebase.
/**
* Enforces filename case conventions
*/
'unicorn/filename-case': 'error' | 'warn' | 'off' | [
'error' | 'warn',
{
case?: 'camelCase' | 'kebabCase' | 'pascalCase' | 'snakeCase'; // Default: 'kebabCase'
ignore?: (string | RegExp)[]; // Default: []
multipleFileExtensions?: boolean; // Default: true
}
];
/**
* Prevents abbreviations in variable and function names
*/
'unicorn/prevent-abbreviations': 'error' | 'warn' | 'off' | [
'error' | 'warn',
{
checkDefaultAndNamespaceImports?: boolean; // Default: false
checkShorthandImports?: boolean; // Default: false
checkShorthandProperties?: boolean; // Default: false
checkVariables?: boolean; // Default: true
checkProperties?: boolean; // Default: false
checkFilenames?: boolean; // Default: false
extendDefaultReplacements?: boolean; // Default: true
replacements?: Record<string, Record<string, boolean>>;
extendDefaultAllowList?: boolean; // Default: true
allowList?: Record<string, boolean>;
ignore?: (string | RegExp)[];
}
];
/**
* Prevents keyword prefixes in identifiers
*/
'unicorn/no-keyword-prefix': 'error' | 'warn' | 'off' | [
'error' | 'warn',
{
onlyCamelCase?: boolean; // Default: false
checkProperties?: boolean; // Default: false
disallowedPrefixes?: string[]; // Default: ['new', 'for', 'class']
}
];Usage Examples:
// ❌ Bad - inconsistent filename cases
// myComponent.js (should be my-component.js with kebab-case)
// MyService.js (should be my-service.js with kebab-case)
// ✅ Good - consistent kebab-case filenames
// my-component.js
// user-service.js
// data-processor.js
// ❌ Bad - abbreviations
const btn = document.querySelector('button');
const userInfo = getUserInfo();
const temp = calculateTemperature();
// ✅ Good - full words
const button = document.querySelector('button');
const userInformation = getUserInformation();
const temperature = calculateTemperature();
// ❌ Bad - keyword prefixes
const newUser = 'John';
const className = 'active';
// ✅ Good - avoiding keyword prefixes
const user = 'John';
const cssClass = 'active';Rules for consistent spacing and formatting patterns.
/**
* Enforces consistent empty brace spacing
*/
'unicorn/empty-brace-spaces': 'error' | 'warn' | 'off';
/**
* Enforces consistent console spacing
*/
'unicorn/no-console-spaces': 'error' | 'warn' | 'off';
/**
* Enforces proper template literal indentation
*/
'unicorn/template-indent': 'error' | 'warn' | 'off' | [
'error' | 'warn',
{
indent?: string | number; // Default: detect from context
tags?: string[]; // Default: []
functions?: string[]; // Default: []
selectors?: string[]; // Default: []
comments?: string[]; // Default: []
}
];Usage Examples:
// ❌ Bad - inconsistent brace spacing
const obj = { };
if (condition) { }
// ✅ Good - consistent brace spacing
const obj = {};
if (condition) {}
// ❌ Bad - console spacing
console.log( 'message' );
// ✅ Good - no extra console spacing
console.log('message');
// ❌ Bad - template literal indentation
const html = `
<div>
<p>Content</p>
</div>
`;
// ✅ Good - proper template literal indentation
const html = `
<div>
<p>Content</p>
</div>
`;Rules enforcing consistent case formatting for various constructs.
/**
* Enforces consistent escape sequence case
*/
'unicorn/escape-case': 'error' | 'warn' | 'off';
/**
* Enforces consistent number literal case
*/
'unicorn/number-literal-case': 'error' | 'warn' | 'off';
/**
* Enforces consistent text encoding identifier case
*/
'unicorn/text-encoding-identifier-case': 'error' | 'warn' | 'off';
/**
* Enforces consistent numeric separators style
*/
'unicorn/numeric-separators-style': 'error' | 'warn' | 'off' | [
'error' | 'warn',
{
hexadecimal?: {
minimumDigits?: number; // Default: 0
groupLength?: number; // Default: 2
};
binary?: {
minimumDigits?: number; // Default: 0
groupLength?: number; // Default: 4
};
octal?: {
minimumDigits?: number; // Default: 0
groupLength?: number; // Default: 4
};
number?: {
minimumDigits?: number; // Default: 5
groupLength?: number; // Default: 3
};
}
];Usage Examples:
// ❌ Bad - inconsistent escape case
const path = 'c:\\users\\documents';
// ✅ Good - consistent escape case
const path = 'C:\\Users\\Documents';
// ❌ Bad - inconsistent number literal case
const hex = 0xabc;
const scientific = 1e10;
// ✅ Good - consistent number literal case
const hex = 0xABC;
const scientific = 1E10;
// ❌ Bad - missing numeric separators
const largeNumber = 1000000;
const hexNumber = 0x1234567890abcdef;
// ✅ Good - using numeric separators
const largeNumber = 1_000_000;
const hexNumber = 0x12_34_56_78_90_ab_cd_ef;Rules for consistent switch statement and brace formatting.
/**
* Enforces consistent switch case brace style
*/
'unicorn/switch-case-braces': 'error' | 'warn' | 'off' | [
'error' | 'warn',
'always' | 'avoid',
{
allowSingleLineStatement?: boolean; // Default: true
}
];
/**
* Prevents useless switch cases
*/
'unicorn/no-useless-switch-case': 'error' | 'warn' | 'off';Usage Examples:
// ❌ Bad - inconsistent switch case braces
switch (value) {
case 'a':
doSomething();
break;
case 'b': {
doSomethingElse();
break;
}
}
// ✅ Good - consistent switch case braces
switch (value) {
case 'a': {
doSomething();
break;
}
case 'b': {
doSomethingElse();
break;
}
}
// ❌ Bad - useless switch case
switch (value) {
case 'a':
return 'a';
default:
return value;
}
// ✅ Good - simplified logic
return value === 'a' ? 'a' : value;Rules for consistent string content and formatting.
/**
* Enforces consistent string content rules
*/
'unicorn/string-content': 'error' | 'warn' | 'off' | [
'error' | 'warn',
{
patterns?: Record<string, string | {
suggest: string;
message?: string;
fix?: boolean;
}>;
}
];
/**
* Prevents hex escape sequences in favor of Unicode
*/
'unicorn/no-hex-escape': 'error' | 'warn' | 'off';Usage Examples:
// ❌ Bad - hex escape sequences
const copyright = '\xA9';
// ✅ Good - Unicode escape sequences
const copyright = '\u00A9';
// With custom string content patterns:
// ❌ Bad - inconsistent quotation marks (if configured)
const message = "Hello 'world'";
// ✅ Good - consistent quotation marks
const message = 'Hello "world"';Rules for consistent comment formatting and management.
/**
* Adds expiration conditions to TODO comments
* Enforces accountability for temporary code and technical debt
*/
'unicorn/expiring-todo-comments': 'error' | 'warn' | 'off' | [
'error' | 'warn',
{
terms?: string[]; // Default: ['todo', 'fixme', 'xxx']
ignore?: (string | RegExp)[]; // Default: []
ignoreDatesOnPullRequests?: boolean; // Default: true
allowWarningComments?: boolean; // Default: true
date?: string; // ISO date format, defaults to current date
}
];Usage Examples:
// ❌ Bad - TODO without expiration
// TODO: Refactor this function
// ✅ Good - TODO with expiration date
// TODO [2024-01-01]: Refactor this function
// ✅ Good - TODO with version expiration
// TODO [engine@>2.0.0]: Remove this compatibility code
// ✅ Good - TODO with dependency condition
// TODO [@babel/core@>7.0.0]: Use new babel API
// ❌ Bad - Expired TODO (if current date > 2023-01-01)
// TODO [2023-01-01]: This should have been fixed
// With custom terms configuration:
// ✅ Good - FIXME with expiration
// FIXME [2024-06-01]: Memory leak in this module
// ✅ Good - XXX with version condition
// XXX [react@>18.0.0]: Update to new hooks APIRules for file content and structure consistency.
/**
* Prevents empty files
*/
'unicorn/no-empty-file': 'error' | 'warn' | 'off';
/**
* Prevents anonymous default exports
*/
'unicorn/no-anonymous-default-export': 'error' | 'warn' | 'off';
/**
* Prevents named default imports
*/
'unicorn/no-named-default': 'error' | 'warn' | 'off';Usage Examples:
// ❌ Bad - empty file (file.js contains nothing)
// ✅ Good - file with content
export const utils = {};
// ❌ Bad - anonymous default export
export default function() {
return 'helper';
}
// ✅ Good - named default export
export default function helper() {
return 'helper';
}
// ❌ Bad - named default import
import { default as React } from 'react';
// ✅ Good - regular default import
import React from 'react';Rules for consistent relative URL formatting.
/**
* Enforces consistent relative URL style
*/
'unicorn/relative-url-style': 'error' | 'warn' | 'off' | [
'error' | 'warn',
'never' | 'always'
];Usage Examples:
// With 'never' option:
// ❌ Bad - using relative URL style
const url = new URL('./path', base);
// ✅ Good - absolute URL construction
const url = new URL(base + '/path');
// With 'always' option:
// ❌ Bad - not using relative URL style
const url = new URL(base + '/path');
// ✅ Good - using relative URL style
const url = new URL('./path', base);export default [
{
plugins: {
unicorn: eslintPluginUnicorn,
},
rules: {
// Naming conventions
'unicorn/filename-case': ['error', { case: 'kebabCase' }],
'unicorn/prevent-abbreviations': ['error', {
replacements: {
btn: { button: true },
elem: { element: true },
prop: { property: true },
}
}],
// Formatting
'unicorn/empty-brace-spaces': 'error',
'unicorn/no-console-spaces': 'error',
'unicorn/template-indent': 'error',
// Case formatting
'unicorn/escape-case': 'error',
'unicorn/number-literal-case': 'error',
'unicorn/numeric-separators-style': 'error',
// Switch and braces
'unicorn/switch-case-braces': ['error', 'always'],
'unicorn/no-useless-switch-case': 'error',
// Comment management
'unicorn/expiring-todo-comments': 'error',
// File structure
'unicorn/no-empty-file': 'error',
'unicorn/no-anonymous-default-export': 'error',
},
},
];export default [
{
plugins: {
unicorn: eslintPluginUnicorn,
},
rules: {
// Custom filename case for React projects
'unicorn/filename-case': [
'error',
{
case: 'pascalCase',
ignore: [/^[a-z]+\.config\.js$/, /^[A-Z]+\.md$/]
}
],
// Custom abbreviation rules
'unicorn/prevent-abbreviations': [
'error',
{
checkFilenames: true,
replacements: {
btn: { button: true },
ctx: { context: true },
evt: { event: true },
prop: false, // Allow 'prop' abbreviation
},
allowList: {
idx: true, // Allow 'idx' as index
}
}
],
// Custom numeric separators
'unicorn/numeric-separators-style': [
'error',
{
number: { minimumDigits: 4, groupLength: 3 },
hexadecimal: { minimumDigits: 5, groupLength: 2 }
}
],
},
},
];