https://github.com/noneforge/eslint-config
TypeScript/JavaScript ESLint configuration with strict type checking and modern stylistic rules
https://github.com/noneforge/eslint-config
code-quality code-style eslint eslint-config eslint9 eslintconfig flat-config javascript javascript-eslint lint noneforge stylistic type-checking typescript typescript-eslint
Last synced: about 1 month ago
JSON representation
TypeScript/JavaScript ESLint configuration with strict type checking and modern stylistic rules
- Host: GitHub
- URL: https://github.com/noneforge/eslint-config
- Owner: noneforge
- License: mit
- Created: 2025-09-07T21:04:30.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2025-09-07T22:29:26.000Z (2 months ago)
- Last Synced: 2025-09-08T00:20:36.943Z (2 months ago)
- Topics: code-quality, code-style, eslint, eslint-config, eslint9, eslintconfig, flat-config, javascript, javascript-eslint, lint, noneforge, stylistic, type-checking, typescript, typescript-eslint
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/@noneforge/eslint-config
- Size: 36.1 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# @noneforge/eslint-config
Modern TypeScript/JavaScript ESLint configuration with strict type checking and comprehensive stylistic rules. Built for ESLint 9+ flat config with full TypeScript 5.5+ support.
## Features
- โจ **ESLint 9 Flat Config** - Modern configuration format with better performance
- ๐ฏ **Strict Type Checking** - Comprehensive type-aware rules to catch errors at build time
- ๐จ **Built-in Formatting** - Replaces Prettier with @stylistic/eslint-plugin for unified tooling
- ๐ **TypeScript 5.5+ Support** - Leverages latest TypeScript features and optimizations
- ๐ฆ **Zero Config Philosophy** - Sensible defaults that work out of the box
- โก **Performance Optimized** - Uses `projectService` for faster type checking
- ๐ง **Smart File Detection** - Different rules for tests, configs, and type definitions
## Related Packages
- [@noneforge/eslint-config-node](https://www.npmjs.com/package/@noneforge/eslint-config-node) - Node.js backend configuration
- [@noneforge/eslint-config-angular](https://www.npmjs.com/package/@noneforge/eslint-config-angular) - Angular application configuration
## Requirements
- Node.js >=18.18.0
- ESLint >=9.22.0
- TypeScript >=5.5.0
## Installation
```bash
npm install --save-dev @noneforge/eslint-config eslint typescript
```
or with Yarn:
```bash
yarn add --dev @noneforge/eslint-config eslint typescript
```
## Usage
Create an `eslint.config.js` file in your project root:
```javascript
import config from '@noneforge/eslint-config';
export default [
...config,
// Your custom rules here
];
```
### With Custom Rules
```javascript
import config from '@noneforge/eslint-config';
export default [
...config,
{
rules: {
// Override or add custom rules
'no-console': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
}
}
];
```
### For Monorepos
```javascript
import config from '@noneforge/eslint-config';
export default [
...config,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
project: ['./packages/*/tsconfig.json'],
}
}
}
];
```
## Rule Categories
### ๐ก๏ธ Core JavaScript Error Prevention
**Essential rules to catch common JavaScript errors:**
- **Syntax and Logic Errors**: `no-dupe-keys`, `no-unreachable`, `no-unsafe-negation`
- **Variable Issues**: `no-undef`, `no-unused-vars` (TypeScript uses `@typescript-eslint/no-unused-vars` with enhanced options), `no-redeclare`
- **Async/Control Flow**: `no-async-promise-executor`, `no-await-in-loop`, `for-direction`
- **Regex Safety**: `no-control-regex`, `no-invalid-regexp`, `no-regex-spaces`
**Enhanced unused variables detection:**
- Variables/args starting with `_` are ignored
- Rest siblings in destructuring are ignored (`const { used, ...rest } = obj`)
- Only checks function arguments after the last used one
- Destructured array elements starting with `_` are ignored
### ๐ฏ TypeScript Type Safety
**Strict type checking for maximum safety:**
- **No Any Policy**: `@typescript-eslint/no-explicit-any`, all `no-unsafe-*` rules
- **Type Assertions**: Enforces consistent assertions, prevents unnecessary type operations
- **Nullish Handling**: `strict-boolean-expressions` with smart nullable object support
- **Promise/Async**: `no-floating-promises`, `no-misused-promises`, `promise-function-async`
- **Type Definitions**: `consistent-type-definitions` is disabled - choose `type` or `interface` based on your needs:
- Use `interface` for: object shapes that can be extended, implements clauses, public APIs
- Use `type` for: unions, intersections, mapped types, tuple types
- Consider `interface extends` over `type &` for better performance
```typescript
// โ Strict boolean expressions prevent errors
if (count) { } // Error: number coercion
if (text) { } // Error: string coercion
// โ
Be explicit
if (count > 0) { }
if (text !== '') { }
if (user) { } // OK: nullable object check
```
### ๐ฆ Import/Export Management
**Automatic import organization:**
- **Sorting**: `simple-import-sort` for consistent ordering
- **Type Imports**: Enforces inline type imports (`import { type User }`)
- **No Side Effects**: Prevents `import type` with side effects
- **Module System**: No `require()` in TypeScript, ESM preferred
```typescript
// โ
Auto-sorted and organized
import { type Config } from './config';
import { type User, type Product } from '@/types';
import { useState } from 'react';
import path from 'node:path';
```
### ๐จ Code Formatting (Prettier Replacement)
**Built-in formatting via @stylistic/eslint-plugin:**
- **Indentation**: 2 spaces, with detailed alignment rules
- **Quotes**: Single quotes with escape avoidance
- **Semicolons**: Always required
- **Line Length**: 120 chars (ignores URLs, strings, templates)
- **Spacing**: Comprehensive rules for consistency
### ๐๏ธ Code Quality & Best Practices
**Modern JavaScript/TypeScript patterns:**
- **ES6+ Features**: `prefer-const`, `no-var`, `prefer-spread`, `prefer-object-has-own`
- **Logical Operators**: `logical-assignment-operators` (use `??=`, `&&=`, `||=`)
- **String Methods**: `prefer-string-starts-ends-with` over regex/indexOf
- **Array Methods**: `prefer-find` over filter[0], `prefer-includes` over indexOf
- **Optional Chaining**: `prefer-optional-chain` over && chains
```typescript
// โ Old patterns
const first = array.filter(x => x.id === id)[0];
if (text.indexOf('prefix') === 0) { }
const value = obj && obj.nested && obj.nested.value;
// โ
Modern patterns
const first = array.find(x => x.id === id);
if (text.startsWith('prefix')) { }
const value = obj?.nested?.value;
```
### ๐ Naming Conventions
**Consistent naming across the codebase:**
- **Variables**: `camelCase`, `PascalCase`, or `UPPER_CASE`
- **Functions**: `camelCase` or `PascalCase`
- **Types/Interfaces**: `PascalCase`
- **Enums**: `PascalCase`
- **Type Parameters**: `PascalCase` (generics)
### ๐ Async/Promise Rules
**Comprehensive async code handling:**
- **Floating Promises**: Must be awaited or explicitly voided
- **Async Functions**: Must return promises (`promise-function-async`)
- **Await Usage**: `require-await` ensures async functions use await
- **Return Await**: Required in try-catch blocks for proper stack traces
```typescript
// โ Common async mistakes
async function bad() {
fetchData(); // floating promise
return await promise; // unnecessary outside try-catch
}
// โ
Proper async handling
async function good() {
await fetchData(); // or void fetchData();
try {
return await promise; // correct in try-catch
} catch (e) {
// handle error
}
}
```
### ๐ JSDoc Documentation
**Smart documentation requirements:**
- **Exported Elements Only**: JSDoc required only for explicitly exported interfaces, types, enums, functions, and arrow functions
- **Library Files**: Stricter requirements for files in `lib/` directories and `public-api.ts` - all public classes, methods, and functions must be documented
- **Alignment**: Enforces consistent JSDoc formatting
- **TypeScript Integration**: Disables type annotations in JSDoc
- **Flexible for Internal Code**: No JSDoc required for non-exported code, keeping internal implementation clean
### ๐งช Test File Rules
**Relaxed rules for test files (`*.spec.ts`, `*.test.ts`):**
- `any` type allowed for test flexibility
- No JSDoc requirements
- Console statements permitted
- Higher callback nesting limit (10 levels)
- Magic numbers allowed
- **No indentation enforcement** (`@stylistic/indent: 'off'`) - flexible formatting for test readability
- **No line length limits** (`@stylistic/max-len: 'off'`) - allows long test descriptions and assertions
- **Floating promises allowed** (`@typescript-eslint/no-floating-promises: 'off'`) - simplified async test scenarios
### ๐ Special File Handling
**Smart detection for different file types:**
- **Config Files** (`*.config.js/ts`): Allows `require()`, relaxed return types
- **Declaration Files** (`*.d.ts`): Minimal rules for ambient types
- **JavaScript Files**: Basic linting without type checking
- **Library Exports** (`lib/**/*.ts`, `public-api.ts`): Stricter JSDoc requirements - all public classes, methods, and functions must be documented for better API documentation
## Additional Examples
### TypeScript Strictness
```typescript
// โ Unnecessary type operations
const value = data as unknown as string; // double assertion
type Same = T extends T ? T : never; // unnecessary constraint
if (typeof x === 'string') {
(x as string).length; // unnecessary assertion after guard
}
// โ
Clean type handling
const value = data as string; // single assertion when needed
type Nullable = T | null; // simple and clear
if (typeof x === 'string') {
x.length; // TypeScript knows the type
}
```
### Template Expressions
```typescript
// โ Restricted template expressions
const msg = `Count: ${someObject}`; // Error: object in template
const id = `ID: ${null}`; // Error: null without handling
// โ
Allowed template usage
const msg = `Count: ${count}`; // numbers allowed
const debug = `Data: ${JSON.stringify(obj)}`; // explicit conversion
const id = `ID: ${userId ?? 'unknown'}`; // null handled
```
### Function Return Types
```typescript
// โ Missing return types
function calculate(a: number, b: number) { // Error: needs return type
return a + b;
}
// โ
Explicit return types (with smart exceptions)
function calculate(a: number, b: number): number {
return a + b;
}
// โ
Exceptions that don't need explicit returns
const add = (a: number, b: number) => a + b; // arrow function expressions
const handler = () => console.log('done'); // void returns
```
## VSCode Integration
Add to `.vscode/settings.json`:
```json
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.experimental.useFlatConfig": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
]
}
```
## Package.json Scripts
```json
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"lint:debug": "eslint . --debug",
"type-check": "tsc --noEmit"
}
}
```
## Migration from ESLint 8
1. Remove `.eslintrc.*` files
2. Create `eslint.config.js` with flat config
3. Update VSCode settings for flat config
4. Remove Prettier (this config handles formatting)
## Performance Tips
- Use `projectService: true` for better TypeScript performance
- Enable ESLint cache: `eslint . --cache`
- Exclude build directories in your tsconfig.json
- Consider using `--max-warnings 0` in CI/CD
## Philosophy
This configuration prioritizes:
1. **Type Safety** - Catch errors at build time, not runtime
2. **Consistency** - Unified formatting without Prettier
3. **Performance** - Optimized for large TypeScript projects
4. **Developer Experience** - Clear errors with practical rules
## License
MIT
## Contributing
Issues and PRs welcome at [GitHub](https://github.com/noneforge/eslint-config)