@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.
@@ -0,0 +1,61 @@
1
+ # Framework Configurations
2
+
3
+ Framework-specific ESLint configurations with specialized rules and patterns.
4
+
5
+ ## Overview
6
+
7
+ This section provides detailed documentation for framework-specific ESLint configurations, including React, Next.js, and other popular development frameworks supported by `@reasonabletech/eslint-config`.
8
+
9
+ ## Available Frameworks
10
+
11
+ ### React
12
+
13
+ - **[React Configuration](./react-config.md)** - ESLint rules for React component development with hooks support
14
+
15
+ ### Next.js
16
+
17
+ - **[Next.js Configuration](./next-config.md)** - Full-stack React applications with server actions and app router
18
+
19
+ ## Framework Selection Guide
20
+
21
+ ### Choose React Configuration When
22
+
23
+ - Building React libraries or component packages
24
+ - Creating client-side React applications
25
+ - Working with React Native projects
26
+ - Developing Storybook components
27
+
28
+ ### Choose Next.js Configuration When
29
+
30
+ - Building Next.js applications with app router
31
+ - Using Next.js server actions and server components
32
+ - Implementing Next.js API routes
33
+ - Deploying full-stack React applications
34
+
35
+ ## Configuration Features
36
+
37
+ Each framework configuration includes:
38
+
39
+ - **Base type-aware rules** from the core configuration
40
+ - **Framework-specific plugins** and their recommended rules
41
+ - **Custom rule overrides** for framework patterns
42
+ - **Specialized globals** for the framework environment
43
+ - **Performance optimizations** for the specific build tool
44
+
45
+ ## Usage Patterns
46
+
47
+ All framework configurations follow the same usage pattern:
48
+
49
+ ```typescript
50
+ // Framework-specific import
51
+ import { createTypeAware[Framework]Config } from "@reasonabletech/eslint-config/[framework]";
52
+
53
+ // Project directory configuration
54
+ export default createTypeAware[Framework]Config(import.meta.dirname);
55
+ ```
56
+
57
+ ## Related Documentation
58
+
59
+ - [API Reference](../api-reference.md) - Complete function documentation
60
+ - [Usage Guide](../../guides/usage-guide.md) - Setup instructions and examples
61
+ - [Architecture](../../concepts/architecture.md) - Framework integration design decisions
@@ -0,0 +1,187 @@
1
+ # Next.js ESLint Configuration
2
+
3
+ The Next.js configuration (`@reasonabletech/eslint-config/next`) provides comprehensive TypeScript, React, and Next.js rules specifically tailored for Next.js applications in the monorepo.
4
+
5
+ ## Features
6
+
7
+ - **Complete TypeScript integration**: All base TypeScript type-aware rules included
8
+ - **Comprehensive React support**: Full React configuration with hooks validation
9
+ - **Next.js optimization**: Core web vitals and Next.js-specific performance rules
10
+ - **Graceful fallbacks**: Automatic React setup when Next.js plugins unavailable
11
+ - **Smart ignore patterns**: Optimized file exclusions for Next.js build outputs
12
+ - **Modular architecture**: Built from focused, reusable modules with shared React rules
13
+
14
+ ## Installation
15
+
16
+ This package is installed as a workspace dependency:
17
+
18
+ ```bash
19
+ pnpm add -D @reasonabletech/eslint-config
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ Create an `eslint.config.mjs` file in your project root:
25
+
26
+ ```javascript
27
+ // eslint.config.mjs
28
+ import { createTypeAwareNextConfig } from "@reasonabletech/eslint-config/next";
29
+
30
+ export default createTypeAwareNextConfig(import.meta.dirname);
31
+ ```
32
+
33
+ ## Configuration Details
34
+
35
+ The Next.js configuration automatically includes the complete TypeScript base configuration plus React-specific enhancements and Next.js-specific optimizations:
36
+
37
+ ### Base TypeScript Features
38
+
39
+ - Full type-aware analysis with TypeScript's type checker
40
+ - **Strict boolean expressions enforced** - explicit checks required even in Next.js
41
+ - JSDoc documentation requirements
42
+ - Performance-optimized type checking
43
+
44
+ ### React Integration
45
+
46
+ - Complete React plugin setup with hooks validation
47
+ - Modern JSX transform support (no React imports needed)
48
+ - Browser and service worker globals configured
49
+ - **TypeScript rule adjustments** for React patterns while maintaining strict safety
50
+
51
+ ### Next.js-Specific Features
52
+
53
+ #### Core Web Vitals & Performance
54
+
55
+ - Next.js `core-web-vitals` rules via `@next/eslint-plugin-next`
56
+ - Performance optimization rules for images, scripts, and routing
57
+ - Server-side rendering and hydration safety checks
58
+
59
+ #### Smart File Ignores
60
+
61
+ - Build outputs: `.next/`, `out/`, `dist/`, `build/`
62
+ - Generated files: `next-env.d.ts`, `next.config.*`
63
+ - Development files: Storybook, test files, config files
64
+ - Next.js app directory patterns: `app/.well-known/**/*`
65
+
66
+ #### Graceful Plugin Loading
67
+
68
+ - **Primary**: Uses Next.js ESLint configs when available
69
+ - **Fallback**: Automatic React setup when Next.js plugins unavailable
70
+ - **Environment-aware**: Adapts to different development environments
71
+
72
+ ### Important: Strict Boolean Expressions in Next.js
73
+
74
+ Like React configuration, Next.js enforces strict boolean expressions to prevent rendering bugs and maintain architectural consistency.
75
+
76
+ #### ❌ Problematic Next.js Patterns
77
+
78
+ ```tsx
79
+ // These patterns violate strict-boolean-expressions
80
+ {
81
+ params.id && <UserPage userId={params.id} />;
82
+ } // Could render "0"
83
+ {
84
+ searchParams?.q && <SearchResults query={searchParams.q} />;
85
+ } // Could render empty string
86
+ {
87
+ session.user && <UserMenu user={session.user} />;
88
+ } // Could render [object Object]
89
+ ```
90
+
91
+ #### ✅ Correct Next.js Patterns
92
+
93
+ ```tsx
94
+ // Explicit checks prevent rendering bugs
95
+ {
96
+ params.id != null && <UserPage userId={params.id} />;
97
+ }
98
+ {
99
+ (searchParams?.q?.length ?? 0) > 0 && (
100
+ <SearchResults query={searchParams.q} />
101
+ );
102
+ }
103
+ {
104
+ session.user != null && <UserMenu user={session.user} />;
105
+ }
106
+
107
+ // Next.js-specific patterns
108
+ {
109
+ Boolean(params.slug) && <DynamicPage slug={params.slug} />;
110
+ }
111
+ {
112
+ searchParams != null && Object.keys(searchParams).length > 0 && (
113
+ <FilteredView />
114
+ );
115
+ }
116
+ ```
117
+
118
+ ## Example with Custom Rules
119
+
120
+ ```javascript
121
+ // eslint.config.js
122
+ import { config as nextConfig } from "@reasonabletech/eslint-config/next";
123
+
124
+ export default [
125
+ ...nextConfig,
126
+ {
127
+ // Page component rules
128
+ files: ["**/pages/**/*.{tsx,jsx}"],
129
+ rules: {
130
+ // Enforce Next.js page conventions
131
+ "@next/next/no-document-import-in-page": "error",
132
+ "@next/next/no-head-import-in-document": "error",
133
+ },
134
+ },
135
+ {
136
+ // API route rules
137
+ files: ["**/pages/api/**/*.{ts,js}"],
138
+ rules: {
139
+ // Enforce API route best practices
140
+ "@next/next/no-html-link-for-pages": "error",
141
+ },
142
+ },
143
+ ];
144
+ ```
145
+
146
+ ## Next.js App Directory Structure
147
+
148
+ When working with Next.js App Directory:
149
+
150
+ ```javascript
151
+ // eslint.config.js
152
+ import { config as nextConfig } from "@reasonabletech/eslint-config/next";
153
+
154
+ export default [
155
+ ...nextConfig,
156
+ {
157
+ // App directory client components
158
+ files: ["**/app/**/page.{tsx,jsx}", "**/app/**/layout.{tsx,jsx}"],
159
+ rules: {
160
+ // Rules specific to page/layout components
161
+ "@next/next/no-sync-scripts": "error",
162
+ },
163
+ },
164
+ {
165
+ // Route handlers
166
+ files: ["**/app/api/**/route.{ts,js}"],
167
+ rules: {
168
+ // Rules specific to API routes
169
+ "no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
170
+ },
171
+ },
172
+ ];
173
+ ```
174
+
175
+ ## Best Practices
176
+
177
+ - Use this configuration for all Next.js applications
178
+ - Configure different rules for pages vs. API routes
179
+ - For the App Directory, consider separate rules for server vs. client components
180
+ - Follow Next.js best practices for optimizing core web vitals
181
+
182
+ ## Related Documentation
183
+
184
+ - [React Configuration](./react-config.md) — React specific configuration (Next.js builds on this)
185
+ - [API Reference](../api-reference.md) — Complete function documentation
186
+ - [Usage Guide](../../guides/usage-guide.md) — Setup instructions and troubleshooting
187
+ - [AI Code Safety](../../concepts/ai-code-safety.md) — Why strict linting matters
@@ -0,0 +1,273 @@
1
+ # React ESLint Configuration
2
+
3
+ The React configuration (`@reasonabletech/eslint-config/react`) provides comprehensive TypeScript and React rules specifically tailored for React projects in the monorepo.
4
+
5
+ ## Features
6
+
7
+ - **Complete TypeScript integration**: All base TypeScript type-aware rules included
8
+ - **Modern React support**: React 18+ with new JSX transform compatibility
9
+ - **React Hooks validation**: Exhaustive dependency checking and Rules of Hooks
10
+ - **Browser environment**: Browser and service worker globals configured
11
+ - **Optimized rule sets**: React-specific TypeScript rule adjustments
12
+ - **Modular architecture**: Built from focused, reusable modules
13
+
14
+ ## Installation
15
+
16
+ This package is installed as a workspace dependency:
17
+
18
+ ```bash
19
+ pnpm add -D @reasonabletech/eslint-config
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ Create an `eslint.config.mjs` file in your project root:
25
+
26
+ ```javascript
27
+ // eslint.config.mjs
28
+ import { createTypeAwareReactConfig } from "@reasonabletech/eslint-config/react";
29
+
30
+ export default createTypeAwareReactConfig(import.meta.dirname);
31
+ ```
32
+
33
+ ## Configuration Details
34
+
35
+ The React configuration automatically includes the complete TypeScript base configuration plus React-specific enhancements:
36
+
37
+ ### Base TypeScript Features
38
+
39
+ - Full type-aware analysis with TypeScript's type checker
40
+ - Strict type safety rules optimized for AI-generated code
41
+ - JSDoc documentation requirements
42
+ - Performance-optimized type checking
43
+
44
+ ### React-Specific Additions
45
+
46
+ #### Plugins & Rules
47
+
48
+ - **React Plugin**: Core React linting with `eslint-plugin-react`
49
+ - **React Hooks Plugin**: Rules of Hooks and exhaustive dependency validation
50
+ - **Modern JSX**: `react/react-in-jsx-scope` disabled for new JSX transform
51
+
52
+ #### Environment Configuration
53
+
54
+ - **Browser Globals**: Complete browser API support
55
+ - **Service Worker Globals**: PWA and service worker compatibility
56
+ - **React Settings**: Automatic React version detection
57
+
58
+ #### TypeScript Rule Adjustments
59
+
60
+ - `@typescript-eslint/prefer-readonly-parameter-types`: Disabled for component props
61
+ - `@typescript-eslint/require-await`: Disabled for event handlers
62
+ - `@typescript-eslint/unbound-method`: Disabled for React patterns
63
+ - **`@typescript-eslint/strict-boolean-expressions`: ENABLED** - Explicit boolean checks required even in React
64
+
65
+ #### JSDoc Rules
66
+
67
+ - Component files (`.tsx`, `.jsx`) exempt from `@returns` documentation
68
+ - TypeScript provides return type information automatically
69
+
70
+ ## Conditional Rendering with Strict Boolean Expressions
71
+
72
+ The React configuration enforces explicit boolean checks in conditional rendering to prevent common bugs and maintain architectural consistency. This means **truthiness checks are not allowed** - you must be explicit about your conditions.
73
+
74
+ ### ❌ Problematic Patterns (Will Cause Lint Errors)
75
+
76
+ ```tsx
77
+ // These patterns can render unexpected values like 0, "", or "[object Object]"
78
+ {
79
+ items && <ItemList items={items} />;
80
+ } // Could render empty array or 0
81
+ {
82
+ count && <Counter value={count} />;
83
+ } // Will render 0 instead of nothing
84
+ {
85
+ user?.name && <UserName name={user.name} />;
86
+ } // Could render empty string
87
+ {
88
+ error && <ErrorMessage>{error}</ErrorMessage>;
89
+ } // Could render error object
90
+ ```
91
+
92
+ ### ✅ Correct Patterns (Explicit Boolean Checks)
93
+
94
+ ```tsx
95
+ // Arrays - check length explicitly
96
+ {
97
+ items.length > 0 && <ItemList items={items} />;
98
+ }
99
+
100
+ // Numbers - explicit comparison
101
+ {
102
+ count > 0 && <Counter value={count} />;
103
+ }
104
+
105
+ // Strings - null check or length check
106
+ {
107
+ user?.name != null && <UserName name={user.name} />;
108
+ }
109
+ {
110
+ (user?.name?.length ?? 0) > 0 && <UserName name={user.name} />;
111
+ }
112
+
113
+ // Objects - explicit null/undefined checks
114
+ {
115
+ error != null && <ErrorMessage>{error}</ErrorMessage>;
116
+ }
117
+ {
118
+ selectedWorkspace != null && (
119
+ <WorkspaceOverview workspace={selectedWorkspace} />
120
+ );
121
+ }
122
+
123
+ // Boolean conversion when appropriate
124
+ {
125
+ Boolean(user?.name) && <UserName name={user.name} />;
126
+ }
127
+
128
+ // Multiple conditions
129
+ {
130
+ user != null && user.isActive && <ActiveUserBadge />;
131
+ }
132
+ ```
133
+
134
+ ### Advanced Patterns
135
+
136
+ #### Guard Components
137
+
138
+ For complex conditions, use guard components:
139
+
140
+ ```tsx
141
+ function ConditionalRenderer({
142
+ condition,
143
+ children,
144
+ }: {
145
+ condition: boolean;
146
+ children: React.ReactNode;
147
+ }) {
148
+ return condition ? <>{children}</> : null;
149
+ }
150
+
151
+ // Usage
152
+ <ConditionalRenderer condition={items.length > 0}>
153
+ <ItemList items={items} />
154
+ </ConditionalRenderer>;
155
+ ```
156
+
157
+ #### Custom Hooks for State Logic
158
+
159
+ ```tsx
160
+ function useVisibilityState(items: unknown[]) {
161
+ return {
162
+ shouldShowList: items.length > 0,
163
+ shouldShowEmptyState: items.length === 0,
164
+ };
165
+ }
166
+
167
+ // Usage in component
168
+ const { shouldShowList, shouldShowEmptyState } = useVisibilityState(items);
169
+ return (
170
+ <>
171
+ {shouldShowList && <ItemList items={items} />}
172
+ {shouldShowEmptyState && <EmptyState />}
173
+ </>
174
+ );
175
+ ```
176
+
177
+ #### Ternary Operators for Either/Or Cases
178
+
179
+ ```tsx
180
+ {
181
+ items.length > 0 ? <ItemList items={items} /> : <EmptyState />;
182
+ }
183
+ ```
184
+
185
+ ### Why This Approach?
186
+
187
+ 1. **Prevents Rendering Bugs**: No more accidentally rendering `0`, `""`, or `[object Object]`
188
+ 2. **Explicit Intent**: Code clearly shows what conditions trigger rendering
189
+ 3. **Consistent Architecture**: Same strict patterns across TypeScript and React code
190
+ 4. **Better Maintainability**: Conditions are clear and unambiguous
191
+ 5. **AI Code Safety**: Strict checks prevent subtle bugs in generated code
192
+
193
+ ## Example with Custom Rules
194
+
195
+ ```javascript
196
+ // eslint.config.mjs
197
+ import { createTypeAwareReactConfig } from "@reasonabletech/eslint-config/react";
198
+
199
+ export default [
200
+ ...createTypeAwareReactConfig(import.meta.dirname),
201
+ {
202
+ // Component file patterns
203
+ files: ["**/components/**/*.{tsx,jsx}"],
204
+ rules: {
205
+ // Enforce component naming conventions
206
+ "react/function-component-definition": [
207
+ "error",
208
+ {
209
+ namedComponents: "function-declaration",
210
+ unnamedComponents: "arrow-function",
211
+ },
212
+ ],
213
+ // Stricter TypeScript rules for components
214
+ "@typescript-eslint/no-unused-vars": "error",
215
+ },
216
+ },
217
+ {
218
+ // Hook file patterns
219
+ files: ["**/hooks/**/*.{ts,tsx}"],
220
+ rules: {
221
+ // Stricter hook dependency checking
222
+ "react-hooks/exhaustive-deps": "error",
223
+ // Require JSDoc for custom hooks
224
+ "jsdoc/require-jsdoc": [
225
+ "error",
226
+ { require: { FunctionDeclaration: true } },
227
+ ],
228
+ },
229
+ },
230
+ ];
231
+ ```
232
+
233
+ ## Modular Architecture
234
+
235
+ The React configuration is built from focused modules:
236
+
237
+ ### `src/react/plugins.ts`
238
+
239
+ - React and React Hooks plugin configurations
240
+ - Browser globals and environment setup
241
+ - Plugin composition utilities
242
+
243
+ ### `src/react/rules.ts`
244
+
245
+ - React-specific rules using shared React patterns
246
+ - Integration with shared React rules from `src/shared/react-rules.ts`
247
+ - Framework-specific rule extensions
248
+
249
+ ### `src/react/config.ts`
250
+
251
+ - Complete configuration builder
252
+ - Combines plugins, rules, and file-specific overrides
253
+ - Orchestrates all React-specific configurations
254
+
255
+ ### Shared Components
256
+
257
+ - `src/shared/react-rules.ts`: Common rules shared with Next.js config
258
+ - `src/index.ts`: Base TypeScript configuration automatically included
259
+
260
+ ## Best Practices
261
+
262
+ - Use the React configuration for any project that uses React
263
+ - Consider using more specific configurations (Next.js) for framework-specific projects
264
+ - Customize rules for specific file patterns to enforce different standards for components, hooks, etc.
265
+ - Keep components and hooks in separate files to apply more targeted linting rules
266
+
267
+ ## Related Documentation
268
+
269
+ - [Next.js Configuration](./next-config.md) — Next.js specific configuration
270
+ - [API Reference](../api-reference.md) — Complete function documentation
271
+ - [Usage Guide](../../guides/usage-guide.md) — Setup instructions and troubleshooting
272
+ - [Refactoring React for Type Safety](../../tutorials/refactoring-react-for-type-safety.md) — Fixing strict-boolean-expressions in React components
273
+ - [AI Code Safety](../../concepts/ai-code-safety.md) — Why strict linting matters