Skip to content

node

npm version License: MIT Node.js ESLint TypeScript

> ESLint configuration for Node.js projects with TypeScript. Extends @jmlweb/eslint-config-base with Node.js-specific rules, globals, and best practices for Node.js development.

  • 🔒 Strict Type Checking: Inherits all strict TypeScript rules from base config
  • 🟢 Node.js Best Practices: Enforces Node.js-specific rules and patterns
  • 🌐 Node.js Globals: Automatically enables Node.js global variables
  • 📦 Import Management: Enforces type-only imports with inline style + automatic sorting
  • 🎯 Code Quality: Prevents common Node.js pitfalls and anti-patterns
  • 🎨 Prettier Integration: Disables all ESLint rules that conflict with Prettier
  • 🚀 Flat Config: Uses ESLint 9+ flat config format (latest stable)
Terminal window
pnpm add -D @jmlweb/eslint-config-node eslint @eslint/js typescript-eslint eslint-config-prettier eslint-plugin-n eslint-plugin-simple-import-sort globals @jmlweb/eslint-config-base

> 💡 Upgrading from a previous version? See the Migration Guide for breaking changes and upgrade instructions.

Create an eslint.config.js file in your project root:

import nodeConfig from '@jmlweb/eslint-config-node';
export default [
...nodeConfig,
// Add your project-specific overrides here
];
eslint.config.js
import nodeConfig from '@jmlweb/eslint-config-node';
export default [...nodeConfig];
eslint.config.js
import nodeConfig from '@jmlweb/eslint-config-node';
export default [
...nodeConfig,
{
files: ['**/*.test.ts', '**/*.spec.ts'],
rules: {
// Allow any in tests
'@typescript-eslint/no-explicit-any': 'off',
// Allow console in tests
'no-console': 'off',
// Relax Node.js rules in tests
'n/no-process-exit': 'off',
},
},
{
ignores: ['dist/', 'build/', 'node_modules/', '*.config.ts'],
},
];
eslint.config.js
import nodeConfig from '@jmlweb/eslint-config-node';
export default [
...nodeConfig,
{
files: ['**/*.ts', '**/*.js'],
rules: {
// Customize Node.js rules
'n/no-process-exit': 'warn', // Warn instead of error
'n/no-deprecated-api': 'error', // Error on deprecated APIs
},
},
];

This configuration applies Node.js-specific rules to:

  • **/*.ts - TypeScript files
  • **/*.js - JavaScript files
  • **/*.mjs - ES modules
  • **/*.cjs - CommonJS files
RuleLevelDescription
n/no-process-exiterrorPrevents direct process.exit() calls
n/no-missing-importerrorPrevents missing imports
n/no-missing-requireerrorPrevents missing require statements
n/no-unpublished-importerrorPrevents importing unpublished packages
n/no-unpublished-requireerrorPrevents requiring unpublished packages
n/no-extraneous-importerrorPrevents extraneous imports
n/no-extraneous-requireerrorPrevents extraneous require statements
n/no-deprecated-apiwarnWarns about deprecated Node.js APIs
n/process-exit-as-throwerrorTreats process.exit as throw
n/no-callback-literalerrorPrevents callback literal patterns
n/no-new-requireerrorPrevents new require()
n/no-path-concaterrorPrevents string concatenation for paths
n/prefer-global/buffererrorPrefers global Buffer
n/prefer-global/consoleerrorPrefers global console
n/prefer-global/processerrorPrefers global process
n/prefer-promises/dnserrorPrefers promise-based DNS APIs
n/prefer-promises/fserrorPrefers promise-based fs APIs
n/prefer-node-protocolerrorPrefers node: protocol for built-in modules
  • ✅ All TypeScript ESLint rules from @jmlweb/eslint-config-base
  • ✅ Node.js recommended rules from eslint-plugin-n
  • ✅ Node.js globals automatically enabled
  • ✅ Node.js best practices and anti-pattern prevention
  • ✅ Automatic import/export sorting
  • ✅ Prettier conflict resolution

The configuration automatically sorts imports and enforces type-only imports:

Before:

import { Component } from './component';
import fs from 'fs';
import type { User } from './types';
import express from 'express';

After auto-fix:

import fs from 'fs';
import express from 'express';
import type { User } from './types';
import { Component } from './component';

Fix import order automatically:

Terminal window
pnpm exec eslint --fix .

> Philosophy: Node.js applications should follow Node.js best practices and leverage the platform’s capabilities correctly.

This package extends the base TypeScript config with Node.js-specific rules that prevent common Node.js pitfalls, enforce best practices for the platform, and provide proper global variable handling for the Node.js runtime.

Node.js Plugin (eslint-plugin-n): Enforces Node.js best practices and catches platform-specific issues

  • Why: Node.js has unique patterns (async I/O, modules, process management) that require specific rules. The plugin catches deprecated APIs, improper module usage, and process handling issues
  • Trade-off: Additional rules to learn, but prevents Node.js-specific bugs
  • When to override: When you know you’re using a pattern correctly despite the warning (rare)

Node.js Globals: Automatically includes Node.js global variables (process, __dirname, Buffer, etc.)

  • Why: Node.js applications need access to platform globals. Explicitly declaring them prevents “undefined variable” errors
  • Trade-off: None - this is required for Node.js development
  • When to override: Never - Node.js code needs these globals

Extends Base TypeScript Config: Inherits all strict type checking rules

  • Why: Node.js applications benefit from strict typing, especially for API contracts, database models, and configuration
  • Trade-off: More verbose code, but prevents runtime errors in production
  • When to override: Follow the same guidelines as the base TypeScript config

Use this configuration when you want:

  • ✅ Node.js library or application development with TypeScript
  • ✅ Maximum type safety with Node.js
  • ✅ Strict code quality standards for Node.js code
  • ✅ Consistent Node.js patterns across the team
  • ✅ Prevention of common Node.js pitfalls
  • ✅ Best practices enforcement for Node.js APIs

For non-Node.js TypeScript projects, use @jmlweb/eslint-config-base instead.

For JavaScript-only Node.js projects, you can extend @jmlweb/eslint-config-base-js and add Node.js plugins manually.

You can extend or override the configuration for your specific needs:

import nodeConfig from '@jmlweb/eslint-config-node';
export default [
...nodeConfig,
{
files: ['**/*.test.ts', '**/*.spec.ts'],
rules: {
// Test-specific rules
'@typescript-eslint/no-explicit-any': 'off',
'n/no-process-exit': 'off',
},
},
{
ignores: ['dist/', 'build/', 'node_modules/'],
},
];

Add linting scripts to your package.json:

{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix"
}
}

Then run:

Terminal window
pnpm lint # Lint all files
pnpm lint:fix # Fix auto-fixable issues
  • Node.js >= 20.11.0 (required for import.meta.dirname in config files)
  • ESLint >= 9.0.0 (flat config format)
  • TypeScript project with tsconfig.json
  • TypeScript project service enabled (automatic with this config)

This package requires the following peer dependencies:

  • eslint (^9.0.0)
  • @eslint/js (^9.0.0)
  • typescript-eslint (^8.0.0)
  • eslint-config-prettier (^9.1.0)
  • eslint-plugin-n (^0.4.0)
  • eslint-plugin-simple-import-sort (^12.0.0)
  • globals (^15.0.0)
  • @jmlweb/eslint-config-base (^1.0.0)

See real-world usage examples:

  • ESLint - Pluggable linting utility for JavaScript and TypeScript
  • Node.js - JavaScript runtime built on Chrome’s V8 engine
  • eslint-plugin-n - ESLint rules for Node.js
  • tsx - TypeScript execute (ts-node alternative)

> Note: If no breaking changes were introduced in a version, it’s safe to upgrade without additional steps.

No breaking changes have been introduced yet. This package follows semantic versioning. When breaking changes are introduced, detailed migration instructions will be provided here.

For version history, see the Changelog.

Need Help? If you encounter issues during migration, please open an issue.

See CHANGELOG.md for version history and release notes.

MIT