@reasonabletech/eslint-config 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,9 +1,36 @@
1
1
  # @reasonabletech/eslint-config
2
2
 
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - - Automated release.
8
+
9
+ ## 0.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`f862453`](https://github.com/ReasonableTech/core-utils/commit/f86245352ba4ef8df56a124c8f17bf8605ac9085) Thanks [@WillieCubed](https://github.com/WillieCubed)! - Audit and fix custom ESLint rules for correctness, false-positive reduction, and API consistency.
14
+
15
+ #### Breaking changes — action required
16
+ - `no-linter-disabling` is deprecated and no longer enabled by default. If you relied on it, use ESLint's built-in `reportUnusedDisableDirectives` option and the native `-- reason` inline syntax instead. The rule remains in the plugin if you need to opt in explicitly.
17
+ - `no-dependency-bundling` no longer flags interfaces based on property types. Only interfaces and type aliases named `*Dependencies` or `*Deps` are flagged. If you had false-positive suppressions for domain models, you can remove them.
18
+ - `createTerminologyRules()` no longer includes default forbidden terms. Pass `forbiddenTerms` explicitly: `createTerminologyRules({ forbiddenTerms: { toolCall: "action" } })`.
19
+ - `createBarrelExportRules()` and `createCodeQualityRules()` no longer accept options (the parameters were no-ops). Remove any arguments at the call site.
20
+ - `createResultTypeRules()` has been removed (it returned an empty object). Remove any imports.
21
+
22
+ #### New rule
23
+ - `no-constructor-instantiation` replaces the previous `no-restricted-syntax` selector that flagged all `new PascalCase()` calls in constructors. The new rule allows built-in constructors (`Map`, `Date`, `Set`, etc.) and default parameter values (`db: Database = new Database()`). No config changes needed — `createDependencyInjectionRules()` uses it automatically.
24
+
25
+ #### Bug fixes
26
+ - `no-error-message-parsing` now correctly detects `/regex/.test(error.message)` patterns (previously only caught `error.message.test()`, which nobody writes).
27
+ - `mergeRuleConfigurations` no longer silently escalates `"warn"` severity to `"error"` when merging `no-restricted-syntax` patterns.
28
+ - `no-null-undefined-checks` error message now provides actionable guidance on simplifying `T | null | undefined` types.
29
+
3
30
  ## [Unreleased]
4
31
 
5
32
  Initial release preparation. See [README.md](./README.md) for usage.
6
33
 
7
34
  ---
8
35
 
9
- *Changelog entries are automatically generated from [changesets](https://github.com/changesets/changesets) on release.*
36
+ _Changelog entries are automatically generated from [changesets](https://github.com/changesets/changesets) on release._
@@ -0,0 +1,268 @@
1
+ # AI Code Safety Through Strict Linting
2
+
3
+ ## Philosophy
4
+
5
+ The the codebase is predominantly AI-generated, which presents unique challenges and opportunities for code quality management. Our ESLint configuration is designed with this reality in mind, emphasizing strict rules that force both human developers and AI tools to produce safer, more maintainable code.
6
+
7
+ ## Core Principles
8
+
9
+ ### 1. **Strict Rules, No Warnings**
10
+
11
+ We have a zero-tolerance policy for ESLint warnings in our codebase:
12
+
13
+ - **All rules are set to `"error"`** - no warnings that can be ignored
14
+ - **Builds fail on any linting violation** - forcing immediate resolution
15
+ - **No `eslint-disable` comments** - rules must be followed, not bypassed
16
+
17
+ **Rationale**: Warnings are too easy to ignore. In a large codebase with frequent AI-generated changes, deferred issues accumulate quickly and become technical debt.
18
+
19
+ ### 2. **"Rip the Band-Aid Off Early"**
20
+
21
+ Issues are caught and resolved immediately during development, not during code review:
22
+
23
+ - **Fail fast development cycles** - problems surface during writing, not review
24
+ - **Reduced cognitive load** - developers focus on logic, not style cleanup
25
+ - **Consistent quality gates** - every commit meets the same high standards
26
+
27
+ ### 3. **Type Safety is Non-Negotiable**
28
+
29
+ Type-aware ESLint rules are mandatory across all projects:
30
+
31
+ ```typescript
32
+ // Canonical setup (required)
33
+ import { createTypeAwareConfig } from "@reasonabletech/eslint-config";
34
+ export default createTypeAwareConfig(import.meta.dirname);
35
+ ```
36
+
37
+ **Why type-aware rules matter**:
38
+
39
+ - Catch more runtime errors during development
40
+ - Force explicit type annotations that improve readability
41
+ - Prevent common AI-generated code issues (implicit any, unsafe assignments)
42
+ - Enable better IDE support and refactoring safety
43
+
44
+ ### 4. **Explicit Behavior Over Implicit**
45
+
46
+ We prefer explicit code patterns that make intent clear:
47
+
48
+ ```typescript
49
+ // ❌ Implicit, unclear behavior
50
+ if (process.env.DATABASE_URL) {
51
+ connect(process.env.DATABASE_URL);
52
+ }
53
+
54
+ // ✅ Explicit, safe behavior
55
+ const config = getEnvironmentConfig();
56
+ if (config.database.url) {
57
+ connect(config.database.url);
58
+ }
59
+ ```
60
+
61
+ ### 5. **Avoid Silent Errors**
62
+
63
+ Code should fail loudly and predictably rather than silently producing incorrect results:
64
+
65
+ ```typescript
66
+ // ❌ Silent failure potential
67
+ const result = data?.user?.profile?.name || "Unknown";
68
+
69
+ // ✅ Explicit error handling
70
+ const result = getUserProfile(data);
71
+ if (!result.success) {
72
+ logger.error("Failed to get user profile", { error: result.error });
73
+ return { success: false, error: "Profile unavailable" };
74
+ }
75
+ ```
76
+
77
+ ## Type Safety Requirements
78
+
79
+ ### Strict Null/Undefined Handling
80
+
81
+ We minimize nullable types and prefer explicit error handling:
82
+
83
+ ```typescript
84
+ // ❌ Nullable return types
85
+ function getUser(id: string): User | null {
86
+ // Silent failure case
87
+ }
88
+
89
+ // ✅ Result types for explicit error handling
90
+ function getUser(id: string): Result<User, "not_found" | "database_error"> {
91
+ try {
92
+ const user = database.findUser(id);
93
+ if (!user) {
94
+ return { success: false, error: "not_found" };
95
+ }
96
+ return { success: true, data: user };
97
+ } catch (error) {
98
+ return { success: false, error: "database_error" };
99
+ }
100
+ }
101
+ ```
102
+
103
+ ### Environment Variable Safety
104
+
105
+ Raw `process.env` access is discouraged. Use configuration wrappers:
106
+
107
+ ```typescript
108
+ // ❌ Direct environment access
109
+ if (process.env.NODE_ENV === "production") {
110
+ // Complex conditional logic
111
+ }
112
+
113
+ // ✅ Wrapped configuration
114
+ const config = getEnvironmentConfig();
115
+ if (config.isProduction) {
116
+ // Clear intent
117
+ }
118
+ ```
119
+
120
+ ### Result Types for Domain Logic
121
+
122
+ Use `Result<T, E>` from `@reasonabletech/utils/result` for operations that can fail:
123
+
124
+ ```typescript
125
+ import type { Result } from "@reasonabletech/utils/result";
126
+
127
+ // Domain operations that can fail should return Results
128
+ async function processPayment(
129
+ amount: number,
130
+ ): Promise<Result<PaymentConfirmation, PaymentError>> {
131
+ // Implementation with explicit error cases
132
+ }
133
+
134
+ // Consumers handle all cases explicitly
135
+ const result = await processPayment(100);
136
+ if (result.success) {
137
+ console.log("Payment processed:", result.data);
138
+ } else {
139
+ handlePaymentError(result.error);
140
+ }
141
+ ```
142
+
143
+ ## AI-Specific Benefits
144
+
145
+ ### 1. **Forces Better AI Output**
146
+
147
+ Strict linting rules compel AI tools to generate higher-quality code:
148
+
149
+ - **Type annotations**: AI must provide explicit return types
150
+ - **Error handling**: AI cannot ignore potential failure cases
151
+ - **Null safety**: AI must handle undefined/null cases explicitly
152
+
153
+ ### 2. **Prevents Common AI Mistakes**
154
+
155
+ - **Unused variables**: AI often generates variables it doesn't use
156
+ - **Unsafe type assertions**: AI may use `any` types inappropriately
157
+ - **Missing await**: AI sometimes forgets async/await patterns
158
+ - **Template literal safety**: AI must handle potentially undefined values in strings
159
+
160
+ ### 3. **Consistent Code Patterns**
161
+
162
+ AI learns to follow consistent patterns across the codebase:
163
+
164
+ - Result types for error handling
165
+ - Explicit type annotations
166
+ - Safe environment variable access
167
+ - Structured logging with context
168
+
169
+ ## Configuration Details
170
+
171
+ ### Key Strict Rules
172
+
173
+ ```typescript
174
+ {
175
+ // Type safety (errors, not warnings)
176
+ "@typescript-eslint/explicit-function-return-type": "error",
177
+ "@typescript-eslint/no-explicit-any": "error",
178
+ "@typescript-eslint/strict-boolean-expressions": "error",
179
+ "@typescript-eslint/prefer-nullish-coalescing": "error",
180
+ "@typescript-eslint/no-non-null-assertion": "error",
181
+
182
+ // Runtime safety
183
+ "@typescript-eslint/no-floating-promises": "error",
184
+ "@typescript-eslint/no-misused-promises": "error",
185
+ "@typescript-eslint/await-thenable": "error",
186
+
187
+ // Code quality
188
+ "@typescript-eslint/no-unused-vars": "error",
189
+ "prefer-const": "error",
190
+ "no-throw-literal": "error"
191
+ }
192
+ ```
193
+
194
+ ### Non-Null Assertion Safety
195
+
196
+ The non-null assertion operator (`!`) is disabled because it completely bypasses TypeScript's null safety checks, potentially causing runtime crashes:
197
+
198
+ ```typescript
199
+ // ❌ Dangerous - bypasses type safety
200
+ const token = createAuthToken(user!.id, user!.email);
201
+ const result = dangerousFunction()!.someProperty;
202
+
203
+ // ✅ Safe alternatives - explicit null checking
204
+ if (!user) {
205
+ throw new Error("User is required");
206
+ }
207
+ const token = createAuthToken(user.id, user.email);
208
+
209
+ // ✅ Safe alternatives - optional chaining with defaults
210
+ const token = user?.id ? createAuthToken(user.id, user.email) : null;
211
+
212
+ // ✅ Safe alternatives - type guards
213
+ function isValidUser(user: User | null): user is User {
214
+ return user !== null && user.id !== undefined;
215
+ }
216
+
217
+ if (isValidUser(user)) {
218
+ const token = createAuthToken(user.id, user.email);
219
+ }
220
+ ```
221
+
222
+ **Why this matters for AI-generated code**: AI tools often use non-null assertions as shortcuts when they encounter nullable types. By disabling this feature, we force AI to implement proper null checking, leading to more robust code that handles edge cases explicitly.
223
+
224
+ ### Canonical Setup Pattern
225
+
226
+ All projects should use one of the package configuration factories:
227
+
228
+ ```typescript
229
+ import { createTypeAwareConfig } from "@reasonabletech/eslint-config";
230
+
231
+ export default createTypeAwareConfig(import.meta.dirname);
232
+ ```
233
+
234
+ ## Benefits
235
+
236
+ ### For Human Developers
237
+
238
+ - **Immediate feedback** on code quality issues
239
+ - **Consistent standards** across the entire codebase
240
+ - **Reduced review overhead** - linting catches issues before review
241
+ - **Better IDE support** with comprehensive type information
242
+
243
+ ### For AI-Generated Code
244
+
245
+ - **Higher quality output** - AI tools adapt to strict requirements
246
+ - **Consistent patterns** - AI learns project conventions
247
+ - **Fewer runtime errors** - type-aware rules catch more issues
248
+ - **Explicit error handling** - AI is forced to handle edge cases
249
+
250
+ ### for the Codebase
251
+
252
+ - **Predictable builds** - all code meets the same quality bar
253
+ - **Reduced technical debt** - issues are resolved immediately
254
+ - **Better maintainability** - explicit patterns are easier to understand
255
+ - **Safer refactoring** - comprehensive type information enables confident changes
256
+
257
+ ## Conclusion
258
+
259
+ Our strict ESLint configuration is not about making development harder—it's about making development **safer** and more **predictable** in an AI-first codebase. By enforcing high standards immediately, we ensure that both human and AI contributors produce code that is reliable, maintainable, and explicit in its intent.
260
+
261
+ The investment in strict linting pays dividends in reduced debugging time, fewer production issues, and a codebase that remains comprehensible as it scales.
262
+
263
+ ## Related Documentation
264
+
265
+ - [Architecture](./architecture.md) — Package design principles and configuration composition
266
+ - [API Reference](../reference/api-reference.md) — All exported functions and plugin rules
267
+ - [Usage Guide](../guides/usage-guide.md) — Setup instructions and troubleshooting
268
+ - [Custom Rules](../../src/custom-rules/README.md) — Rule catalog and contributing guide
@@ -0,0 +1,394 @@
1
+ # Architecture
2
+
3
+ This document outlines the architectural design and principles behind `@reasonabletech/eslint-config`, explaining the decisions made to create a maintainable, modular, and consistent ESLint configuration system for the monorepo.
4
+
5
+ ## Design Principles
6
+
7
+ ### 1. Type-Aware First
8
+
9
+ **Principle:** All configurations prioritize TypeScript type-aware rules as the primary approach.
10
+
11
+ **Rationale:** AI-generated code requires comprehensive static analysis to catch subtle runtime errors that syntax-only rules would miss. Type-aware rules leverage TypeScript's type system to detect:
12
+
13
+ - Unsafe type operations
14
+ - Floating promises
15
+ - Incorrect async/await usage
16
+ - Type assertion issues
17
+ - Boolean expression strictness
18
+
19
+ **Implementation:** The `createTypeAwareConfig()` function is the primary export for all greenfield TypeScript projects.
20
+
21
+ ### 2. Modular Composition
22
+
23
+ **Principle:** All configurations are built from composable, shared modules to eliminate duplication.
24
+
25
+ **Rationale:** The original monolithic configuration contained 400+ lines with massive duplication across base, type-aware, React, and Next.js configurations. This led to:
26
+
27
+ - Maintenance overhead when updating rules
28
+ - Inconsistencies between configurations
29
+ - Difficulty understanding rule origins
30
+ - Code bloat
31
+
32
+ **Architecture:**
33
+
34
+ ```
35
+ src/
36
+ ├── index.ts # Base TypeScript configuration
37
+ ├── react.ts # React configuration entry point
38
+ ├── next.ts # Next.js configuration entry point
39
+ ├── base-configs.ts # Core TypeScript configuration logic
40
+ ├── react/ # React-specific modules
41
+ │ ├── config.ts # React configuration builder
42
+ │ ├── plugins.ts # React plugin setups
43
+ │ └── rules.ts # React rule definitions
44
+ ├── next/ # Next.js-specific modules
45
+ │ ├── config.ts # Next.js configuration builder
46
+ │ ├── ignores.ts # File ignore patterns
47
+ │ ├── plugins.ts # Plugin loading and fallbacks
48
+ │ ├── rules.ts # Rule configurations
49
+ │ └── settings.ts # Plugin settings
50
+ ├── shared/ # Shared utilities
51
+ │ └── react-rules.ts # Common React rules for both React and Next.js
52
+ ├── shared-ignores.ts # Centralized ignore patterns
53
+ └── shared-rules.ts # Shared TypeScript rule sets
54
+ ```
55
+
56
+ ### 3. Explicit Over Implicit
57
+
58
+ **Principle:** All rules and patterns are explicitly defined rather than relying on defaults.
59
+
60
+ **Rationale:** AI-generated code analysis requires predictable, explicit rule sets. Implicit defaults can lead to:
61
+
62
+ - Inconsistent behavior across projects
63
+ - Difficulty debugging rule conflicts
64
+ - Unclear rule inheritance chains
65
+
66
+ **Implementation:** Each rule is explicitly set with clear documentation of its purpose and behavior.
67
+
68
+ ### 4. Framework-Specific Customization
69
+
70
+ **Principle:** Framework configurations extend the base rather than replacing it entirely.
71
+
72
+ **Rationale:** Frameworks like React and Next.js have specific patterns that conflict with strict TypeScript rules, but they should still maintain the core safety guarantees.
73
+
74
+ **Implementation:** Framework overrides are isolated in separate rule sets that can be composed with the base configuration.
75
+
76
+ ## Package Structure
77
+
78
+ ### Core Components
79
+
80
+ #### 1. Shared Ignore Patterns (`src/shared-ignores.ts`)
81
+
82
+ **Purpose:** Centralized file exclusion patterns for all project types.
83
+
84
+ **Categories:**
85
+
86
+ - Build outputs (`dist/`, `build/`, `.next/`)
87
+ - Dependencies (`node_modules/`, `.pnp.*`)
88
+ - Generated files (`*.d.ts`, `*.generated.*`)
89
+ - Development tooling (`scripts/`, config files)
90
+ - Test infrastructure and coverage
91
+ - IDE and OS-specific files
92
+
93
+ **Design Decision:** Single array with comprehensive patterns rather than categorized objects to maintain ESLint compatibility and simplicity.
94
+
95
+ #### 2. Modular Rule Organization
96
+
97
+ **Purpose:** Framework-specific rule modules that eliminate duplication.
98
+
99
+ **React Module (`src/react/`):**
100
+
101
+ - `rules.ts`: React-specific rule definitions using shared React rules
102
+ - `plugins.ts`: React and React Hooks plugin configurations
103
+ - `config.ts`: Complete React configuration builder
104
+
105
+ **Next.js Module (`src/next/`):**
106
+
107
+ - `rules.ts`: Next.js rule definitions with React rule inheritance
108
+ - `plugins.ts`: Plugin loading with graceful fallbacks
109
+ - `ignores.ts`: Next.js-specific file ignore patterns
110
+ - `settings.ts`: Plugin settings for React and Next.js
111
+ - `config.ts`: Complete Next.js configuration orchestrator
112
+
113
+ **Shared Module (`src/shared/`):**
114
+
115
+ - `react-rules.ts`: Common React rules shared between React and Next.js configs
116
+
117
+ **Design Decision:** Focused modules with single responsibilities rather than monolithic rule objects to improve maintainability and enable better code organization.
118
+
119
+ #### 3. Base Configuration Builders (`src/base-configs.ts`)
120
+
121
+ **Purpose:** Factory functions that compose shared components into complete configurations.
122
+
123
+ **Functions:**
124
+
125
+ - `createTypeAwareBaseConfig()`: Type-aware foundation
126
+
127
+ **Design Decision:** Factory functions rather than static objects to enable parameterization (project directory) and better TypeScript integration.
128
+
129
+ ### Framework Configurations
130
+
131
+ #### React Configuration (`react.ts`)
132
+
133
+ **Extends:** Base configuration + React-specific rules
134
+
135
+ **Additions:**
136
+
137
+ - React Hooks plugin with recommended rules
138
+ - JSX transform compatibility (no React import required)
139
+ - Browser and service worker globals
140
+ - Relaxed parameter typing for component props
141
+
142
+ **Design Decision:** Separate file to enable selective imports and clear framework boundaries.
143
+
144
+ #### Next.js Configuration (`next.ts`)
145
+
146
+ **Extends:** Base configuration + React rules + Next.js-specific rules
147
+
148
+ **Additions:**
149
+
150
+ - Next.js Core Web Vitals rules via FlatCompat
151
+ - Server action support (allows async without explicit await)
152
+ - Service worker globals for PWA features
153
+
154
+ **Design Decision:** Uses FlatCompat for Next.js integration to maintain compatibility with Next.js's ESLint plugin ecosystem.
155
+
156
+ ## Architectural Patterns
157
+
158
+ ### 1. Composition Over Inheritance
159
+
160
+ The package uses functional composition rather than class inheritance:
161
+
162
+ ```typescript
163
+ // ✅ Composition approach
164
+ const config = [
165
+ ...createTypeAwareBaseConfig(projectDir),
166
+ reactPlugin.configs.flat.recommended,
167
+ { rules: reactRuleOverrides },
168
+ ];
169
+
170
+ // ❌ Inheritance approach (avoided)
171
+ class ReactConfig extends BaseConfig {
172
+ // Complex inheritance chain
173
+ }
174
+ ```
175
+
176
+ **Benefits:**
177
+
178
+ - Clear data flow and dependencies
179
+ - Easy to understand rule sources
180
+ - No hidden inheritance behavior
181
+ - Better TypeScript inference
182
+
183
+ ### 2. Configuration as Data
184
+
185
+ All configurations are plain JavaScript objects/arrays rather than classes:
186
+
187
+ ```typescript
188
+ // ✅ Data-driven approach
189
+ export const baseRules: Linter.RulesRecord = {
190
+ "no-throw-literal": "error",
191
+ // ...
192
+ };
193
+
194
+ // ❌ Class-based approach (avoided)
195
+ class RuleManager {
196
+ getRules() {
197
+ /* complex logic */
198
+ }
199
+ }
200
+ ```
201
+
202
+ **Benefits:**
203
+
204
+ - Serializable and inspectable
205
+ - No runtime dependencies
206
+ - Easy to merge and extend
207
+ - Compatible with ESLint's flat config system
208
+
209
+ ### 3. Explicit Dependencies
210
+
211
+ All imports are explicit and traceable:
212
+
213
+ ```typescript
214
+ // ✅ Explicit imports
215
+ import { sharedIgnores } from "./shared-ignores.js";
216
+ import { baseRules, typeAwareRules } from "./shared-rules.js";
217
+
218
+ // ❌ Implicit dependencies (avoided)
219
+ import * as config from "./monolithic-config.js";
220
+ ```
221
+
222
+ **Benefits:**
223
+
224
+ - Clear dependency relationships
225
+ - Better tree-shaking
226
+ - Easier refactoring
227
+ - Explicit API boundaries
228
+
229
+ ## Rule Philosophy
230
+
231
+ ### Error Handling Standards
232
+
233
+ **Principle:** Never parse error messages; always use structured error detection.
234
+
235
+ **Implementation:**
236
+
237
+ ```typescript
238
+ "no-throw-literal": "error",
239
+ "prefer-promise-reject-errors": "error",
240
+ "@typescript-eslint/only-throw-error": "error",
241
+ ```
242
+
243
+ **Rationale:** AI-generated code often includes error handling patterns. Parsing error messages leads to brittle code that breaks when error messages change.
244
+
245
+ ### TypeScript Safety
246
+
247
+ **Principle:** Maximize type safety while maintaining practical development experience.
248
+
249
+ **Implementation:**
250
+
251
+ ```typescript
252
+ "@typescript-eslint/no-explicit-any": "error",
253
+ "@typescript-eslint/no-non-null-assertion": "error",
254
+ "@typescript-eslint/strict-boolean-expressions": "error",
255
+ ```
256
+
257
+ **Rationale:** AI-generated code can introduce subtle type safety issues. Strict rules catch these early in development.
258
+
259
+ ### Framework Accommodations
260
+
261
+ **Principle:** Relax rules only where framework patterns make strict rules impractical.
262
+
263
+ **Example - React:**
264
+
265
+ ```typescript
266
+ "@typescript-eslint/prefer-readonly-parameter-types": "off", // Component props
267
+ "@typescript-eslint/require-await": "off", // Event handlers
268
+ "@typescript-eslint/unbound-method": "off", // React patterns
269
+ ```
270
+
271
+ **Important Change: Strict Boolean Expressions in React**
272
+
273
+ As of the latest architecture revision, **`@typescript-eslint/strict-boolean-expressions` is no longer disabled for React projects**. This maintains consistent architectural patterns across the platform and prevents subtle rendering bugs.
274
+
275
+ **Rationale:**
276
+
277
+ - **Consistency**: All TypeScript code follows the same strict patterns
278
+ - **Bug Prevention**: Prevents rendering of `0`, `""`, or `[object Object]` in React components
279
+ - **Better Architecture**: Encourages explicit conditional logic over implicit truthiness
280
+ - **AI Code Safety**: Maintains strict type checking even in React contexts
281
+
282
+ React components should use explicit boolean checks:
283
+
284
+ ```tsx
285
+ // ❌ Previously allowed, now flagged as error
286
+ {
287
+ items && <ItemList items={items} />;
288
+ }
289
+
290
+ // ✅ Required explicit pattern
291
+ {
292
+ items.length > 0 && <ItemList items={items} />;
293
+ }
294
+ ```
295
+
296
+ ## Implementation Approach
297
+
298
+ The current architecture standardizes configuration through a modular design:
299
+
300
+ 1. **Shared rule and ignore modules** provide a single source of truth.
301
+ 2. **Factory functions** compose complete project-specific configurations.
302
+ 3. **Framework adapters** apply React and Next.js behavior without duplicating the base.
303
+ 4. **Documentation and examples** define the canonical setup for new packages and apps.
304
+
305
+ ## Performance Considerations
306
+
307
+ ### Configuration Size
308
+
309
+ **Goal:** Minimize configuration object size while maintaining comprehensive rule coverage.
310
+
311
+ **Implementation:**
312
+
313
+ - Shared ignore patterns reduce duplication
314
+ - Rule objects are composed rather than merged at runtime
315
+ - TypeScript inference eliminates need for runtime type checking
316
+
317
+ ### Type Checking Performance
318
+
319
+ **Goal:** Balance comprehensive type checking with reasonable performance.
320
+
321
+ **Implementation:**
322
+
323
+ - Type-aware rules are opt-in via `createTypeAwareConfig()`
324
+ - Project directory parameterization for efficient TypeScript project loading
325
+ - Comprehensive ignore patterns reduce files processed
326
+
327
+ ## Extensibility
328
+
329
+ ### Adding New Framework Support
330
+
331
+ To add support for a new framework:
332
+
333
+ 1. **Create framework-specific rules** in `src/shared-rules.ts`
334
+ 2. **Create framework configuration file** (e.g., `svelte.ts`)
335
+ 3. **Compose base configuration** with framework-specific additions
336
+ 4. **Document usage patterns** in the usage guide
337
+
338
+ ### Custom Rule Integration
339
+
340
+ Projects can extend configurations:
341
+
342
+ ```typescript
343
+ export default [
344
+ ...createTypeAwareConfig(import.meta.dirname),
345
+ {
346
+ rules: {
347
+ // Project-specific overrides
348
+ "@typescript-eslint/no-unused-vars": "warn",
349
+ },
350
+ },
351
+ ];
352
+ ```
353
+
354
+ ## Quality Assurance
355
+
356
+ ### Testing Strategy
357
+
358
+ **Configuration packages are exempt** from comprehensive testing per UIDE-126 standards because:
359
+
360
+ - They contain declarative configuration objects, not business logic
361
+ - Their "testing" happens naturally when consumed by other packages
362
+ - Configuration errors are caught during actual linting operations
363
+
364
+ ### Validation Approach
365
+
366
+ **Runtime validation:**
367
+
368
+ - ESLint validates configuration structure when loaded
369
+ - TypeScript ensures configuration object types are correct
370
+ - Consumer packages validate rule effectiveness through linting
371
+
372
+ **Documentation validation:**
373
+
374
+ - All examples are tested in real projects
375
+ - API documentation matches actual exports
376
+
377
+ ## Future Considerations
378
+
379
+ ### Planned Enhancements
380
+
381
+ 1. **Additional framework support** (Svelte, Astro, etc.)
382
+ 2. **Rule set customization** for different project types
383
+ 3. **Performance optimization** for large monorepos
384
+ 4. **Integration improvements** with development tools
385
+
386
+ ### Versioning Policy
387
+
388
+ Public exports and behavior follow semantic versioning. Breaking changes are introduced only in major releases with updated package documentation.
389
+
390
+ ## Related Documentation
391
+
392
+ - [API Reference](../reference/api-reference.md) - Complete API documentation
393
+ - [Usage Guide](../guides/usage-guide.md) - Detailed usage instructions
394
+ - [Examples](../../examples/) - Configuration examples