https://github.com/stackvault/eslint-config-node
Node.js ESLint configuration with TypeScript
https://github.com/stackvault/eslint-config-node
api backend eslint eslint-config eslint-plugin-n eslint-plugin-security eslint9 eslintconfig flat-config node nodejs security server stackvault typescript
Last synced: about 1 month ago
JSON representation
Node.js ESLint configuration with TypeScript
- Host: GitHub
- URL: https://github.com/stackvault/eslint-config-node
- Owner: stackvault
- License: mit
- Created: 2025-09-06T10:55:27.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-09-06T12:24:46.000Z (9 months ago)
- Last Synced: 2025-09-23T00:11:28.522Z (9 months ago)
- Topics: api, backend, eslint, eslint-config, eslint-plugin-n, eslint-plugin-security, eslint9, eslintconfig, flat-config, node, nodejs, security, server, stackvault, typescript
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/@stackvault/eslint-config-node
- 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
# @stackvault/eslint-config-node
Production-ready Node.js ESLint configuration with TypeScript, security rules, and performance optimizations. Built on top of [@stackvault/eslint-config-typescript](https://www.npmjs.com/package/@stackvault/eslint-config-typescript) with Node.js-specific enhancements for backend development.
## Features
- 🛡️ **Security First** - Built-in security scanning with eslint-plugin-security
- 🚀 **Node.js 20+ Optimized** - Leverages modern Node.js APIs and patterns
- 📦 **TypeScript Foundation** - Inherits all strict type checking from base config
- ⚡ **Performance Rules** - Enforces async patterns and non-blocking operations
- 🔒 **Promise Safety** - Comprehensive promise and async/await validation
- 🎯 **Modern Patterns** - Prefers native Node.js APIs and ES2021+ features
## Installation
```bash
npm install --save-dev @stackvault/eslint-config-node eslint typescript
```
or with Yarn:
```bash
yarn add --dev @stackvault/eslint-config-node eslint typescript
```
## Requirements
- Node.js >=20.0.0 (LTS)
- ESLint >=9.22.0
- TypeScript >=5.5.0
## Usage
Create an `eslint.config.js` file in your project root:
```javascript
import nodeConfig from '@stackvault/eslint-config-node';
export default [
...nodeConfig,
// Your custom rules here
];
```
### With Custom Rules
```javascript
import nodeConfig from '@stackvault/eslint-config-node';
export default [
...nodeConfig,
{
rules: {
// Override for your specific needs
'n/no-process-env': 'off', // If you need direct process.env access
'security/detect-object-injection': 'off', // If too many false positives
}
}
];
```
### For Microservices
```javascript
import nodeConfig from '@stackvault/eslint-config-node';
export default [
...nodeConfig,
{
rules: {
'n/no-process-exit': 'off', // Allow process.exit for containers
'n/no-sync': 'off', // Allow sync operations at startup
}
}
];
```
## What's Included
### Inherited from TypeScript Config
This configuration extends [@stackvault/eslint-config-typescript](https://www.npmjs.com/package/@stackvault/eslint-config-typescript), providing:
- **Strict type checking** with type-aware rules
- **Built-in formatting** via @stylistic/eslint-plugin (no Prettier needed)
- **Import sorting** and organization
- **Consistent code patterns** and naming conventions
### Security Rules
Comprehensive security scanning to prevent common vulnerabilities:
- **Path traversal protection** - Detects non-literal fs operations
- **Command injection prevention** - Flags dangerous child_process usage
- **RegExp DoS protection** - Identifies unsafe regular expressions
- **Timing attack warnings** - Alerts on potential timing vulnerabilities
- **Buffer safety** - Ensures secure buffer operations
### Node.js Best Practices
Modern Node.js patterns enforced via eslint-plugin-n:
- **Node: protocol imports** - Requires `node:fs` instead of `fs`
- **Promise-based APIs** - Prefers `fs.promises` over callbacks
- **Version compatibility** - Ensures Node.js 20+ API usage
- **Global preferences** - Enforces global Buffer, process, console
- **No blocking operations** - Prevents synchronous I/O in async contexts
### Promise & Async Handling
Enhanced async operation rules via eslint-plugin-promise:
- **Proper error handling** - Enforces catch or return for promises
- **Async/await patterns** - Prefers modern async over callbacks
- **Promise chain safety** - Prevents common promise anti-patterns
- **No floating promises** - Ensures all promises are handled
### Modern JavaScript Patterns
Selected Unicorn rules for cleaner code:
- **Modern APIs** - `.at()`, `.replaceAll()`, structured clone
- **Top-level await** - For ES modules
- **Prefer for...of** - Over forEach for better performance
- **Optional catch binding** - Cleaner error handling
- **Native fetch** - Uses Node.js built-in fetch
## Key Rules Explained
### Security Patterns
```typescript
// ❌ Error: detect-non-literal-fs-filename
const file = userInput;
fs.readFile(file, callback);
// ✅ Correct: Validate and sanitize paths
import path from 'node:path';
const safePath = path.join(SAFE_DIR, path.basename(userInput));
fs.readFile(safePath, callback);
```
### Node.js Protocol Imports
```typescript
// ❌ Error: prefer-node-protocol
import fs from 'fs';
import { readFile } from 'fs/promises';
// ✅ Correct: Use node: protocol
import fs from 'node:fs';
import { readFile } from 'node:fs/promises';
```
### Async File Operations
```typescript
// ❌ Error: no-sync
const data = fs.readFileSync('config.json');
// ✅ Correct: Use async operations
const data = await fs.promises.readFile('config.json');
```
### Promise Handling
```typescript
// ❌ Error: no-floating-promises
async function processData() {
saveToDatabase(data); // Floating promise
}
// ✅ Correct: Handle the promise
async function processData() {
await saveToDatabase(data);
// or
void saveToDatabase(data); // Explicitly ignore
}
```
## Special File Handling
### Configuration Files
Relaxed rules for `*.config.js` and `*.config.ts`:
- Sync operations allowed
- Environment variables permitted
- Dynamic requires allowed
### Test Files
Relaxed security and type checking for `*.spec.ts` and `*.test.ts`:
- Unpublished imports allowed (for test libraries)
- Object injection warnings disabled
- Any types permitted for mocking
### Migration Scripts
Special rules for `scripts/` and `migrations/` directories:
- Console logging allowed
- Process.exit permitted
- File system warnings reduced
## VSCode Integration
Add to `.vscode/settings.json`:
```json
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"eslint.experimental.useFlatConfig": true,
"eslint.validate": [
"javascript",
"typescript"
]
}
```
## Package.json Scripts
```json
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"lint:ci": "eslint . --max-warnings 0",
"lint:security": "eslint . --rule 'security/*: error'",
"type-check": "tsc --noEmit"
}
}
```
## Environment Variables
For projects using environment variables:
```typescript
// Create a typed env.ts file
const env = {
PORT: process.env.PORT || '3000',
NODE_ENV: process.env.NODE_ENV || 'development',
DATABASE_URL: process.env.DATABASE_URL!,
} as const;
export default env;
```
This pattern provides type safety while satisfying linter rules.
## Performance Tips
- Enable ESLint cache: `eslint . --cache`
- Use `--max-warnings 0` in CI/CD pipelines
- Consider disabling expensive rules in development:
```javascript
const isDev = process.env.NODE_ENV === 'development';
export default [
...nodeConfig,
{
rules: {
'security/detect-object-injection': isDev ? 'off' : 'warn',
}
}
];
```
## Common Patterns
### Error Handling
```typescript
// Recommended error class
class AppError extends Error {
constructor(
message: string,
public statusCode: number = 500,
public isOperational = true
) {
super(message);
Error.captureStackTrace(this, this.constructor);
}
}
```
### Async Middleware
```typescript
// Express async handler wrapper
const asyncHandler = (fn: RequestHandler): RequestHandler => {
return (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
};
```
## Migration from ESLint 8
1. Remove `.eslintrc.*` files
2. Create `eslint.config.js` with flat config
3. Update to Node.js 20+ for full feature support
4. Replace `eslint-plugin-node` with `eslint-plugin-n`
5. Update scripts to use flat config
## Philosophy
This configuration prioritizes:
1. **Security** - Prevent vulnerabilities before they reach production
2. **Performance** - Non-blocking operations and modern APIs
3. **Type Safety** - Full TypeScript benefits for backend code
4. **Modern Patterns** - Leverage Node.js 20+ capabilities
5. **Developer Experience** - Clear errors with actionable fixes
## License
MIT
## Contributing
Issues and PRs welcome at [GitHub](https://github.com/stackvault/eslint-config-node)