project-graph-mcp 1.0.0

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,76 @@
1
+ {
2
+ "name": "express-5",
3
+ "description": "Express.js 5.x API standards",
4
+ "docs": "https://expressjs.com/",
5
+ "detect": {
6
+ "packageJson": [
7
+ "express"
8
+ ],
9
+ "imports": [
10
+ "from 'express'",
11
+ "require('express')"
12
+ ],
13
+ "patterns": [
14
+ "app.get(",
15
+ "app.post(",
16
+ "app.use("
17
+ ]
18
+ },
19
+ "rules": [
20
+ {
21
+ "id": "express-no-sync-methods",
22
+ "name": "Avoid sync file methods",
23
+ "description": "Synchronous methods block the event loop",
24
+ "pattern": "Sync(",
25
+ "patternType": "string",
26
+ "replacement": "Use async versions: readFile, writeFile, etc.",
27
+ "severity": "warning",
28
+ "filePattern": "*.js",
29
+ "docs": "https://expressjs.com/en/advanced/best-practice-performance.html"
30
+ },
31
+ {
32
+ "id": "express-error-handler",
33
+ "name": "Missing error parameter",
34
+ "description": "Error handlers must have 4 parameters (err, req, res, next)",
35
+ "pattern": "app.use\\(\\(req, res\\)",
36
+ "patternType": "regex",
37
+ "replacement": "app.use((err, req, res, next) => { ... })",
38
+ "severity": "info",
39
+ "filePattern": "*.js",
40
+ "docs": "https://expressjs.com/en/guide/error-handling.html"
41
+ },
42
+ {
43
+ "id": "express-no-res-send-in-loop",
44
+ "name": "res.send() in loop",
45
+ "description": "Response can only be sent once per request",
46
+ "pattern": "forEach.*res\\.send",
47
+ "patternType": "regex",
48
+ "replacement": "Collect results, then send once",
49
+ "severity": "error",
50
+ "filePattern": "*.js",
51
+ "docs": "https://expressjs.com/en/api.html#res.send"
52
+ },
53
+ {
54
+ "id": "express-use-helmet",
55
+ "name": "Consider using Helmet",
56
+ "description": "Helmet helps secure Express apps with HTTP headers",
57
+ "pattern": "app.listen(",
58
+ "patternType": "string",
59
+ "replacement": "Add app.use(helmet()) for security headers",
60
+ "severity": "info",
61
+ "filePattern": "*.js",
62
+ "docs": "https://helmetjs.github.io/"
63
+ },
64
+ {
65
+ "id": "express-async-handler",
66
+ "name": "Async route without try-catch",
67
+ "description": "Unhandled promise rejections can crash the server",
68
+ "pattern": "async (req, res)",
69
+ "patternType": "string",
70
+ "replacement": "Wrap in try-catch or use express-async-handler",
71
+ "severity": "warning",
72
+ "filePattern": "*.js",
73
+ "docs": "https://expressjs.com/en/guide/error-handling.html"
74
+ }
75
+ ]
76
+ }
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "fastify-5",
3
+ "description": "Fastify 5.x server standards",
4
+ "docs": "https://fastify.dev/docs/latest/",
5
+ "detect": {
6
+ "packageJson": [
7
+ "fastify"
8
+ ],
9
+ "imports": [
10
+ "from 'fastify'",
11
+ "require('fastify')"
12
+ ],
13
+ "patterns": [
14
+ "fastify.get(",
15
+ "fastify.post("
16
+ ]
17
+ },
18
+ "rules": [
19
+ {
20
+ "id": "fastify-use-schema",
21
+ "name": "Define JSON Schema for routes",
22
+ "description": "Schema enables validation and serialization",
23
+ "pattern": "fastify.get('",
24
+ "patternType": "string",
25
+ "replacement": "fastify.get('/path', { schema: { ... } }, handler)",
26
+ "severity": "info",
27
+ "filePattern": "*.js",
28
+ "docs": "https://fastify.dev/docs/latest/Reference/Validation-and-Serialization/"
29
+ },
30
+ {
31
+ "id": "fastify-async-handlers",
32
+ "name": "Use async handlers",
33
+ "description": "Async handlers auto-handle promise rejections",
34
+ "pattern": "function(request, reply)",
35
+ "patternType": "string",
36
+ "replacement": "async function(request, reply)",
37
+ "severity": "warning",
38
+ "filePattern": "*.js",
39
+ "docs": "https://fastify.dev/docs/latest/Reference/Routes/#async-await"
40
+ },
41
+ {
42
+ "id": "fastify-use-plugins",
43
+ "name": "Encapsulate with plugins",
44
+ "description": "Use plugins for modular architecture",
45
+ "pattern": "fastify.register(",
46
+ "patternType": "string",
47
+ "replacement": "fastify.register(plugin, { prefix: '/api' })",
48
+ "severity": "info",
49
+ "filePattern": "*.js",
50
+ "docs": "https://fastify.dev/docs/latest/Reference/Plugins/"
51
+ },
52
+ {
53
+ "id": "fastify-no-express-middleware",
54
+ "name": "Avoid Express middleware",
55
+ "description": "Use Fastify hooks instead of Express middleware",
56
+ "pattern": "express()",
57
+ "patternType": "string",
58
+ "replacement": "Use fastify.addHook() or @fastify/middie",
59
+ "severity": "warning",
60
+ "filePattern": "*.js",
61
+ "docs": "https://fastify.dev/docs/latest/Reference/Hooks/"
62
+ },
63
+ {
64
+ "id": "fastify-use-logger",
65
+ "name": "Enable built-in logger",
66
+ "description": "Fastify has pino logger built-in",
67
+ "pattern": "console.log(",
68
+ "patternType": "string",
69
+ "replacement": "request.log.info() or fastify.log.info()",
70
+ "severity": "info",
71
+ "filePattern": "*.js",
72
+ "docs": "https://fastify.dev/docs/latest/Reference/Logging/"
73
+ }
74
+ ]
75
+ }
@@ -0,0 +1,88 @@
1
+ {
2
+ "name": "nestjs-10",
3
+ "description": "NestJS 10.x architecture standards",
4
+ "docs": "https://docs.nestjs.com/",
5
+ "detect": {
6
+ "packageJson": [
7
+ "@nestjs/core",
8
+ "@nestjs/common"
9
+ ],
10
+ "imports": [
11
+ "from '@nestjs/common'",
12
+ "from '@nestjs/core'"
13
+ ],
14
+ "patterns": [
15
+ "@Controller",
16
+ "@Injectable",
17
+ "@Module"
18
+ ]
19
+ },
20
+ "rules": [
21
+ {
22
+ "id": "nestjs-use-dto",
23
+ "name": "Use DTOs for validation",
24
+ "description": "Create DTO classes with class-validator decorators",
25
+ "pattern": "@Body() body:",
26
+ "patternType": "string",
27
+ "replacement": "@Body() dto: CreateItemDto",
28
+ "severity": "warning",
29
+ "filePattern": "*.ts",
30
+ "docs": "https://docs.nestjs.com/techniques/validation"
31
+ },
32
+ {
33
+ "id": "nestjs-no-any-injection",
34
+ "name": "Type all injected dependencies",
35
+ "description": "Avoid any type for constructor injection",
36
+ "pattern": "constructor.*: any",
37
+ "patternType": "regex",
38
+ "replacement": "constructor(private service: ServiceClass)",
39
+ "severity": "warning",
40
+ "filePattern": "*.ts",
41
+ "docs": "https://docs.nestjs.com/providers"
42
+ },
43
+ {
44
+ "id": "nestjs-use-interceptors",
45
+ "name": "Use interceptors for cross-cutting concerns",
46
+ "description": "Logging, caching, transform should use interceptors",
47
+ "pattern": "console.log.*request",
48
+ "patternType": "regex",
49
+ "replacement": "@UseInterceptors(LoggingInterceptor)",
50
+ "severity": "info",
51
+ "filePattern": "*.ts",
52
+ "docs": "https://docs.nestjs.com/interceptors"
53
+ },
54
+ {
55
+ "id": "nestjs-use-guards",
56
+ "name": "Use guards for authorization",
57
+ "description": "Auth checks should be in guards, not controllers",
58
+ "pattern": "if.*user.*throw",
59
+ "patternType": "regex",
60
+ "replacement": "@UseGuards(AuthGuard)",
61
+ "severity": "warning",
62
+ "filePattern": "*.controller.ts",
63
+ "docs": "https://docs.nestjs.com/guards"
64
+ },
65
+ {
66
+ "id": "nestjs-use-pipes",
67
+ "name": "Use pipes for validation",
68
+ "description": "Apply ValidationPipe globally or per-route",
69
+ "pattern": "@Body()",
70
+ "patternType": "string",
71
+ "replacement": "@Body(ValidationPipe) or app.useGlobalPipes()",
72
+ "severity": "info",
73
+ "filePattern": "*.ts",
74
+ "docs": "https://docs.nestjs.com/pipes"
75
+ },
76
+ {
77
+ "id": "nestjs-swagger-decorators",
78
+ "name": "Add Swagger decorators",
79
+ "description": "Document API with @ApiTags, @ApiOperation, etc.",
80
+ "pattern": "@Controller(",
81
+ "patternType": "string",
82
+ "replacement": "@ApiTags('...')\n@Controller('...')",
83
+ "severity": "info",
84
+ "filePattern": "*.controller.ts",
85
+ "docs": "https://docs.nestjs.com/openapi/introduction"
86
+ }
87
+ ]
88
+ }
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "nextjs-15",
3
+ "description": "Next.js 15 App Router standards",
4
+ "docs": "https://nextjs.org/docs",
5
+ "detect": {
6
+ "packageJson": [
7
+ "next"
8
+ ],
9
+ "imports": [
10
+ "from 'next'",
11
+ "next/"
12
+ ],
13
+ "patterns": [
14
+ "app/",
15
+ "page.tsx",
16
+ "layout.tsx"
17
+ ]
18
+ },
19
+ "rules": [
20
+ {
21
+ "id": "nextjs-use-app-router",
22
+ "name": "Prefer App Router over Pages",
23
+ "description": "App Router is the recommended approach in Next.js 13+",
24
+ "pattern": "pages/",
25
+ "patternType": "string",
26
+ "replacement": "Move to app/ directory with Server Components",
27
+ "severity": "info",
28
+ "filePattern": "*.tsx",
29
+ "docs": "https://nextjs.org/docs/app"
30
+ },
31
+ {
32
+ "id": "nextjs-server-actions",
33
+ "name": "Use Server Actions for mutations",
34
+ "description": "Prefer Server Actions over API routes for form handling",
35
+ "pattern": "fetch('/api/",
36
+ "patternType": "string",
37
+ "replacement": "async function action() { 'use server'; ... }",
38
+ "severity": "info",
39
+ "filePattern": "*.tsx",
40
+ "docs": "https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions"
41
+ },
42
+ {
43
+ "id": "nextjs-no-client-fetch",
44
+ "name": "Fetch data on server",
45
+ "description": "Server Components can fetch data directly without useEffect",
46
+ "pattern": "useEffect.*fetch",
47
+ "patternType": "regex",
48
+ "replacement": "async function Page() { const data = await fetch(...) }",
49
+ "severity": "warning",
50
+ "filePattern": "*.tsx",
51
+ "docs": "https://nextjs.org/docs/app/building-your-application/data-fetching"
52
+ },
53
+ {
54
+ "id": "nextjs-image-component",
55
+ "name": "Use next/image for images",
56
+ "description": "next/image provides automatic optimization",
57
+ "pattern": "<img src=",
58
+ "patternType": "string",
59
+ "replacement": "<Image src={...} alt={...} width={...} height={...} />",
60
+ "severity": "warning",
61
+ "filePattern": "*.tsx",
62
+ "docs": "https://nextjs.org/docs/app/api-reference/components/image"
63
+ },
64
+ {
65
+ "id": "nextjs-link-component",
66
+ "name": "Use next/link for navigation",
67
+ "description": "next/link enables client-side navigation",
68
+ "pattern": "<a href=\"/",
69
+ "patternType": "string",
70
+ "replacement": "<Link href=\"/...\">",
71
+ "severity": "warning",
72
+ "filePattern": "*.tsx",
73
+ "docs": "https://nextjs.org/docs/app/api-reference/components/link"
74
+ },
75
+ {
76
+ "id": "nextjs-metadata-export",
77
+ "name": "Export metadata for SEO",
78
+ "description": "Use metadata export for page SEO",
79
+ "pattern": "<title>",
80
+ "patternType": "string",
81
+ "replacement": "export const metadata = { title: '...' }",
82
+ "severity": "info",
83
+ "filePattern": "*.tsx",
84
+ "docs": "https://nextjs.org/docs/app/building-your-application/optimizing/metadata"
85
+ }
86
+ ]
87
+ }
@@ -0,0 +1,156 @@
1
+ {
2
+ "name": "node-22",
3
+ "description": "Node.js 22+ modern standards",
4
+ "docs": "https://nodejs.org/docs/latest/api/",
5
+ "alwaysApply": true,
6
+ "detect": {
7
+ "packageJson": [],
8
+ "imports": [],
9
+ "patterns": []
10
+ },
11
+ "rules": [
12
+ {
13
+ "id": "node-no-require",
14
+ "name": "Use ESM imports",
15
+ "description": "Prefer ES modules over CommonJS require()",
16
+ "pattern": "require(",
17
+ "patternType": "string",
18
+ "replacement": "import ... from '...'",
19
+ "severity": "warning",
20
+ "filePattern": "*.js",
21
+ "docs": "https://nodejs.org/api/esm.html"
22
+ },
23
+ {
24
+ "id": "node-no-callback-hell",
25
+ "name": "Avoid callback nesting",
26
+ "description": "Use async/await instead of nested callbacks",
27
+ "pattern": ", (err,",
28
+ "patternType": "string",
29
+ "replacement": "await promisify() or native async methods",
30
+ "severity": "warning",
31
+ "filePattern": "*.js",
32
+ "docs": "https://nodejs.org/api/util.html#utilpromisifyoriginal"
33
+ },
34
+ {
35
+ "id": "node-no-process-exit",
36
+ "name": "Avoid process.exit()",
37
+ "description": "Let Node exit naturally, or use proper shutdown handlers",
38
+ "pattern": "process.exit(",
39
+ "patternType": "string",
40
+ "replacement": "Graceful shutdown with cleanup",
41
+ "severity": "info",
42
+ "filePattern": "*.js",
43
+ "docs": "https://nodejs.org/api/process.html#processexitcode"
44
+ },
45
+ {
46
+ "id": "node-use-fetch",
47
+ "name": "Use native fetch()",
48
+ "description": "Node 18+ has built-in fetch, no need for node-fetch",
49
+ "pattern": "node-fetch",
50
+ "patternType": "string",
51
+ "replacement": "Use globalThis.fetch()",
52
+ "severity": "warning",
53
+ "filePattern": "*.js",
54
+ "docs": "https://nodejs.org/api/globals.html#fetch"
55
+ },
56
+ {
57
+ "id": "node-use-crypto-randomuuid",
58
+ "name": "Use crypto.randomUUID()",
59
+ "description": "Node 19+ has built-in UUID generation",
60
+ "pattern": "uuid",
61
+ "patternType": "string",
62
+ "replacement": "crypto.randomUUID()",
63
+ "severity": "info",
64
+ "filePattern": "*.js",
65
+ "docs": "https://nodejs.org/api/crypto.html#cryptorandomuuidoptions"
66
+ },
67
+ {
68
+ "id": "node-use-structuredclone",
69
+ "name": "Use structuredClone()",
70
+ "description": "Node 17+ has built-in deep cloning",
71
+ "pattern": "JSON.parse(JSON.stringify(",
72
+ "patternType": "string",
73
+ "replacement": "structuredClone(obj)",
74
+ "severity": "info",
75
+ "filePattern": "*.js",
76
+ "docs": "https://developer.mozilla.org/en-US/docs/Web/API/structuredClone"
77
+ },
78
+ {
79
+ "id": "node-no-sync-fs",
80
+ "name": "Avoid sync fs methods",
81
+ "description": "Synchronous methods block the event loop",
82
+ "pattern": "Sync(",
83
+ "patternType": "string",
84
+ "replacement": "Use fs/promises: readFile, writeFile, etc.",
85
+ "severity": "warning",
86
+ "filePattern": "*.js",
87
+ "docs": "https://nodejs.org/api/fs.html#fspromisesapi"
88
+ },
89
+ {
90
+ "id": "node-no-or-fallback-data",
91
+ "name": "Avoid || fallback for data",
92
+ "description": "Using || for defaults can hide bugs (0, '', false become fallback). Use ?? or explicit checks.",
93
+ "pattern": "|| data.",
94
+ "patternType": "string",
95
+ "replacement": "?? or explicit null/undefined check",
96
+ "severity": "warning",
97
+ "filePattern": "*.js",
98
+ "docs": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing"
99
+ },
100
+ {
101
+ "id": "node-no-or-fallback-response",
102
+ "name": "Avoid || fallback for response",
103
+ "description": "Using || for defaults can mask empty responses and cause silent failures",
104
+ "pattern": "|| response.",
105
+ "patternType": "string",
106
+ "replacement": "?? or explicit null/undefined check",
107
+ "severity": "warning",
108
+ "filePattern": "*.js",
109
+ "docs": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing"
110
+ },
111
+ {
112
+ "id": "node-no-or-fallback-result",
113
+ "name": "Avoid || fallback for result",
114
+ "description": "Using || can hide zero values or empty strings. Use ?? for null/undefined only.",
115
+ "pattern": "|| result",
116
+ "patternType": "string",
117
+ "replacement": "?? or explicit null/undefined check",
118
+ "severity": "warning",
119
+ "filePattern": "*.js",
120
+ "docs": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing"
121
+ },
122
+ {
123
+ "id": "node-no-cyrillic-comments",
124
+ "name": "No Cyrillic in comments",
125
+ "description": "Comments should be in English for international collaboration",
126
+ "pattern": "//.*[а-яА-ЯёЁ]",
127
+ "patternType": "regex",
128
+ "replacement": "Translate comment to English",
129
+ "severity": "info",
130
+ "filePattern": "*.js",
131
+ "docs": ""
132
+ },
133
+ {
134
+ "id": "node-no-html-comments",
135
+ "name": "No comments in HTML",
136
+ "description": "HTML comments are visible in source and increase file size",
137
+ "pattern": "<!--",
138
+ "patternType": "string",
139
+ "replacement": "Remove comment or use server-side templating",
140
+ "severity": "warning",
141
+ "filePattern": "*.html",
142
+ "docs": ""
143
+ },
144
+ {
145
+ "id": "node-no-public-js-comments",
146
+ "name": "No comments in public JS",
147
+ "description": "Comments in public JS expose implementation details and increase bundle size",
148
+ "pattern": "//",
149
+ "patternType": "string",
150
+ "replacement": "Remove comments or use build-time stripping",
151
+ "severity": "info",
152
+ "filePattern": "**/public/**/*.js",
153
+ "docs": ""
154
+ }
155
+ ]
156
+ }
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "react-18",
3
+ "description": "React 18+ component standards",
4
+ "docs": "https://react.dev/",
5
+ "detect": {
6
+ "packageJson": [
7
+ "react",
8
+ "react-dom"
9
+ ],
10
+ "imports": [
11
+ "from 'react'",
12
+ "from \"react\""
13
+ ],
14
+ "patterns": [
15
+ "useState",
16
+ "useEffect"
17
+ ]
18
+ },
19
+ "rules": [
20
+ {
21
+ "id": "react-no-class-components",
22
+ "name": "Use functional components",
23
+ "description": "Prefer functional components over class components in React 18+",
24
+ "pattern": "extends Component",
25
+ "patternType": "string",
26
+ "replacement": "function Component() { ... } or const Component = () => { ... }",
27
+ "severity": "warning",
28
+ "filePattern": "*.jsx",
29
+ "docs": "https://react.dev/learn/your-first-component"
30
+ },
31
+ {
32
+ "id": "react-no-default-export",
33
+ "name": "Use named exports",
34
+ "description": "Prefer named exports for better refactoring support",
35
+ "pattern": "export default",
36
+ "patternType": "string",
37
+ "replacement": "export function/const ComponentName",
38
+ "severity": "info",
39
+ "filePattern": "*.jsx",
40
+ "docs": "https://react.dev/learn/importing-and-exporting-components"
41
+ },
42
+ {
43
+ "id": "react-useeffect-deps",
44
+ "name": "useEffect without deps array",
45
+ "description": "useEffect should have a dependency array to prevent infinite loops",
46
+ "pattern": "useEffect\\([^)]+\\)\\s*$",
47
+ "patternType": "regex",
48
+ "replacement": "useEffect(() => { ... }, [dependencies])",
49
+ "severity": "warning",
50
+ "filePattern": "*.jsx",
51
+ "docs": "https://react.dev/reference/react/useEffect"
52
+ },
53
+ {
54
+ "id": "react-no-inline-styles",
55
+ "name": "Avoid inline styles",
56
+ "description": "Use CSS modules or styled-components instead of inline styles",
57
+ "pattern": "style={{",
58
+ "patternType": "string",
59
+ "replacement": "className={styles.myClass}",
60
+ "severity": "info",
61
+ "filePattern": "*.jsx",
62
+ "docs": "https://react.dev/learn/passing-props-to-a-component"
63
+ },
64
+ {
65
+ "id": "react-no-dangerouslysetinnerhtml",
66
+ "name": "Avoid dangerouslySetInnerHTML",
67
+ "description": "Can lead to XSS vulnerabilities, use with caution",
68
+ "pattern": "dangerouslySetInnerHTML",
69
+ "patternType": "string",
70
+ "replacement": "Parse and render safe content",
71
+ "severity": "error",
72
+ "filePattern": "*.jsx",
73
+ "docs": "https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html"
74
+ },
75
+ {
76
+ "id": "react-key-prop",
77
+ "name": "Array key should not use index",
78
+ "description": "Using array index as key can cause issues with reordering",
79
+ "pattern": "key={index}",
80
+ "patternType": "string",
81
+ "replacement": "key={item.id} or unique identifier",
82
+ "severity": "warning",
83
+ "filePattern": "*.jsx",
84
+ "docs": "https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key"
85
+ }
86
+ ]
87
+ }
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "react-19",
3
+ "description": "React 19+ with Server Components and Actions",
4
+ "docs": "https://react.dev/",
5
+ "detect": {
6
+ "packageJson": [
7
+ "react"
8
+ ],
9
+ "imports": [
10
+ "from 'react'",
11
+ "from \"react\""
12
+ ],
13
+ "patterns": [
14
+ "use client",
15
+ "use server",
16
+ "useActionState"
17
+ ]
18
+ },
19
+ "rules": [
20
+ {
21
+ "id": "react19-use-action-state",
22
+ "name": "Use useActionState for forms",
23
+ "description": "Prefer useActionState over useState for form handling",
24
+ "pattern": "useState.*handleSubmit",
25
+ "patternType": "regex",
26
+ "replacement": "useActionState((prev, formData) => { ... })",
27
+ "severity": "info",
28
+ "filePattern": "*.jsx",
29
+ "docs": "https://react.dev/reference/react/useActionState"
30
+ },
31
+ {
32
+ "id": "react19-use-optimistic",
33
+ "name": "Consider useOptimistic for instant UI",
34
+ "description": "Use useOptimistic for optimistic updates",
35
+ "pattern": "setLoading(true)",
36
+ "patternType": "string",
37
+ "replacement": "useOptimistic() for instant feedback",
38
+ "severity": "info",
39
+ "filePattern": "*.jsx",
40
+ "docs": "https://react.dev/reference/react/useOptimistic"
41
+ },
42
+ {
43
+ "id": "react19-no-forwardref",
44
+ "name": "forwardRef is deprecated",
45
+ "description": "In React 19, ref is passed as a prop, forwardRef not needed",
46
+ "pattern": "forwardRef",
47
+ "patternType": "string",
48
+ "replacement": "function Component({ ref, ...props })",
49
+ "severity": "warning",
50
+ "filePattern": "*.jsx",
51
+ "docs": "https://react.dev/blog/2024/04/25/react-19"
52
+ },
53
+ {
54
+ "id": "react19-no-use-memo-everywhere",
55
+ "name": "React Compiler handles memoization",
56
+ "description": "With React Compiler, manual useMemo/useCallback often unnecessary",
57
+ "pattern": "useMemo(",
58
+ "patternType": "string",
59
+ "replacement": "Let React Compiler optimize, remove if not needed",
60
+ "severity": "info",
61
+ "filePattern": "*.jsx",
62
+ "docs": "https://react.dev/learn/react-compiler"
63
+ },
64
+ {
65
+ "id": "react19-use-form-status",
66
+ "name": "Use useFormStatus for pending state",
67
+ "description": "useFormStatus provides pending state for forms",
68
+ "pattern": "isSubmitting",
69
+ "patternType": "string",
70
+ "replacement": "const { pending } = useFormStatus()",
71
+ "severity": "info",
72
+ "filePattern": "*.jsx",
73
+ "docs": "https://react.dev/reference/react-dom/hooks/useFormStatus"
74
+ }
75
+ ]
76
+ }