@jgamaraalv/ts-dev-kit 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.
Files changed (117) hide show
  1. package/.claude-plugin/marketplace.json +24 -0
  2. package/.claude-plugin/plugin.json +24 -0
  3. package/CHANGELOG.md +24 -0
  4. package/LICENSE +21 -0
  5. package/README.md +128 -0
  6. package/agents/accessibility-pro.md +139 -0
  7. package/agents/api-builder.md +110 -0
  8. package/agents/code-reviewer.md +190 -0
  9. package/agents/database-expert.md +138 -0
  10. package/agents/debugger.md +241 -0
  11. package/agents/docker-expert.md +51 -0
  12. package/agents/multi-agent-coordinator.md +378 -0
  13. package/agents/nextjs-expert.md +136 -0
  14. package/agents/performance-engineer.md +138 -0
  15. package/agents/playwright-expert.md +126 -0
  16. package/agents/react-specialist.md +97 -0
  17. package/agents/security-scanner.md +105 -0
  18. package/agents/test-generator.md +221 -0
  19. package/agents/typescript-pro.md +253 -0
  20. package/agents/ux-optimizer.md +93 -0
  21. package/docs/rules/orchestration.md.template +126 -0
  22. package/package.json +28 -0
  23. package/skills/bullmq/SKILL.md +225 -0
  24. package/skills/bullmq/references/flows-and-schedulers.md +186 -0
  25. package/skills/bullmq/references/job-types-and-options.md +163 -0
  26. package/skills/bullmq/references/patterns.md +273 -0
  27. package/skills/bullmq/references/production.md +308 -0
  28. package/skills/composition-patterns/SKILL.md +58 -0
  29. package/skills/composition-patterns/references/architecture-avoid-boolean-props.md +87 -0
  30. package/skills/composition-patterns/references/architecture-compound-components.md +107 -0
  31. package/skills/composition-patterns/references/patterns-children-over-render-props.md +77 -0
  32. package/skills/composition-patterns/references/patterns-explicit-variants.md +87 -0
  33. package/skills/composition-patterns/references/react19-no-forwardref.md +37 -0
  34. package/skills/composition-patterns/references/state-context-interface.md +194 -0
  35. package/skills/composition-patterns/references/state-decouple-implementation.md +96 -0
  36. package/skills/composition-patterns/references/state-lift-state.md +126 -0
  37. package/skills/conventional-commits/SKILL.md +148 -0
  38. package/skills/docker/SKILL.md +55 -0
  39. package/skills/docker/references/compose-configs.md +95 -0
  40. package/skills/docker/references/monorepo-dockerfile.md +111 -0
  41. package/skills/drizzle-pg/SKILL.md +202 -0
  42. package/skills/drizzle-pg/references/advanced.md +299 -0
  43. package/skills/drizzle-pg/references/migrations.md +214 -0
  44. package/skills/drizzle-pg/references/queries.md +321 -0
  45. package/skills/drizzle-pg/references/relations.md +272 -0
  46. package/skills/drizzle-pg/references/schema-pg.md +256 -0
  47. package/skills/drizzle-pg/references/sql-operator.md +215 -0
  48. package/skills/fastify-best-practices/SKILL.md +143 -0
  49. package/skills/fastify-best-practices/references/hooks-and-lifecycle.md +122 -0
  50. package/skills/fastify-best-practices/references/plugins-and-encapsulation.md +137 -0
  51. package/skills/fastify-best-practices/references/request-reply-errors.md +189 -0
  52. package/skills/fastify-best-practices/references/routes-and-handlers.md +134 -0
  53. package/skills/fastify-best-practices/references/server-and-options.md +127 -0
  54. package/skills/fastify-best-practices/references/typescript-and-logging.md +223 -0
  55. package/skills/fastify-best-practices/references/validation-and-serialization.md +190 -0
  56. package/skills/ioredis/SKILL.md +51 -0
  57. package/skills/ioredis/references/advanced-patterns.md +312 -0
  58. package/skills/ioredis/references/cluster-sentinel.md +280 -0
  59. package/skills/ioredis/references/connection-options.md +187 -0
  60. package/skills/ioredis/references/core-api.md +179 -0
  61. package/skills/nextjs-best-practices/SKILL.md +194 -0
  62. package/skills/nextjs-best-practices/references/async-patterns.md +84 -0
  63. package/skills/nextjs-best-practices/references/bundling.md +192 -0
  64. package/skills/nextjs-best-practices/references/data-patterns.md +310 -0
  65. package/skills/nextjs-best-practices/references/debug-tricks.md +127 -0
  66. package/skills/nextjs-best-practices/references/directives.md +74 -0
  67. package/skills/nextjs-best-practices/references/error-handling.md +237 -0
  68. package/skills/nextjs-best-practices/references/file-conventions.md +152 -0
  69. package/skills/nextjs-best-practices/references/font.md +175 -0
  70. package/skills/nextjs-best-practices/references/functions.md +116 -0
  71. package/skills/nextjs-best-practices/references/hydration-error.md +86 -0
  72. package/skills/nextjs-best-practices/references/image.md +184 -0
  73. package/skills/nextjs-best-practices/references/metadata.md +305 -0
  74. package/skills/nextjs-best-practices/references/parallel-routes.md +299 -0
  75. package/skills/nextjs-best-practices/references/route-handlers.md +154 -0
  76. package/skills/nextjs-best-practices/references/rsc-boundaries.md +168 -0
  77. package/skills/nextjs-best-practices/references/runtime-selection.md +40 -0
  78. package/skills/nextjs-best-practices/references/scripts.md +148 -0
  79. package/skills/nextjs-best-practices/references/self-hosting.md +210 -0
  80. package/skills/nextjs-best-practices/references/suspense-boundaries.md +67 -0
  81. package/skills/owasp-security-review/SKILL.md +98 -0
  82. package/skills/owasp-security-review/references/a01-broken-access-control.md +78 -0
  83. package/skills/owasp-security-review/references/a02-security-misconfiguration.md +81 -0
  84. package/skills/owasp-security-review/references/a03-supply-chain-failures.md +65 -0
  85. package/skills/owasp-security-review/references/a04-cryptographic-failures.md +82 -0
  86. package/skills/owasp-security-review/references/a05-injection.md +106 -0
  87. package/skills/owasp-security-review/references/a06-insecure-design.md +76 -0
  88. package/skills/owasp-security-review/references/a07-authentication-failures.md +83 -0
  89. package/skills/owasp-security-review/references/a08-integrity-failures.md +72 -0
  90. package/skills/owasp-security-review/references/a09-logging-alerting-failures.md +76 -0
  91. package/skills/owasp-security-review/references/a10-exceptional-conditions.md +131 -0
  92. package/skills/postgresql/SKILL.md +50 -0
  93. package/skills/postgresql/references/ddl-schema.md +300 -0
  94. package/skills/postgresql/references/indexes.md +257 -0
  95. package/skills/postgresql/references/jsonb.md +261 -0
  96. package/skills/postgresql/references/performance.md +291 -0
  97. package/skills/postgresql/references/psql-cli.md +153 -0
  98. package/skills/postgresql/references/queries.md +287 -0
  99. package/skills/postgresql/references/transactions.md +280 -0
  100. package/skills/react-best-practices/SKILL.md +110 -0
  101. package/skills/react-best-practices/references/advanced-patterns.md +91 -0
  102. package/skills/react-best-practices/references/async-patterns.md +233 -0
  103. package/skills/react-best-practices/references/bundle-optimization.md +201 -0
  104. package/skills/react-best-practices/references/client-patterns.md +178 -0
  105. package/skills/react-best-practices/references/js-performance.md +210 -0
  106. package/skills/react-best-practices/references/rendering-performance.md +209 -0
  107. package/skills/react-best-practices/references/rerender-optimization.md +316 -0
  108. package/skills/react-best-practices/references/server-performance.md +274 -0
  109. package/skills/service-worker/SKILL.md +195 -0
  110. package/skills/service-worker/references/api-reference.md +114 -0
  111. package/skills/service-worker/references/caching-strategies.md +202 -0
  112. package/skills/service-worker/references/push-and-sync.md +261 -0
  113. package/skills/typescript-conventions/SKILL.md +51 -0
  114. package/skills/ui-ux-guidelines/SKILL.md +105 -0
  115. package/skills/ui-ux-guidelines/references/accessibility-and-interaction.md +74 -0
  116. package/skills/ui-ux-guidelines/references/forms-content-checklist.md +126 -0
  117. package/skills/ui-ux-guidelines/references/layout-typography-animation.md +95 -0
@@ -0,0 +1,210 @@
1
+ # JavaScript Performance
2
+
3
+ Low-level JS optimizations for DOM manipulation, caching, and data structures.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Avoid Layout Thrashing](#avoid-layout-thrashing)
8
+ - [Cache Repeated Function Calls](#cache-repeated-function-calls)
9
+ - [Cache Storage API Calls](#cache-storage-api-calls)
10
+ - [Build Index Maps for Repeated Lookups](#build-index-maps-for-repeated-lookups)
11
+ - [Use Loop for Min/Max Instead of Sort](#use-loop-for-minmax-instead-of-sort)
12
+
13
+ ---
14
+
15
+ ## Avoid Layout Thrashing
16
+
17
+ Avoid interleaving style writes with layout reads. Reading layout properties (`offsetWidth`, `getBoundingClientRect()`, `getComputedStyle()`) between style changes forces a synchronous reflow.
18
+
19
+ **Incorrect (interleaved reads and writes):**
20
+
21
+ ```typescript
22
+ function layoutThrashing(element: HTMLElement) {
23
+ element.style.width = "100px";
24
+ const width = element.offsetWidth; // Forces reflow
25
+ element.style.height = "200px";
26
+ const height = element.offsetHeight; // Forces another reflow
27
+ }
28
+ ```
29
+
30
+ **Correct (batch writes, then read once):**
31
+
32
+ ```typescript
33
+ function updateElementStyles(element: HTMLElement) {
34
+ element.style.width = "100px";
35
+ element.style.height = "200px";
36
+ element.style.backgroundColor = "blue";
37
+ element.style.border = "1px solid black";
38
+
39
+ const { width, height } = element.getBoundingClientRect();
40
+ }
41
+ ```
42
+
43
+ **Better: use CSS classes:**
44
+
45
+ ```typescript
46
+ element.classList.add("highlighted-box");
47
+ const { width, height } = element.getBoundingClientRect();
48
+ ```
49
+
50
+ **React example:**
51
+
52
+ ```tsx
53
+ // Incorrect
54
+ useEffect(() => {
55
+ ref.current.style.width = "100px";
56
+ const width = ref.current.offsetWidth; // Forces layout
57
+ ref.current.style.height = "200px";
58
+ }, [isHighlighted]);
59
+
60
+ // Correct: toggle class
61
+ <div className={isHighlighted ? "highlighted-box" : ""}>Content</div>;
62
+ ```
63
+
64
+ Prefer CSS classes over inline styles. See [layout-forcing properties gist](https://gist.github.com/paulirish/5d52fb081b3570c81e3a) for more information.
65
+
66
+ ---
67
+
68
+ ## Cache Repeated Function Calls
69
+
70
+ Use a module-level Map to cache function results when the same function is called repeatedly with the same inputs.
71
+
72
+ **Incorrect (redundant computation):**
73
+
74
+ ```typescript
75
+ function ProjectList({ projects }: { projects: Project[] }) {
76
+ return (
77
+ <div>
78
+ {projects.map((project) => {
79
+ const slug = slugify(project.name); // Called 100+ times for same names
80
+ return <ProjectCard key={project.id} slug={slug} />;
81
+ })}
82
+ </div>
83
+ );
84
+ }
85
+ ```
86
+
87
+ **Correct (cached results):**
88
+
89
+ ```typescript
90
+ const slugifyCache = new Map<string, string>();
91
+
92
+ function cachedSlugify(text: string): string {
93
+ if (slugifyCache.has(text)) return slugifyCache.get(text)!;
94
+ const result = slugify(text);
95
+ slugifyCache.set(text, result);
96
+ return result;
97
+ }
98
+ ```
99
+
100
+ Use a Map (not a hook) so it works everywhere: utilities, event handlers, not just React components.
101
+
102
+ Reference: [How we made the Vercel Dashboard twice as fast](https://vercel.com/blog/how-we-made-the-vercel-dashboard-twice-as-fast)
103
+
104
+ ---
105
+
106
+ ## Cache Storage API Calls
107
+
108
+ `localStorage`, `sessionStorage`, and `document.cookie` are synchronous and expensive. Cache reads in memory.
109
+
110
+ **Incorrect (reads storage on every call):**
111
+
112
+ ```typescript
113
+ function getTheme() {
114
+ return localStorage.getItem("theme") ?? "light";
115
+ }
116
+ // Called 10 times = 10 storage reads
117
+ ```
118
+
119
+ **Correct (Map cache):**
120
+
121
+ ```typescript
122
+ const storageCache = new Map<string, string | null>();
123
+
124
+ function getLocalStorage(key: string) {
125
+ if (!storageCache.has(key)) {
126
+ storageCache.set(key, localStorage.getItem(key));
127
+ }
128
+ return storageCache.get(key);
129
+ }
130
+
131
+ function setLocalStorage(key: string, value: string) {
132
+ localStorage.setItem(key, value);
133
+ storageCache.set(key, value);
134
+ }
135
+ ```
136
+
137
+ **Invalidate on external changes:**
138
+
139
+ ```typescript
140
+ window.addEventListener("storage", (e) => {
141
+ if (e.key) storageCache.delete(e.key);
142
+ });
143
+
144
+ document.addEventListener("visibilitychange", () => {
145
+ if (document.visibilityState === "visible") storageCache.clear();
146
+ });
147
+ ```
148
+
149
+ ---
150
+
151
+ ## Build Index Maps for Repeated Lookups
152
+
153
+ Multiple `.find()` calls by the same key should use a Map.
154
+
155
+ **Incorrect (O(n) per lookup):**
156
+
157
+ ```typescript
158
+ function processOrders(orders: Order[], users: User[]) {
159
+ return orders.map((order) => ({
160
+ ...order,
161
+ user: users.find((u) => u.id === order.userId),
162
+ }));
163
+ }
164
+ ```
165
+
166
+ **Correct (O(1) per lookup):**
167
+
168
+ ```typescript
169
+ function processOrders(orders: Order[], users: User[]) {
170
+ const userById = new Map(users.map((u) => [u.id, u]));
171
+
172
+ return orders.map((order) => ({
173
+ ...order,
174
+ user: userById.get(order.userId),
175
+ }));
176
+ }
177
+ ```
178
+
179
+ Build map once O(n), then all lookups are O(1). For 1000 orders x 1000 users: 1M ops down to 2K ops.
180
+
181
+ ---
182
+
183
+ ## Use Loop for Min/Max Instead of Sort
184
+
185
+ Finding the smallest or largest element only requires a single pass. Sorting is O(n log n) waste.
186
+
187
+ **Incorrect (O(n log n)):**
188
+
189
+ ```typescript
190
+ function getLatestProject(projects: Project[]) {
191
+ const sorted = [...projects].sort((a, b) => b.updatedAt - a.updatedAt);
192
+ return sorted[0];
193
+ }
194
+ ```
195
+
196
+ **Correct (O(n)):**
197
+
198
+ ```typescript
199
+ function getLatestProject(projects: Project[]) {
200
+ if (projects.length === 0) return null;
201
+
202
+ let latest = projects[0];
203
+ for (let i = 1; i < projects.length; i++) {
204
+ if (projects[i].updatedAt > latest.updatedAt) latest = projects[i];
205
+ }
206
+ return latest;
207
+ }
208
+ ```
209
+
210
+ `Math.min(...arr)` / `Math.max(...arr)` works for small arrays but throws on very large arrays due to spread operator limitations (~124K in Chrome, ~638K in Safari).
@@ -0,0 +1,209 @@
1
+ # Rendering Performance
2
+
3
+ Optimize DOM rendering, hydration, and visual transitions.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Animate SVG Wrapper Instead of SVG Element](#animate-svg-wrapper-instead-of-svg-element)
8
+ - [CSS content-visibility for Long Lists](#css-content-visibility-for-long-lists)
9
+ - [Hoist Static JSX Elements](#hoist-static-jsx-elements)
10
+ - [Prevent Hydration Mismatch Without Flickering](#prevent-hydration-mismatch-without-flickering)
11
+ - [Use useTransition Over Manual Loading States](#use-usetransition-over-manual-loading-states)
12
+
13
+ ---
14
+
15
+ ## Animate SVG Wrapper Instead of SVG Element
16
+
17
+ Many browsers don't have hardware acceleration for CSS3 animations on SVG elements. Wrap SVG in a `<div>` and animate the wrapper instead.
18
+
19
+ **Incorrect (no hardware acceleration):**
20
+
21
+ ```tsx
22
+ function LoadingSpinner() {
23
+ return (
24
+ <svg className="animate-spin" width="24" height="24" viewBox="0 0 24 24">
25
+ <circle cx="12" cy="12" r="10" stroke="currentColor" />
26
+ </svg>
27
+ );
28
+ }
29
+ ```
30
+
31
+ **Correct (hardware accelerated):**
32
+
33
+ ```tsx
34
+ function LoadingSpinner() {
35
+ return (
36
+ <div className="animate-spin">
37
+ <svg width="24" height="24" viewBox="0 0 24 24">
38
+ <circle cx="12" cy="12" r="10" stroke="currentColor" />
39
+ </svg>
40
+ </div>
41
+ );
42
+ }
43
+ ```
44
+
45
+ Applies to all CSS transforms and transitions (`transform`, `opacity`, `translate`, `scale`, `rotate`).
46
+
47
+ ---
48
+
49
+ ## CSS content-visibility for Long Lists
50
+
51
+ Apply `content-visibility: auto` to defer off-screen rendering.
52
+
53
+ ```css
54
+ .message-item {
55
+ content-visibility: auto;
56
+ contain-intrinsic-size: 0 80px;
57
+ }
58
+ ```
59
+
60
+ ```tsx
61
+ function MessageList({ messages }: { messages: Message[] }) {
62
+ return (
63
+ <div className="overflow-y-auto h-screen">
64
+ {messages.map((msg) => (
65
+ <div key={msg.id} className="message-item">
66
+ <Avatar user={msg.author} />
67
+ <div>{msg.content}</div>
68
+ </div>
69
+ ))}
70
+ </div>
71
+ );
72
+ }
73
+ ```
74
+
75
+ For 1000 messages, browser skips layout/paint for ~990 off-screen items (10x faster initial render).
76
+
77
+ ---
78
+
79
+ ## Hoist Static JSX Elements
80
+
81
+ Extract static JSX outside components to avoid re-creation.
82
+
83
+ **Incorrect (recreates element every render):**
84
+
85
+ ```tsx
86
+ function LoadingSkeleton() {
87
+ return <div className="animate-pulse h-20 bg-gray-200" />;
88
+ }
89
+
90
+ function Container() {
91
+ return <div>{loading && <LoadingSkeleton />}</div>;
92
+ }
93
+ ```
94
+
95
+ **Correct (reuses same element):**
96
+
97
+ ```tsx
98
+ const loadingSkeleton = <div className="animate-pulse h-20 bg-gray-200" />;
99
+
100
+ function Container() {
101
+ return <div>{loading && loadingSkeleton}</div>;
102
+ }
103
+ ```
104
+
105
+ Especially helpful for large and static SVG nodes. React Compiler automatically hoists static JSX when enabled.
106
+
107
+ ---
108
+
109
+ ## Prevent Hydration Mismatch Without Flickering
110
+
111
+ When rendering content that depends on client-side storage (localStorage, cookies), avoid both SSR breakage and post-hydration flickering by injecting a synchronous inline script that updates the DOM before React hydrates.
112
+
113
+ **Incorrect (visual flickering):**
114
+
115
+ ```tsx
116
+ function ThemeWrapper({ children }: { children: ReactNode }) {
117
+ const [theme, setTheme] = useState("light");
118
+
119
+ useEffect(() => {
120
+ const stored = localStorage.getItem("theme");
121
+ if (stored) setTheme(stored);
122
+ }, []);
123
+
124
+ return <div className={theme}>{children}</div>;
125
+ }
126
+ ```
127
+
128
+ **Correct (no flicker, no hydration mismatch):**
129
+
130
+ Use an inline `<script>` tag with a self-executing function that reads localStorage synchronously and sets the className on the wrapper element before React hydrates. The script runs before the browser paints, ensuring correct initial render.
131
+
132
+ ```tsx
133
+ function ThemeWrapper({ children }: { children: ReactNode }) {
134
+ return (
135
+ <>
136
+ <div id="theme-wrapper">{children}</div>
137
+ {/* Inline script reads localStorage and sets className synchronously */}
138
+ <ThemeScript />
139
+ </>
140
+ );
141
+ }
142
+ ```
143
+
144
+ The inline script executes synchronously before showing the element. Useful for theme toggles, user preferences, and authentication states.
145
+
146
+ ---
147
+
148
+ ## Use useTransition Over Manual Loading States
149
+
150
+ Use `useTransition` instead of manual `useState` for loading states. Provides built-in `isPending` state and automatically manages transitions.
151
+
152
+ **Incorrect (manual loading state):**
153
+
154
+ ```tsx
155
+ function SearchResults() {
156
+ const [query, setQuery] = useState("");
157
+ const [results, setResults] = useState([]);
158
+ const [isLoading, setIsLoading] = useState(false);
159
+
160
+ const handleSearch = async (value: string) => {
161
+ setIsLoading(true);
162
+ setQuery(value);
163
+ const data = await fetchResults(value);
164
+ setResults(data);
165
+ setIsLoading(false);
166
+ };
167
+
168
+ return (
169
+ <>
170
+ <input onChange={(e) => handleSearch(e.target.value)} />
171
+ {isLoading && <Spinner />}
172
+ <ResultsList results={results} />
173
+ </>
174
+ );
175
+ }
176
+ ```
177
+
178
+ **Correct (useTransition):**
179
+
180
+ ```tsx
181
+ import { useTransition, useState } from "react";
182
+
183
+ function SearchResults() {
184
+ const [query, setQuery] = useState("");
185
+ const [results, setResults] = useState([]);
186
+ const [isPending, startTransition] = useTransition();
187
+
188
+ const handleSearch = (value: string) => {
189
+ setQuery(value);
190
+
191
+ startTransition(async () => {
192
+ const data = await fetchResults(value);
193
+ setResults(data);
194
+ });
195
+ };
196
+
197
+ return (
198
+ <>
199
+ <input onChange={(e) => handleSearch(e.target.value)} />
200
+ {isPending && <Spinner />}
201
+ <ResultsList results={results} />
202
+ </>
203
+ );
204
+ }
205
+ ```
206
+
207
+ Benefits: automatic pending state, error resilience, better responsiveness, interrupt handling (new transitions cancel pending ones).
208
+
209
+ Reference: [useTransition](https://react.dev/reference/react/useTransition)