{"id":31585087,"url":"https://github.com/noneforge/eslint-config","last_synced_at":"2026-05-09T03:32:06.341Z","repository":{"id":313704268,"uuid":"1052319246","full_name":"noneforge/eslint-config","owner":"noneforge","description":"TypeScript/JavaScript ESLint configuration with strict type checking and modern stylistic rules","archived":false,"fork":false,"pushed_at":"2026-01-07T03:55:01.000Z","size":66,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-15T13:49:20.643Z","etag":null,"topics":["code-quality","code-style","eslint","eslint-config","eslint9","eslintconfig","flat-config","javascript","javascript-eslint","lint","noneforge","prettier","stylistic","type-checking","typescript","typescript-eslint"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@noneforge/eslint-config","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/noneforge.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-07T21:04:30.000Z","updated_at":"2026-01-07T03:55:05.000Z","dependencies_parsed_at":"2025-09-08T00:20:40.340Z","dependency_job_id":"f5eecab9-9609-433d-b107-8e039b93d0f4","html_url":"https://github.com/noneforge/eslint-config","commit_stats":null,"previous_names":["noneforge/eslint-config"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/noneforge/eslint-config","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noneforge%2Feslint-config","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noneforge%2Feslint-config/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noneforge%2Feslint-config/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noneforge%2Feslint-config/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/noneforge","download_url":"https://codeload.github.com/noneforge/eslint-config/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noneforge%2Feslint-config/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32805901,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-quality","code-style","eslint","eslint-config","eslint9","eslintconfig","flat-config","javascript","javascript-eslint","lint","noneforge","prettier","stylistic","type-checking","typescript","typescript-eslint"],"created_at":"2025-10-06T01:27:12.965Z","updated_at":"2026-05-09T03:32:06.324Z","avatar_url":"https://github.com/noneforge.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @noneforge/eslint-config\n\nModern TypeScript/JavaScript ESLint configuration with strict type checking and comprehensive stylistic rules. Built for ESLint 9+ flat config with full TypeScript 5.5+ support.\n\n## Features\n\n- ✨ **ESLint 9 Flat Config** - Modern configuration format with better performance\n- 🎯 **Strict Type Checking** - Comprehensive type-aware rules to catch errors at build time\n- 🎨 **Built-in Formatting** - Replaces Prettier with @stylistic/eslint-plugin for unified tooling\n- 🚀 **TypeScript 5.5+ Support** - Leverages latest TypeScript features and optimizations\n- 📦 **Zero Config Philosophy** - Sensible defaults that work out of the box\n- ⚡ **Performance Optimized** - Uses `projectService` for faster type checking\n- 🔧 **Smart File Detection** - Different rules for tests, configs, and type definitions\n\n## Related Packages\n\n- [@noneforge/eslint-config-node](https://www.npmjs.com/package/@noneforge/eslint-config-node) - Node.js backend configuration\n- [@noneforge/eslint-config-angular](https://www.npmjs.com/package/@noneforge/eslint-config-angular) - Angular application configuration\n\n## Requirements\n\n- Node.js \u003e=18.18.0\n- ESLint \u003e=9.22.0\n- TypeScript \u003e=5.5.0\n\n## Installation\n\n```bash\nnpm install --save-dev @noneforge/eslint-config eslint typescript\n```\n\nor with Yarn:\n\n```bash\nyarn add --dev @noneforge/eslint-config eslint typescript\n```\n\n## Usage\n\nCreate an `eslint.config.js` file in your project root:\n\n```javascript\nimport config from '@noneforge/eslint-config';\n\nexport default [\n  ...config,\n  // Your custom rules here\n];\n```\n\n### With Custom Rules\n\n```javascript\nimport config from '@noneforge/eslint-config';\n\nexport default [\n  ...config,\n  {\n    rules: {\n      // Override or add custom rules\n      'no-console': 'off',\n      '@typescript-eslint/no-explicit-any': 'warn',\n    }\n  }\n];\n```\n\n### For Monorepos\n\n```javascript\nimport config from '@noneforge/eslint-config';\n\nexport default [\n  ...config,\n  {\n    languageOptions: {\n      parserOptions: {\n        projectService: true,\n        tsconfigRootDir: import.meta.dirname,\n        project: ['./packages/*/tsconfig.json'],\n      }\n    }\n  }\n];\n```\n\n## Rule Categories\n\n### 🛡️ Core JavaScript Error Prevention\n**Essential rules to catch common JavaScript errors:**\n- **Syntax and Logic Errors**: `no-dupe-keys`, `no-unreachable`, `no-unsafe-negation`\n- **Variable Issues**: `no-undef`, `no-unused-vars` (TypeScript uses `@typescript-eslint/no-unused-vars` with enhanced options), `no-redeclare`\n- **Async/Control Flow**: `no-async-promise-executor`, `no-await-in-loop`, `for-direction`\n- **Regex Safety**: `no-control-regex`, `no-invalid-regexp`, `no-regex-spaces`\n\n**Enhanced unused variables detection:**\n- Variables/args starting with `_` are ignored\n- Rest siblings in destructuring are ignored (`const { used, ...rest } = obj`)\n- Only checks function arguments after the last used one\n- Destructured array elements starting with `_` are ignored\n\n### 🎯 TypeScript Type Safety\n**Strict type checking for maximum safety:**\n- **No Any Policy**: `@typescript-eslint/no-explicit-any`, all `no-unsafe-*` rules\n- **Type Assertions**: Enforces consistent assertions, prevents unnecessary type operations\n- **Nullish Handling**: `strict-boolean-expressions` with smart nullable object support\n- **Promise/Async**: `no-floating-promises`, `no-misused-promises`, `promise-function-async`\n- **Type Definitions**: `consistent-type-definitions` is disabled - choose `type` or `interface` based on your needs:\n  - Use `interface` for: object shapes that can be extended, implements clauses, public APIs\n  - Use `type` for: unions, intersections, mapped types, tuple types\n  - Consider `interface extends` over `type \u0026` for better performance\n\n```typescript\n// ❌ Strict boolean expressions prevent errors\nif (count) { }  // Error: number coercion\nif (text) { }   // Error: string coercion\n\n// ✅ Be explicit\nif (count \u003e 0) { }\nif (text !== '') { }\nif (user) { }  // OK: nullable object check\n```\n\n### 📦 Import/Export Management\n**Automatic import organization:**\n- **Sorting**: `simple-import-sort` for consistent ordering\n- **Type Imports**: Enforces inline type imports (`import { type User }`)\n- **No Side Effects**: Prevents `import type` with side effects\n- **Module System**: No `require()` in TypeScript, ESM preferred\n\n```typescript\n// ✅ Auto-sorted and organized\nimport { type Config } from './config';\nimport { type User, type Product } from '@/types';\nimport { useState } from 'react';\nimport path from 'node:path';\n```\n\n### 🎨 Code Formatting (Prettier Replacement)\n**Built-in formatting via @stylistic/eslint-plugin:**\n- **Indentation**: 2 spaces, with detailed alignment rules\n- **Quotes**: Single quotes with escape avoidance\n- **Semicolons**: Always required\n- **Line Length**: 120 chars (ignores URLs, strings, templates)\n- **Spacing**: Comprehensive rules for consistency\n\n### 🏗️ Code Quality \u0026 Best Practices\n**Modern JavaScript/TypeScript patterns:**\n- **ES6+ Features**: `prefer-const`, `no-var`, `prefer-spread`, `prefer-object-has-own`\n- **Logical Operators**: `logical-assignment-operators` (use `??=`, `\u0026\u0026=`, `||=`)\n- **String Methods**: `prefer-string-starts-ends-with` over regex/indexOf\n- **Array Methods**: `prefer-find` over filter[0], `prefer-includes` over indexOf\n- **Optional Chaining**: `prefer-optional-chain` over \u0026\u0026 chains\n\n```typescript\n// ❌ Old patterns\nconst first = array.filter(x =\u003e x.id === id)[0];\nif (text.indexOf('prefix') === 0) { }\nconst value = obj \u0026\u0026 obj.nested \u0026\u0026 obj.nested.value;\n\n// ✅ Modern patterns\nconst first = array.find(x =\u003e x.id === id);\nif (text.startsWith('prefix')) { }\nconst value = obj?.nested?.value;\n```\n\n### 📝 Naming Conventions\n**Consistent naming across the codebase:**\n- **Variables**: `camelCase`, `PascalCase`, or `UPPER_CASE`\n- **Functions**: `camelCase` or `PascalCase`\n- **Types/Interfaces**: `PascalCase`\n- **Enums**: `PascalCase`\n- **Type Parameters**: `PascalCase` (generics)\n\n### 🔄 Async/Promise Rules\n**Comprehensive async code handling:**\n- **Floating Promises**: Must be awaited or explicitly voided\n- **Async Functions**: Must return promises (`promise-function-async`)\n- **Await Usage**: `require-await` ensures async functions use await\n- **Return Await**: Required in try-catch blocks for proper stack traces\n\n```typescript\n// ❌ Common async mistakes\nasync function bad() {\n  fetchData();  // floating promise\n  return await promise;  // unnecessary outside try-catch\n}\n\n// ✅ Proper async handling\nasync function good() {\n  await fetchData();  // or void fetchData();\n  try {\n    return await promise;  // correct in try-catch\n  } catch (e) {\n    // handle error\n  }\n}\n```\n\n### 📚 JSDoc Documentation\n**Smart documentation requirements:**\n- **Exported Elements Only**: JSDoc required only for explicitly exported interfaces, types, enums, functions, and arrow functions\n- **Library Files**: Stricter requirements for files in `lib/` directories and `public-api.ts` - all public classes, methods, and functions must be documented\n- **Alignment**: Enforces consistent JSDoc formatting\n- **TypeScript Integration**: Disables type annotations in JSDoc\n- **Flexible for Internal Code**: No JSDoc required for non-exported code, keeping internal implementation clean\n\n### 🧪 Test File Rules\n**Relaxed rules for test files (`*.spec.ts`, `*.test.ts`):**\n- `any` type allowed for test flexibility\n- No JSDoc requirements\n- Console statements permitted\n- Higher callback nesting limit (10 levels)\n- Magic numbers allowed\n- **No indentation enforcement** (`@stylistic/indent: 'off'`) - flexible formatting for test readability\n- **No line length limits** (`@stylistic/max-len: 'off'`) - allows long test descriptions and assertions\n- **Floating promises allowed** (`@typescript-eslint/no-floating-promises: 'off'`) - simplified async test scenarios\n\n### 📁 Special File Handling\n**Smart detection for different file types:**\n- **Config Files** (`*.config.js/ts`): Allows `require()`, relaxed return types\n- **Declaration Files** (`*.d.ts`): Minimal rules for ambient types\n- **JavaScript Files**: Basic linting without type checking\n- **Library Exports** (`lib/**/*.ts`, `public-api.ts`): Stricter JSDoc requirements - all public classes, methods, and functions must be documented for better API documentation\n\n## Additional Examples\n\n### TypeScript Strictness\n```typescript\n// ❌ Unnecessary type operations\nconst value = data as unknown as string;  // double assertion\ntype Same\u003cT\u003e = T extends T ? T : never;   // unnecessary constraint\nif (typeof x === 'string') {\n  (x as string).length;  // unnecessary assertion after guard\n}\n\n// ✅ Clean type handling\nconst value = data as string;  // single assertion when needed\ntype Nullable\u003cT\u003e = T | null;   // simple and clear\nif (typeof x === 'string') {\n  x.length;  // TypeScript knows the type\n}\n```\n\n### Template Expressions\n```typescript\n// ❌ Restricted template expressions\nconst msg = `Count: ${someObject}`;  // Error: object in template\nconst id = `ID: ${null}`;  // Error: null without handling\n\n// ✅ Allowed template usage\nconst msg = `Count: ${count}`;  // numbers allowed\nconst debug = `Data: ${JSON.stringify(obj)}`;  // explicit conversion\nconst id = `ID: ${userId ?? 'unknown'}`;  // null handled\n```\n\n### Function Return Types\n```typescript\n// ❌ Missing return types\nfunction calculate(a: number, b: number) {  // Error: needs return type\n  return a + b;\n}\n\n// ✅ Explicit return types (with smart exceptions)\nfunction calculate(a: number, b: number): number {\n  return a + b;\n}\n\n// ✅ Exceptions that don't need explicit returns\nconst add = (a: number, b: number) =\u003e a + b;  // arrow function expressions\nconst handler = () =\u003e console.log('done');  // void returns\n```\n\n## VSCode Integration\n\nAdd to `.vscode/settings.json`:\n\n```json\n{\n  \"editor.codeActionsOnSave\": {\n    \"source.fixAll.eslint\": \"explicit\"\n  },\n  \"eslint.experimental.useFlatConfig\": true,\n  \"eslint.validate\": [\n    \"javascript\",\n    \"javascriptreact\",\n    \"typescript\",\n    \"typescriptreact\"\n  ]\n}\n```\n\n## Package.json Scripts\n\n```json\n{\n  \"scripts\": {\n    \"lint\": \"eslint .\",\n    \"lint:fix\": \"eslint . --fix\",\n    \"lint:debug\": \"eslint . --debug\",\n    \"type-check\": \"tsc --noEmit\"\n  }\n}\n```\n\n## Migration from ESLint 8\n\n1. Remove `.eslintrc.*` files\n2. Create `eslint.config.js` with flat config\n3. Update VSCode settings for flat config\n4. Remove Prettier (this config handles formatting)\n\n## Performance Tips\n\n- Use `projectService: true` for better TypeScript performance\n- Enable ESLint cache: `eslint . --cache`\n- Exclude build directories in your tsconfig.json\n- Consider using `--max-warnings 0` in CI/CD\n\n## Philosophy\n\nThis configuration prioritizes:\n\n1. **Type Safety** - Catch errors at build time, not runtime\n2. **Consistency** - Unified formatting without Prettier\n3. **Performance** - Optimized for large TypeScript projects\n4. **Developer Experience** - Clear errors with practical rules\n\n## License\n\nMIT\n\n## Contributing\n\nIssues and PRs welcome at [GitHub](https://github.com/noneforge/eslint-config)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoneforge%2Feslint-config","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnoneforge%2Feslint-config","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoneforge%2Feslint-config/lists"}