@xonovex/skills 0.1.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.
- package/.claude-plugin/plugin.json +21 -0
- package/commands/code-align.md +108 -0
- package/commands/code-harden.md +74 -0
- package/commands/code-simplify.md +145 -0
- package/commands/git-commit.md +146 -0
- package/commands/insights-extract.md +109 -0
- package/commands/insights-integrate.md +100 -0
- package/commands/plan-continue.md +167 -0
- package/commands/plan-create.md +107 -0
- package/commands/plan-research.md +113 -0
- package/commands/plan-subplans-create.md +111 -0
- package/commands/plan-tdd-create.md +128 -0
- package/commands/plan-update.md +99 -0
- package/commands/plan-validate.md +100 -0
- package/commands/plan-worktree-abandon.md +104 -0
- package/commands/plan-worktree-create.md +92 -0
- package/commands/plan-worktree-merge.md +132 -0
- package/package.json +44 -0
- package/skills/astro-guidelines/SKILL.md +23 -0
- package/skills/astro-guidelines/reference/accessibility.md +31 -0
- package/skills/astro-guidelines/reference/components.md +42 -0
- package/skills/astro-guidelines/reference/content-collections.md +32 -0
- package/skills/astro-guidelines/reference/islands-architecture.md +26 -0
- package/skills/astro-guidelines/reference/project-structure.md +32 -0
- package/skills/c99-game-opinionated-guidelines/SKILL.md +43 -0
- package/skills/c99-game-opinionated-guidelines/reference/builder-pattern.md +29 -0
- package/skills/c99-game-opinionated-guidelines/reference/coordinate-system.md +27 -0
- package/skills/c99-game-opinionated-guidelines/reference/geometry-pipeline.md +29 -0
- package/skills/c99-game-opinionated-guidelines/reference/math-types.md +31 -0
- package/skills/c99-game-opinionated-guidelines/reference/mesh-types.md +32 -0
- package/skills/c99-game-opinionated-guidelines/reference/physics-patterns.md +28 -0
- package/skills/c99-game-opinionated-guidelines/reference/spatial-structures.md +26 -0
- package/skills/c99-game-opinionated-guidelines/reference/tagged-unions.md +40 -0
- package/skills/c99-game-opinionated-guidelines/reference/vertex-packing.md +38 -0
- package/skills/c99-guidelines/SKILL.md +29 -0
- package/skills/c99-guidelines/reference/compound-literals.md +33 -0
- package/skills/c99-guidelines/reference/const-correctness.md +32 -0
- package/skills/c99-guidelines/reference/designated-initializers.md +32 -0
- package/skills/c99-guidelines/reference/error-handling.md +49 -0
- package/skills/c99-guidelines/reference/inline-functions.md +37 -0
- package/skills/c99-guidelines/reference/memory-management.md +35 -0
- package/skills/c99-opinionated-guidelines/SKILL.md +44 -0
- package/skills/c99-opinionated-guidelines/reference/alignment.md +50 -0
- package/skills/c99-opinionated-guidelines/reference/caller-owns-memory.md +38 -0
- package/skills/c99-opinionated-guidelines/reference/compound-literals.md +33 -0
- package/skills/c99-opinionated-guidelines/reference/const-correctness.md +32 -0
- package/skills/c99-opinionated-guidelines/reference/data-oriented-design.md +42 -0
- package/skills/c99-opinionated-guidelines/reference/designated-initializers.md +32 -0
- package/skills/c99-opinionated-guidelines/reference/error-handling.md +49 -0
- package/skills/c99-opinionated-guidelines/reference/file-naming.md +33 -0
- package/skills/c99-opinionated-guidelines/reference/implementation-variants.md +35 -0
- package/skills/c99-opinionated-guidelines/reference/inline-functions.md +37 -0
- package/skills/c99-opinionated-guidelines/reference/memory-management.md +35 -0
- package/skills/c99-opinionated-guidelines/reference/safety-validations.md +32 -0
- package/skills/c99-opinionated-guidelines/reference/testing-patterns.md +39 -0
- package/skills/cmake-guidelines/SKILL.md +31 -0
- package/skills/cmake-guidelines/reference/compile-options.md +34 -0
- package/skills/cmake-guidelines/reference/fetchcontent.md +32 -0
- package/skills/cmake-guidelines/reference/find-package.md +29 -0
- package/skills/cmake-guidelines/reference/generator-expressions.md +34 -0
- package/skills/cmake-guidelines/reference/installation.md +38 -0
- package/skills/cmake-guidelines/reference/project-structure.md +40 -0
- package/skills/cmake-guidelines/reference/target-types.md +37 -0
- package/skills/cmake-guidelines/reference/testing.md +30 -0
- package/skills/cmake-guidelines/reference/visibility-specifiers.md +32 -0
- package/skills/content-guidelines/SKILL.md +36 -0
- package/skills/content-guidelines/reference/humanize.md +30 -0
- package/skills/content-guidelines/reference/news.md +28 -0
- package/skills/content-guidelines/reference/travelguide.md +31 -0
- package/skills/docker-guidelines/SKILL.md +23 -0
- package/skills/docker-guidelines/reference/docker-compose.md +40 -0
- package/skills/docker-guidelines/reference/layer-caching.md +25 -0
- package/skills/docker-guidelines/reference/multi-stage-builds.md +37 -0
- package/skills/docker-guidelines/reference/production-config.md +32 -0
- package/skills/docker-guidelines/reference/security.md +27 -0
- package/skills/express.js-guidelines/SKILL.md +32 -0
- package/skills/express.js-guidelines/reference/app-setup.md +39 -0
- package/skills/express.js-guidelines/reference/authentication.md +39 -0
- package/skills/express.js-guidelines/reference/controllers.md +49 -0
- package/skills/express.js-guidelines/reference/error-handling.md +54 -0
- package/skills/express.js-guidelines/reference/project-structure.md +29 -0
- package/skills/express.js-guidelines/reference/responses.md +30 -0
- package/skills/express.js-guidelines/reference/routes.md +29 -0
- package/skills/express.js-guidelines/reference/testing.md +39 -0
- package/skills/express.js-guidelines/reference/validation.md +41 -0
- package/skills/general-fp-guidelines/SKILL.md +28 -0
- package/skills/general-oop-guidelines/SKILL.md +28 -0
- package/skills/git-guidelines/SKILL.md +46 -0
- package/skills/git-guidelines/reference/commit.md +32 -0
- package/skills/git-guidelines/reference/merge-resolve.md +38 -0
- package/skills/git-guidelines/reference/worktree-abandon.md +48 -0
- package/skills/git-guidelines/reference/worktree-cleanup.md +40 -0
- package/skills/git-guidelines/reference/worktree-commit.md +46 -0
- package/skills/git-guidelines/reference/worktree-create.md +42 -0
- package/skills/git-guidelines/reference/worktree-merge.md +45 -0
- package/skills/git-guidelines/reference/worktree-validate.md +44 -0
- package/skills/hono-guidelines/SKILL.md +49 -0
- package/skills/hono-guidelines/reference/application-structure.md +53 -0
- package/skills/hono-guidelines/reference/context-storage.md +46 -0
- package/skills/hono-guidelines/reference/cookie-handling.md +63 -0
- package/skills/hono-guidelines/reference/error-handling.md +69 -0
- package/skills/hono-guidelines/reference/middleware-combine.md +47 -0
- package/skills/hono-guidelines/reference/middleware-patterns.md +58 -0
- package/skills/hono-guidelines/reference/platform-runtime.md +41 -0
- package/skills/hono-guidelines/reference/security-middleware.md +60 -0
- package/skills/hono-guidelines/reference/validation-type-safety.md +43 -0
- package/skills/hono-guidelines/reference/websocket-support.md +59 -0
- package/skills/hono-opinionated-guidelines/SKILL.md +49 -0
- package/skills/hono-opinionated-guidelines/reference/application-structure.md +53 -0
- package/skills/hono-opinionated-guidelines/reference/body-limit.md +57 -0
- package/skills/hono-opinionated-guidelines/reference/context-storage.md +46 -0
- package/skills/hono-opinionated-guidelines/reference/controllers.md +38 -0
- package/skills/hono-opinionated-guidelines/reference/cookie-handling.md +63 -0
- package/skills/hono-opinionated-guidelines/reference/error-handling.md +69 -0
- package/skills/hono-opinionated-guidelines/reference/middleware-combine.md +47 -0
- package/skills/hono-opinionated-guidelines/reference/middleware-patterns.md +58 -0
- package/skills/hono-opinionated-guidelines/reference/openapi-explicit-status-codes.md +61 -0
- package/skills/hono-opinionated-guidelines/reference/openapi-inline-handlers.md +56 -0
- package/skills/hono-opinionated-guidelines/reference/openapi-router-hierarchy.md +64 -0
- package/skills/hono-opinionated-guidelines/reference/openapi-spec-generation.md +57 -0
- package/skills/hono-opinionated-guidelines/reference/platform-runtime.md +41 -0
- package/skills/hono-opinionated-guidelines/reference/router-selection.md +34 -0
- package/skills/hono-opinionated-guidelines/reference/security-middleware.md +60 -0
- package/skills/hono-opinionated-guidelines/reference/validation-type-safety.md +43 -0
- package/skills/hono-opinionated-guidelines/reference/websocket-support.md +59 -0
- package/skills/insights-guidelines/SKILL.md +28 -0
- package/skills/insights-guidelines/reference/insights-extract.md +31 -0
- package/skills/insights-guidelines/reference/insights-integrate.md +35 -0
- package/skills/instruction-guidelines/SKILL.md +26 -0
- package/skills/instruction-guidelines/reference/assimilate.md +38 -0
- package/skills/instruction-guidelines/reference/simplify.md +46 -0
- package/skills/instruction-guidelines/reference/sync.md +41 -0
- package/skills/kubernetes-guidelines/SKILL.md +28 -0
- package/skills/kubernetes-guidelines/reference/configmaps-secrets.md +34 -0
- package/skills/kubernetes-guidelines/reference/deployments.md +55 -0
- package/skills/kubernetes-guidelines/reference/kustomize.md +41 -0
- package/skills/kubernetes-guidelines/reference/network-policies.md +53 -0
- package/skills/kubernetes-guidelines/reference/services.md +36 -0
- package/skills/kubernetes-guidelines/reference/validation.md +32 -0
- package/skills/lua-guidelines/SKILL.md +29 -0
- package/skills/lua-guidelines/reference/coroutines.md +66 -0
- package/skills/lua-guidelines/reference/error-handling.md +41 -0
- package/skills/lua-guidelines/reference/idiomatic-patterns.md +40 -0
- package/skills/lua-guidelines/reference/input-validation.md +42 -0
- package/skills/lua-guidelines/reference/local-variables.md +33 -0
- package/skills/lua-guidelines/reference/metatables.md +52 -0
- package/skills/lua-guidelines/reference/module-pattern.md +37 -0
- package/skills/lua-guidelines/reference/string-concatenation.md +31 -0
- package/skills/lua-opinionated-guidelines/SKILL.md +32 -0
- package/skills/lua-opinionated-guidelines/reference/cache-lookups.md +43 -0
- package/skills/lua-opinionated-guidelines/reference/coroutines.md +66 -0
- package/skills/lua-opinionated-guidelines/reference/error-handling.md +41 -0
- package/skills/lua-opinionated-guidelines/reference/idiomatic-patterns.md +40 -0
- package/skills/lua-opinionated-guidelines/reference/input-validation.md +42 -0
- package/skills/lua-opinionated-guidelines/reference/jit-friendly-tables.md +57 -0
- package/skills/lua-opinionated-guidelines/reference/local-variables.md +33 -0
- package/skills/lua-opinionated-guidelines/reference/metatables.md +52 -0
- package/skills/lua-opinionated-guidelines/reference/module-pattern.md +37 -0
- package/skills/lua-opinionated-guidelines/reference/string-concatenation.md +31 -0
- package/skills/moon-guidelines/SKILL.md +30 -0
- package/skills/moon-guidelines/reference/docker-multistage.md +42 -0
- package/skills/moon-guidelines/reference/project-constraints.md +25 -0
- package/skills/moon-guidelines/reference/query-language.md +27 -0
- package/skills/moon-guidelines/reference/tag-based-filtering.md +28 -0
- package/skills/moon-guidelines/reference/task-configuration.md +38 -0
- package/skills/moon-guidelines/reference/task-inheritance.md +30 -0
- package/skills/motion-react-guidelines/SKILL.md +66 -0
- package/skills/motion-react-guidelines/reference/3d-effects.md +35 -0
- package/skills/motion-react-guidelines/reference/entrance.md +36 -0
- package/skills/motion-react-guidelines/reference/exit.md +35 -0
- package/skills/motion-react-guidelines/reference/gestures.md +23 -0
- package/skills/motion-react-guidelines/reference/layout.md +39 -0
- package/skills/motion-react-guidelines/reference/motion-values.md +33 -0
- package/skills/motion-react-guidelines/reference/performance.md +32 -0
- package/skills/motion-react-guidelines/reference/scroll.md +38 -0
- package/skills/motion-react-guidelines/reference/spring-physics.md +40 -0
- package/skills/motion-react-guidelines/reference/stagger.md +34 -0
- package/skills/motion-react-guidelines/reference/svg-path.md +33 -0
- package/skills/motion-react-guidelines/reference/text-effects.md +39 -0
- package/skills/plan-guidelines/SKILL.md +56 -0
- package/skills/plan-guidelines/reference/code-align.md +23 -0
- package/skills/plan-guidelines/reference/code-barrels-remove.md +24 -0
- package/skills/plan-guidelines/reference/code-comments-remove.md +28 -0
- package/skills/plan-guidelines/reference/code-harden.md +30 -0
- package/skills/plan-guidelines/reference/code-shared-extract.md +25 -0
- package/skills/plan-guidelines/reference/code-simplify.md +33 -0
- package/skills/plan-guidelines/reference/code-template-extract.md +34 -0
- package/skills/plan-guidelines/reference/code-template-scaffold.md +36 -0
- package/skills/plan-guidelines/reference/general-research.md +35 -0
- package/skills/plan-guidelines/reference/plan-create.md +37 -0
- package/skills/plan-guidelines/reference/plan-tdd-create.md +44 -0
- package/skills/plan-guidelines/reference/todos.md +39 -0
- package/skills/presentation-guidelines/SKILL.md +25 -0
- package/skills/presentation-guidelines/reference/presentation-create.md +41 -0
- package/skills/presentation-guidelines/reference/presentation-motion-scaffold.md +38 -0
- package/skills/python-guidelines/SKILL.md +32 -0
- package/skills/python-guidelines/reference/async-await-patterns.md +62 -0
- package/skills/python-guidelines/reference/caching-functions.md +47 -0
- package/skills/python-guidelines/reference/dataclasses-type-hints.md +63 -0
- package/skills/python-guidelines/reference/exception-handling.md +72 -0
- package/skills/python-guidelines/reference/generators-comprehensions.md +54 -0
- package/skills/python-guidelines/reference/pathlib-file-ops.md +60 -0
- package/skills/python-guidelines/reference/resource-management.md +58 -0
- package/skills/python-guidelines/reference/string-formatting.md +41 -0
- package/skills/python-guidelines/reference/type-checking.md +47 -0
- package/skills/react-guidelines/SKILL.md +105 -0
- package/skills/react-guidelines/reference/accessibility.md +31 -0
- package/skills/react-guidelines/reference/activity-effect-event.md +42 -0
- package/skills/react-guidelines/reference/component-design.md +57 -0
- package/skills/react-guidelines/reference/hooks.md +39 -0
- package/skills/react-guidelines/reference/migration-anti-patterns.md +33 -0
- package/skills/react-guidelines/reference/migration-deprecations.md +109 -0
- package/skills/react-guidelines/reference/migration-paradigm-shifts.md +33 -0
- package/skills/react-guidelines/reference/migration-typescript.md +95 -0
- package/skills/react-guidelines/reference/new-hooks.md +94 -0
- package/skills/react-guidelines/reference/performance-optimization.md +41 -0
- package/skills/react-guidelines/reference/react-compiler.md +34 -0
- package/skills/react-guidelines/reference/server-components.md +99 -0
- package/skills/react-guidelines/reference/state-management.md +72 -0
- package/skills/react-guidelines/reference/suspense-streaming.md +36 -0
- package/skills/remotion-guidelines/SKILL.md +67 -0
- package/skills/remotion-guidelines/reference/animations.md +121 -0
- package/skills/remotion-guidelines/reference/assets.md +21 -0
- package/skills/remotion-guidelines/reference/captions.md +33 -0
- package/skills/remotion-guidelines/reference/charts.md +35 -0
- package/skills/remotion-guidelines/reference/compositions.md +40 -0
- package/skills/remotion-guidelines/reference/dom-measurement.md +82 -0
- package/skills/remotion-guidelines/reference/gifs.md +33 -0
- package/skills/remotion-guidelines/reference/lottie.md +41 -0
- package/skills/remotion-guidelines/reference/maps.md +26 -0
- package/skills/remotion-guidelines/reference/media.md +39 -0
- package/skills/remotion-guidelines/reference/mediabunny.md +28 -0
- package/skills/remotion-guidelines/reference/sequencing.md +44 -0
- package/skills/remotion-guidelines/reference/text.md +24 -0
- package/skills/remotion-guidelines/reference/three-d.md +33 -0
- package/skills/remotion-guidelines/reference/timing.md +22 -0
- package/skills/remotion-guidelines/reference/transitions.md +52 -0
- package/skills/shell-scripting-guidelines/SKILL.md +31 -0
- package/skills/shell-scripting-guidelines/reference/argument-parsing.md +67 -0
- package/skills/shell-scripting-guidelines/reference/common-patterns.md +46 -0
- package/skills/shell-scripting-guidelines/reference/error-handling.md +62 -0
- package/skills/shell-scripting-guidelines/reference/functions.md +66 -0
- package/skills/shell-scripting-guidelines/reference/idempotency.md +57 -0
- package/skills/shell-scripting-guidelines/reference/parameter-expansion.md +38 -0
- package/skills/shell-scripting-guidelines/reference/posix-compatibility.md +53 -0
- package/skills/shell-scripting-guidelines/reference/quoting.md +42 -0
- package/skills/shell-scripting-guidelines/reference/script-template.md +70 -0
- package/skills/shell-scripting-guidelines/reference/strict-mode.md +41 -0
- package/skills/shell-scripting-guidelines/reference/validation.md +30 -0
- package/skills/skill-guidelines/SKILL.md +33 -0
- package/skills/skill-guidelines/reference/assimilate.md +51 -0
- package/skills/skill-guidelines/reference/create.md +48 -0
- package/skills/skill-guidelines/reference/extract.md +48 -0
- package/skills/skill-guidelines/reference/simplify.md +56 -0
- package/skills/sql-postgresql-guidelines/SKILL.md +31 -0
- package/skills/sql-postgresql-guidelines/reference/constraints.md +47 -0
- package/skills/sql-postgresql-guidelines/reference/cte-patterns.md +42 -0
- package/skills/sql-postgresql-guidelines/reference/data-types.md +46 -0
- package/skills/sql-postgresql-guidelines/reference/indexing.md +45 -0
- package/skills/sql-postgresql-guidelines/reference/jsonb.md +54 -0
- package/skills/sql-postgresql-guidelines/reference/performance.md +46 -0
- package/skills/sql-postgresql-guidelines/reference/role-based-access.md +47 -0
- package/skills/sql-postgresql-guidelines/reference/row-level-security.md +66 -0
- package/skills/strudel-guidelines/SKILL.md +52 -0
- package/skills/strudel-guidelines/reference/arrangement.md +24 -0
- package/skills/strudel-guidelines/reference/conditionals.md +22 -0
- package/skills/strudel-guidelines/reference/effects.md +22 -0
- package/skills/strudel-guidelines/reference/genre-ambient.md +26 -0
- package/skills/strudel-guidelines/reference/genre-harsh.md +21 -0
- package/skills/strudel-guidelines/reference/genre-trance.md +23 -0
- package/skills/strudel-guidelines/reference/layering.md +22 -0
- package/skills/strudel-guidelines/reference/mini-notation.md +74 -0
- package/skills/strudel-guidelines/reference/modulation.md +22 -0
- package/skills/strudel-guidelines/reference/scales-harmony.md +20 -0
- package/skills/strudel-guidelines/reference/sounds.md +89 -0
- package/skills/strudel-guidelines/reference/tempo-timing.md +23 -0
- package/skills/terraform-guidelines/SKILL.md +28 -0
- package/skills/terraform-guidelines/reference/advanced-patterns.md +88 -0
- package/skills/terraform-guidelines/reference/locals.md +53 -0
- package/skills/terraform-guidelines/reference/module-definition.md +81 -0
- package/skills/terraform-guidelines/reference/module-structure.md +51 -0
- package/skills/terraform-guidelines/reference/remote-state.md +38 -0
- package/skills/terraform-guidelines/reference/root-module.md +71 -0
- package/skills/terraform-guidelines/reference/typed-variables.md +90 -0
- package/skills/threejs-guidelines/SKILL.md +38 -0
- package/skills/threejs-guidelines/reference/animation.md +26 -0
- package/skills/threejs-guidelines/reference/cameras-controls.md +26 -0
- package/skills/threejs-guidelines/reference/geometry.md +22 -0
- package/skills/threejs-guidelines/reference/interaction.md +25 -0
- package/skills/threejs-guidelines/reference/lighting-shadows.md +31 -0
- package/skills/threejs-guidelines/reference/loaders.md +29 -0
- package/skills/threejs-guidelines/reference/materials.md +25 -0
- package/skills/threejs-guidelines/reference/math.md +27 -0
- package/skills/threejs-guidelines/reference/node-materials.md +32 -0
- package/skills/threejs-guidelines/reference/patterns.md +29 -0
- package/skills/threejs-guidelines/reference/performance.md +24 -0
- package/skills/threejs-guidelines/reference/physics-vr.md +36 -0
- package/skills/threejs-guidelines/reference/postprocessing.md +26 -0
- package/skills/threejs-guidelines/reference/scene-fundamentals.md +26 -0
- package/skills/threejs-guidelines/reference/shaders.md +28 -0
- package/skills/threejs-guidelines/reference/textures.md +21 -0
- package/skills/threejs-guidelines/reference/webgpu.md +34 -0
- package/skills/typescript-guidelines/SKILL.md +37 -0
- package/skills/typescript-guidelines/reference/async-without-await.md +32 -0
- package/skills/typescript-guidelines/reference/avoid-barrel-exports.md +25 -0
- package/skills/typescript-guidelines/reference/avoid-eslint-disable.md +28 -0
- package/skills/typescript-guidelines/reference/avoid-reexports.md +26 -0
- package/skills/typescript-guidelines/reference/env-access-bracket-notation.md +29 -0
- package/skills/typescript-guidelines/reference/numeric-separator-enforcement.md +30 -0
- package/skills/typescript-guidelines/reference/template-literals-require-string-conversion.md +26 -0
- package/skills/typescript-guidelines/reference/unbound-method-references.md +32 -0
- package/skills/typescript-guidelines/reference/unnecessary-async-keywords.md +37 -0
- package/skills/typescript-to-lua-guidelines/SKILL.md +33 -0
- package/skills/typescript-to-lua-guidelines/reference/avoiding-heavy-features.md +41 -0
- package/skills/typescript-to-lua-guidelines/reference/coroutine-patterns.md +49 -0
- package/skills/typescript-to-lua-guidelines/reference/function-patterns.md +59 -0
- package/skills/typescript-to-lua-guidelines/reference/lua-interop.md +49 -0
- package/skills/typescript-to-lua-guidelines/reference/module-organization.md +42 -0
- package/skills/typescript-to-lua-guidelines/reference/multi-return-functions.md +47 -0
- package/skills/typescript-to-lua-guidelines/reference/namespaces-vs-classes.md +52 -0
- package/skills/typescript-to-lua-guidelines/reference/performance-tips.md +68 -0
- package/skills/typescript-to-lua-guidelines/reference/stable-tables.md +60 -0
- package/skills/typescript-to-lua-guidelines/reference/tsconfig.md +46 -0
- package/skills/typescript-to-lua-guidelines/reference/tstl-decorators.md +61 -0
- package/skills/typescript-to-lua-guidelines/reference/type-safety.md +79 -0
- package/skills/vitest-guidelines/SKILL.md +32 -0
- package/skills/vitest-guidelines/reference/cors-preflight-status-code.md +34 -0
- package/skills/vitest-guidelines/reference/http-testing.md +57 -0
- package/skills/vitest-guidelines/reference/json-response-type-safety.md +40 -0
- package/skills/vitest-guidelines/reference/mock-patterns.md +53 -0
- package/skills/vitest-guidelines/reference/project-references-path-resolution.md +36 -0
- package/skills/vitest-guidelines/reference/test-organization.md +25 -0
- package/skills/vitest-guidelines/reference/timestamp-testing.md +55 -0
- package/skills/vitest-guidelines/reference/type-safety.md +55 -0
- package/skills/vitest-guidelines/reference/typescript-config.md +43 -0
- package/skills/zod-guidelines/SKILL.md +33 -0
- package/skills/zod-guidelines/reference/default-values-output-type.md +63 -0
- package/skills/zod-guidelines/reference/migration-string-validators.md +38 -0
- package/skills/zod-guidelines/reference/migration-v4.md +46 -0
- package/skills/zod-guidelines/reference/schema-organization.md +73 -0
- package/skills/zod-guidelines/reference/validation-patterns.md +37 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# deprecations: React 19 Removed & Deprecated APIs
|
|
2
|
+
|
|
3
|
+
**Guideline:** Migrate away from removed APIs; avoid deprecated patterns that will be removed in future versions.
|
|
4
|
+
|
|
5
|
+
**Rationale:** React 19 removes long-deprecated APIs. Upgrade to React 18.3 first to see deprecation warnings, then migrate.
|
|
6
|
+
|
|
7
|
+
| Removed | Migration |
|
|
8
|
+
|---------|-----------|
|
|
9
|
+
| `ReactDOM.render()` | `createRoot().render()` |
|
|
10
|
+
| `ReactDOM.hydrate()` | `hydrateRoot()` |
|
|
11
|
+
| `unmountComponentAtNode()` | `root.unmount()` |
|
|
12
|
+
| `ReactDOM.findDOMNode()` | Use refs |
|
|
13
|
+
| `propTypes` | TypeScript |
|
|
14
|
+
| `defaultProps` (functions) | ES6 default parameters |
|
|
15
|
+
| String refs | Callback refs or `useRef` |
|
|
16
|
+
| Legacy Context | `createContext` |
|
|
17
|
+
| `react-dom/test-utils` | `act` from `'react'` |
|
|
18
|
+
|
|
19
|
+
| Deprecated | Migration |
|
|
20
|
+
|------------|-----------|
|
|
21
|
+
| `forwardRef` | `ref` as prop |
|
|
22
|
+
| `Context.Provider` | `<Context value={}>` |
|
|
23
|
+
|
|
24
|
+
**Example:**
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
// Removed: ReactDOM.render
|
|
28
|
+
import { render } from 'react-dom'; // ❌ Removed
|
|
29
|
+
render(<App />, document.getElementById('root'));
|
|
30
|
+
|
|
31
|
+
// Migration: createRoot
|
|
32
|
+
import { createRoot } from 'react-dom/client';
|
|
33
|
+
const root = createRoot(document.getElementById('root')!);
|
|
34
|
+
root.render(<App />);
|
|
35
|
+
|
|
36
|
+
// Removed: string refs
|
|
37
|
+
class Bad extends Component {
|
|
38
|
+
componentDidMount() { this.refs.input.focus(); }
|
|
39
|
+
render() { return <input ref="input" />; } // ❌ Removed
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Migration: useRef
|
|
43
|
+
function Good() {
|
|
44
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
45
|
+
useEffect(() => { inputRef.current?.focus(); }, []);
|
|
46
|
+
return <input ref={inputRef} />;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Removed: propTypes
|
|
50
|
+
Button.propTypes = { label: PropTypes.string }; // ❌ Ignored
|
|
51
|
+
|
|
52
|
+
// Migration: TypeScript
|
|
53
|
+
function Button({ label }: { label: string }) {
|
|
54
|
+
return <button>{label}</button>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Removed: defaultProps (function components)
|
|
58
|
+
function Button({ size }) { return <button className={size}>Click</button>; }
|
|
59
|
+
Button.defaultProps = { size: 'medium' }; // ❌ Removed
|
|
60
|
+
|
|
61
|
+
// Migration: ES6 defaults
|
|
62
|
+
function Button({ size = 'medium' }: { size?: string }) {
|
|
63
|
+
return <button className={size}>Click</button>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Deprecated: forwardRef
|
|
67
|
+
const Input = forwardRef((props, ref) => <input ref={ref} {...props} />);
|
|
68
|
+
|
|
69
|
+
// Migration: ref as prop
|
|
70
|
+
function Input({ ref, ...props }: { ref?: Ref<HTMLInputElement> }) {
|
|
71
|
+
return <input ref={ref} {...props} />;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Deprecated: Context.Provider
|
|
75
|
+
<ThemeContext.Provider value="dark">{children}</ThemeContext.Provider>
|
|
76
|
+
|
|
77
|
+
// Migration: Context directly
|
|
78
|
+
<ThemeContext value="dark">{children}</ThemeContext>
|
|
79
|
+
|
|
80
|
+
// Removed: react-dom/test-utils
|
|
81
|
+
import { act } from 'react-dom/test-utils'; // ❌ Removed
|
|
82
|
+
|
|
83
|
+
// Migration: import from react
|
|
84
|
+
import { act } from 'react';
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Migration codemods:**
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Run all React 19 codemods
|
|
91
|
+
npx codemod@latest react/19/migration-recipe
|
|
92
|
+
|
|
93
|
+
# Individual codemods
|
|
94
|
+
npx codemod@latest react/19/replace-reactdom-render
|
|
95
|
+
npx codemod@latest react/19/replace-string-ref
|
|
96
|
+
npx codemod@latest react/19/replace-forward-ref
|
|
97
|
+
npx codemod@latest react/19/replace-act-import
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Techniques:**
|
|
101
|
+
- Removed APIs: ReactDOM.render, ReactDOM.hydrate, findDOMNode, string refs, propTypes
|
|
102
|
+
- createRoot: Use for client-side rendering instead of deprecated ReactDOM.render
|
|
103
|
+
- useRef/Callback refs: Replace string refs like ref="fieldName"
|
|
104
|
+
- TypeScript: Replace propTypes validation with type-safe function parameters
|
|
105
|
+
- defaultProps: Use ES6 default parameters instead of .defaultProps
|
|
106
|
+
- forwardRef: Migrate to ref as prop for better type safety
|
|
107
|
+
- Context: Use Context directly instead of Context.Provider wrapper
|
|
108
|
+
- Act import: Import from 'react' not 'react-dom/test-utils'
|
|
109
|
+
- Codemods: Run react/19/migration-recipe to automate common migrations
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# migration-paradigm-shifts: React 19 Mental Model Changes
|
|
2
|
+
|
|
3
|
+
**Guideline:** Think server-first, compiler-optimized, declarative; React 19 shifts from client-side to Server Components and from manual to automatic optimization.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Server Components eliminate useEffect data fetching; Compiler removes manual memoization burden; Form Actions replace useState form fields.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
```tsx
|
|
9
|
+
// OLD: Client fetch + loading state
|
|
10
|
+
function ProductPage({ productId }) {
|
|
11
|
+
const [product, setProduct] = useState(null);
|
|
12
|
+
const [loading, setLoading] = useState(true);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
fetch(`/api/products/${productId}`).then(data => { setProduct(data); setLoading(false); });
|
|
15
|
+
}, [productId]);
|
|
16
|
+
if (loading) return <Skeleton />;
|
|
17
|
+
return <ProductDetails product={product} />;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// NEW: Server Component - direct DB access
|
|
21
|
+
async function ProductPage({ productId }) {
|
|
22
|
+
const product = await db.products.find(productId);
|
|
23
|
+
return <ProductDetails product={product} />;
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Techniques:**
|
|
28
|
+
- Server-first: Async Server Components (SC) by default, 'use client' for islands only
|
|
29
|
+
- Data fetching: SC replaces useEffect; no loading state needed (Suspense handles it)
|
|
30
|
+
- Form handling: useActionState replaces useState; FormData replaces controlled inputs
|
|
31
|
+
- Memoization: React Compiler handles it; write clean code, compiler optimizes
|
|
32
|
+
- Loading UX: Suspense boundaries for progressive disclosure instead of all-or-nothing
|
|
33
|
+
- Paradigm shift: Trust the framework; write simple code, compiler/SC handle complexity
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# typescript-changes: React 19 TypeScript Changes
|
|
2
|
+
|
|
3
|
+
**Guideline:** Update TypeScript types for React 19's breaking changes to refs, JSX namespace, and removed types.
|
|
4
|
+
|
|
5
|
+
**Rationale:** React 19 changes ref semantics, removes deprecated types, and scopes JSX namespace. Run codemods to automate most migrations.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
// Ref callbacks must not return values (except cleanup)
|
|
11
|
+
<div ref={current => (instance = current)} /> // ❌ Error - implicit return
|
|
12
|
+
<div ref={current => { instance = current; }} /> // ✅ Block body
|
|
13
|
+
|
|
14
|
+
// Cleanup functions ARE allowed
|
|
15
|
+
<div ref={current => {
|
|
16
|
+
// setup
|
|
17
|
+
return () => { /* cleanup */ };
|
|
18
|
+
}} />
|
|
19
|
+
|
|
20
|
+
// useRef requires argument
|
|
21
|
+
const ref = useRef<HTMLDivElement>(); // ❌ Error
|
|
22
|
+
const ref = useRef<HTMLDivElement>(null); // ✅ Required
|
|
23
|
+
|
|
24
|
+
// ReactElement props are now unknown
|
|
25
|
+
type Props = ReactElement['props']; // unknown (was any)
|
|
26
|
+
type Props = ReactElement<{ id: string }>['props']; // { id: string }
|
|
27
|
+
|
|
28
|
+
// Global JSX namespace removed - import explicitly
|
|
29
|
+
declare global { namespace JSX { ... } } // ❌ Removed
|
|
30
|
+
|
|
31
|
+
declare module 'react' { // ✅ Module scoped
|
|
32
|
+
namespace JSX {
|
|
33
|
+
interface IntrinsicElements {
|
|
34
|
+
'my-element': { myProp: string };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Import JSX type explicitly
|
|
40
|
+
import type { JSX } from 'react';
|
|
41
|
+
const element: JSX.Element = <div />;
|
|
42
|
+
|
|
43
|
+
// Removed types - use alternatives
|
|
44
|
+
import { ReactChild, VFC } from 'react'; // ❌ Removed
|
|
45
|
+
|
|
46
|
+
// Alternatives
|
|
47
|
+
type Child = ReactElement | number | string; // was ReactChild
|
|
48
|
+
type Component = FC<Props>; // was VFC, SFC
|
|
49
|
+
|
|
50
|
+
// Typing ref as prop
|
|
51
|
+
interface InputProps {
|
|
52
|
+
placeholder?: string;
|
|
53
|
+
ref?: React.Ref<HTMLInputElement>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function Input({ placeholder, ref }: InputProps) {
|
|
57
|
+
return <input placeholder={placeholder} ref={ref} />;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Typing useActionState
|
|
61
|
+
interface FormState { error: string | null; success: boolean }
|
|
62
|
+
|
|
63
|
+
const [state, formAction, isPending] = useActionState<FormState, FormData>(
|
|
64
|
+
async (prevState, formData) => {
|
|
65
|
+
return { error: null, success: true };
|
|
66
|
+
},
|
|
67
|
+
{ error: null, success: false }
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// Typing useOptimistic
|
|
71
|
+
const [optimistic, addOptimistic] = useOptimistic<Message[], Omit<Message, 'pending'>>(
|
|
72
|
+
messages,
|
|
73
|
+
(state, newMessage) => [...state, { ...newMessage, pending: true }]
|
|
74
|
+
);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Migration codemods:**
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Run all TypeScript codemods
|
|
81
|
+
npx types-react-codemod@latest preset-19 ./src
|
|
82
|
+
|
|
83
|
+
# Individual codemods
|
|
84
|
+
npx types-react-codemod@latest no-implicit-ref-callback-return ./src
|
|
85
|
+
npx types-react-codemod@latest refobject-defaults ./src
|
|
86
|
+
npx types-react-codemod@latest scoped-jsx ./src
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Techniques:**
|
|
90
|
+
- Update `@types/react` and `@types/react-dom` to ^19.0.0
|
|
91
|
+
- Run `npx types-react-codemod@latest preset-19 ./src`
|
|
92
|
+
- Fix ref callback implicit returns: `=> (x = y)` → `=> { x = y; }`
|
|
93
|
+
- Add arguments to `useRef()` calls
|
|
94
|
+
- Replace removed types (`ReactChild`, `VFC`)
|
|
95
|
+
- Import `JSX` type from `'react'` if used
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# new-hooks: React 19 Hooks
|
|
2
|
+
|
|
3
|
+
**Guideline:** Use React 19's new hooks for forms, optimistic updates, and promise/context reading.
|
|
4
|
+
|
|
5
|
+
**Rationale:** These hooks replace manual state management patterns, reducing boilerplate and providing built-in pending states, error handling, and progressive enhancement.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { useActionState, useOptimistic, use, Suspense } from 'react';
|
|
11
|
+
import { useFormStatus } from 'react-dom';
|
|
12
|
+
|
|
13
|
+
// useActionState - form state with async actions
|
|
14
|
+
function ContactForm() {
|
|
15
|
+
const [state, formAction, isPending] = useActionState(
|
|
16
|
+
async (prevState, formData) => {
|
|
17
|
+
const result = await submitForm({
|
|
18
|
+
email: formData.get('email'),
|
|
19
|
+
message: formData.get('message'),
|
|
20
|
+
});
|
|
21
|
+
if (result.error) return { error: result.error };
|
|
22
|
+
return { success: true };
|
|
23
|
+
},
|
|
24
|
+
null
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<form action={formAction}>
|
|
29
|
+
<input name="email" type="email" disabled={isPending} />
|
|
30
|
+
<textarea name="message" disabled={isPending} />
|
|
31
|
+
<SubmitButton />
|
|
32
|
+
{state?.error && <p className="error">{state.error}</p>}
|
|
33
|
+
</form>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// useFormStatus - reads parent form state (must be inside form)
|
|
38
|
+
function SubmitButton() {
|
|
39
|
+
const { pending } = useFormStatus();
|
|
40
|
+
return (
|
|
41
|
+
<button type="submit" disabled={pending}>
|
|
42
|
+
{pending ? 'Sending...' : 'Send'}
|
|
43
|
+
</button>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// useOptimistic - instant feedback, reverts on error
|
|
48
|
+
function LikeButton({ postId, likes }: { postId: string; likes: number }) {
|
|
49
|
+
const [optimisticLikes, addOptimistic] = useOptimistic(
|
|
50
|
+
likes,
|
|
51
|
+
(current, delta: number) => current + delta
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
async function handleLike() {
|
|
55
|
+
addOptimistic(1);
|
|
56
|
+
await likePost(postId); // reverts if throws
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<form action={handleLike}>
|
|
61
|
+
<button type="submit">{optimisticLikes} likes</button>
|
|
62
|
+
</form>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// use() - read promises (suspends until resolved)
|
|
67
|
+
function Comments({ commentsPromise }: { commentsPromise: Promise<Comment[]> }) {
|
|
68
|
+
const comments = use(commentsPromise);
|
|
69
|
+
return comments.map(c => <p key={c.id}>{c.text}</p>);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// use() - conditional context (not possible with useContext)
|
|
73
|
+
function ThemedContent({ showTheme }: { showTheme: boolean }) {
|
|
74
|
+
if (!showTheme) return <div>Plain</div>;
|
|
75
|
+
const theme = use(ThemeContext); // can be called conditionally!
|
|
76
|
+
return <div className={theme}>Themed</div>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Parent creates promise, child reads it
|
|
80
|
+
function Page({ postId }: { postId: string }) {
|
|
81
|
+
const commentsPromise = fetchComments(postId);
|
|
82
|
+
return (
|
|
83
|
+
<Suspense fallback={<Skeleton />}>
|
|
84
|
+
<Comments commentsPromise={commentsPromise} />
|
|
85
|
+
</Suspense>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Techniques:**
|
|
91
|
+
- Use `useActionState` for form state with async actions (replaces manual loading/error state)
|
|
92
|
+
- Use `useOptimistic` for instant UI feedback that reverts on error
|
|
93
|
+
- Use `use()` to read promises (suspends) or context (can be conditional)
|
|
94
|
+
- Use `useFormStatus` inside forms to read parent form's pending state
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# performance-optimization: Performance Optimization Techniques
|
|
2
|
+
|
|
3
|
+
**Guideline:** Use memo() for expensive components; lazy-load routes with React.lazy + Suspense; prefer SSR/SSG; let Compiler handle calculations.
|
|
4
|
+
|
|
5
|
+
**Rationale:** memo() prevents unnecessary re-renders; code splitting reduces initial bundle; SSR improves FCP; React 19 Compiler removes manual memoization burden.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
```tsx
|
|
9
|
+
// Memoize expensive component
|
|
10
|
+
const ExpensiveList = memo(function({ items, onItemClick }) {
|
|
11
|
+
return (
|
|
12
|
+
<ul>
|
|
13
|
+
{items.map(item => (
|
|
14
|
+
<li key={item.id} onClick={() => onItemClick(item.id)}>
|
|
15
|
+
{item.name}
|
|
16
|
+
</li>
|
|
17
|
+
))}
|
|
18
|
+
</ul>
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Lazy load routes
|
|
23
|
+
const Dashboard = lazy(() => import("./pages/Dashboard"));
|
|
24
|
+
function App() {
|
|
25
|
+
return (
|
|
26
|
+
<Suspense fallback={<LoadingSpinner />}>
|
|
27
|
+
<Routes>
|
|
28
|
+
<Route path="/dashboard" element={<Dashboard />} />
|
|
29
|
+
</Routes>
|
|
30
|
+
</Suspense>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Techniques:**
|
|
36
|
+
- memo(): Wrap expensive components to skip re-render if props unchanged
|
|
37
|
+
- lazy() + Suspense: Code splitting; reduces initial bundle by ~50-70%
|
|
38
|
+
- useCallback: Stabilize callbacks passed to memoized children (pair with memo)
|
|
39
|
+
- useMemo: Only for effect dependencies or expensive one-time calculations
|
|
40
|
+
- React Compiler: In React 19, removes need for manual memoization (vite/next.js config)
|
|
41
|
+
- SSR/SSG: Server Components and static generation for better FCP and SEO
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# react-compiler: React Compiler & Automatic Memoization
|
|
2
|
+
|
|
3
|
+
**Guideline:** Write clean code without manual memoization; let Compiler handle it automatically; use useMemo/useCallback only for effect dependencies.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Compiler analyzes data flow and applies memoization where beneficial; manual optimization adds overhead and is often incorrect.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
```tsx
|
|
9
|
+
// Compiler handles this automatically
|
|
10
|
+
function ProductList({ items, onSelect }) {
|
|
11
|
+
const sorted = items.filter(x => x.active).sort(byName);
|
|
12
|
+
return sorted.map(item => (
|
|
13
|
+
<li key={item.id} onClick={() => onSelect(item.id)}>{item.name}</li>
|
|
14
|
+
));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Manual useMemo only for stable effect dependency
|
|
18
|
+
function SearchResults({ query }) {
|
|
19
|
+
const searchParams = useMemo(
|
|
20
|
+
() => ({ query, timestamp: Date.now() }),
|
|
21
|
+
[query]
|
|
22
|
+
);
|
|
23
|
+
useEffect(() => { fetchResults(searchParams); }, [searchParams]);
|
|
24
|
+
return <Results />;
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Techniques:**
|
|
29
|
+
- Compiler enabled: Vite react({ babel: { plugins: ['babel-plugin-react-compiler'] } }) or Next.js experimental.reactCompiler
|
|
30
|
+
- Rules of React: Pure functions, immutable state, unconditional hooks (compiler enforces)
|
|
31
|
+
- Manual memoization: Only for stable effect dependencies; let Compiler handle render optimizations
|
|
32
|
+
- Opt-in ('use memo'): Incremental adoption; compile specific components
|
|
33
|
+
- Opt-out ('use no memo'): Skip compilation for legacy/problematic code
|
|
34
|
+
- Keep it simple: Write readable code; Compiler finds and optimizes bottlenecks
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# server-components: React Server Components & Actions
|
|
2
|
+
|
|
3
|
+
**Guideline:** Use Server Components by default for data fetching and static UI; add `'use client'` only for interactivity.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Server Components send zero JS to the client, access databases/APIs directly, and eliminate loading state boilerplate. Client boundaries should be minimal.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
// Server Component (default) - no directive needed
|
|
11
|
+
async function ProductPage({ params }: { params: { id: string } }) {
|
|
12
|
+
const product = await db.products.find(params.id);
|
|
13
|
+
const reviews = await db.reviews.findMany({ productId: params.id });
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<main>
|
|
17
|
+
<h1>{product.name}</h1>
|
|
18
|
+
<p>{product.description}</p>
|
|
19
|
+
<AddToCartButton productId={product.id} /> {/* Client island */}
|
|
20
|
+
<ReviewList reviews={reviews} />
|
|
21
|
+
</main>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Client Component - needs directive for interactivity
|
|
26
|
+
'use client';
|
|
27
|
+
|
|
28
|
+
function AddToCartButton({ productId }: { productId: string }) {
|
|
29
|
+
const [isPending, startTransition] = useTransition();
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<button
|
|
33
|
+
onClick={() => startTransition(() => addToCart(productId))}
|
|
34
|
+
disabled={isPending}
|
|
35
|
+
>
|
|
36
|
+
{isPending ? 'Adding...' : 'Add to Cart'}
|
|
37
|
+
</button>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Server Action - separate file recommended
|
|
42
|
+
// actions.ts
|
|
43
|
+
'use server';
|
|
44
|
+
|
|
45
|
+
export async function createPost(prevState: any, formData: FormData) {
|
|
46
|
+
const title = formData.get('title') as string;
|
|
47
|
+
if (!title) return { error: 'Title required' };
|
|
48
|
+
|
|
49
|
+
await db.posts.create({ title });
|
|
50
|
+
revalidatePath('/posts');
|
|
51
|
+
return { success: true };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function deletePost(id: string) {
|
|
55
|
+
await db.posts.delete(id);
|
|
56
|
+
revalidatePath('/posts');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Using Server Actions in Client Component
|
|
60
|
+
'use client';
|
|
61
|
+
|
|
62
|
+
import { createPost } from './actions';
|
|
63
|
+
import { useActionState } from 'react';
|
|
64
|
+
|
|
65
|
+
function NewPostForm() {
|
|
66
|
+
const [state, formAction, isPending] = useActionState(createPost, null);
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<form action={formAction}>
|
|
70
|
+
<input name="title" disabled={isPending} />
|
|
71
|
+
<button disabled={isPending}>Create</button>
|
|
72
|
+
{state?.error && <span>{state.error}</span>}
|
|
73
|
+
</form>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Inline Server Action in Server Component
|
|
78
|
+
async function QuickForm() {
|
|
79
|
+
async function handleSubmit(formData: FormData) {
|
|
80
|
+
'use server';
|
|
81
|
+
await db.items.create({ name: formData.get('name') });
|
|
82
|
+
revalidatePath('/items');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<form action={handleSubmit}>
|
|
87
|
+
<input name="name" />
|
|
88
|
+
<button>Add</button>
|
|
89
|
+
</form>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Techniques:**
|
|
95
|
+
- No directive = Server Component (default); can be `async`, access db/fs directly
|
|
96
|
+
- Add `'use client'` only for useState, useEffect, onClick, browser APIs
|
|
97
|
+
- Use `'use server'` for Server Actions (mutations callable from client)
|
|
98
|
+
- Keep client boundaries small - wrap only interactive parts
|
|
99
|
+
- Pass Server Components as children to Client Components when needed
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# state-management: State Management Best Practices
|
|
2
|
+
|
|
3
|
+
**Guideline:** Use local state with `useState`, lift state only when multiple components need it, and derive computed values.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Local state keeps components independent and easier to reason about. Lifting state only when necessary prevents prop drilling and over-sharing. Derived state eliminates synchronization bugs.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
// ✅ Local state
|
|
11
|
+
function Counter() {
|
|
12
|
+
const [count, setCount] = useState(0);
|
|
13
|
+
return <button onClick={() => setCount(count + 1)}>{count}</button>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// ✅ Lifted state (when siblings need to share)
|
|
17
|
+
function Parent() {
|
|
18
|
+
const [count, setCount] = useState(0);
|
|
19
|
+
return (
|
|
20
|
+
<>
|
|
21
|
+
<Counter count={count} onIncrement={() => setCount(count + 1)} />
|
|
22
|
+
<Display count={count} />
|
|
23
|
+
</>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ✅ useReducer for complex state
|
|
28
|
+
type State = {count: number; step: number};
|
|
29
|
+
type Action =
|
|
30
|
+
| {type: "increment"}
|
|
31
|
+
| {type: "decrement"}
|
|
32
|
+
| {type: "setStep"; step: number};
|
|
33
|
+
|
|
34
|
+
function reducer(state: State, action: Action): State {
|
|
35
|
+
switch (action.type) {
|
|
36
|
+
case "increment":
|
|
37
|
+
return {...state, count: state.count + state.step};
|
|
38
|
+
case "decrement":
|
|
39
|
+
return {...state, count: state.count - state.step};
|
|
40
|
+
case "setStep":
|
|
41
|
+
return {...state, step: action.step};
|
|
42
|
+
default:
|
|
43
|
+
return state;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function ComplexCounter() {
|
|
48
|
+
const [state, dispatch] = useReducer(reducer, {count: 0, step: 1});
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div>
|
|
52
|
+
<p>Count: {state.count}</p>
|
|
53
|
+
<button onClick={() => dispatch({type: "increment"})}>+</button>
|
|
54
|
+
<button onClick={() => dispatch({type: "decrement"})}>-</button>
|
|
55
|
+
<input
|
|
56
|
+
type="number"
|
|
57
|
+
value={state.step}
|
|
58
|
+
onChange={(e) =>
|
|
59
|
+
dispatch({type: "setStep", step: Number(e.target.value)})
|
|
60
|
+
}
|
|
61
|
+
/>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Techniques:**
|
|
68
|
+
- Start with local `useState` in the component that owns the data
|
|
69
|
+
- If multiple sibling components need the state, lift to their parent
|
|
70
|
+
- For complex state logic, use `useReducer` instead of multiple `useState`
|
|
71
|
+
- Use `useMemo` to derive values from existing state
|
|
72
|
+
- Consider Context API for deeply nested prop passing
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# suspense-streaming: Suspense, Streaming & Error Handling
|
|
2
|
+
|
|
3
|
+
**Guideline:** Use granular Suspense boundaries for independent progressive loading; nest for hierarchical control; combine with Error Boundaries.
|
|
4
|
+
|
|
5
|
+
**Rationale:** Suspense enables streaming—content loads incrementally, not all-or-nothing; React 19 pre-warms siblings for faster perceived performance.
|
|
6
|
+
|
|
7
|
+
**Example:**
|
|
8
|
+
```tsx
|
|
9
|
+
function Dashboard() {
|
|
10
|
+
return (
|
|
11
|
+
<div>
|
|
12
|
+
<Suspense fallback={<StatsSkeleton />}>
|
|
13
|
+
<StatsSection /> {/* Shows at 150ms */}
|
|
14
|
+
</Suspense>
|
|
15
|
+
<Suspense fallback={<UserSkeleton />}>
|
|
16
|
+
<UserSection /> {/* Shows at 200ms independently */}
|
|
17
|
+
</Suspense>
|
|
18
|
+
</div>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Error + Suspense: graceful failure
|
|
23
|
+
<ErrorBoundary fallback={<ErrorMessage />}>
|
|
24
|
+
<Suspense fallback={<Loading />}>
|
|
25
|
+
<DataDisplay />
|
|
26
|
+
</Suspense>
|
|
27
|
+
</ErrorBoundary>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Techniques:**
|
|
31
|
+
- Independent boundaries: Each Suspense boundary loads and shows independently (faster perceived time)
|
|
32
|
+
- Nested boundaries: Hierarchy for critical→secondary→tertiary with fallbacks at each level
|
|
33
|
+
- Error Boundaries: Catch component errors; pair with Suspense for complete error handling
|
|
34
|
+
- Root-level errors: React 19 onUncaughtError and onCaughtError callbacks
|
|
35
|
+
- Skeleton sizing: Match dimensions to prevent layout shift (CLS optimization)
|
|
36
|
+
- Pre-warming: React 19 fetches siblings during suspension for faster transitions
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: remotion-guidelines
|
|
3
|
+
description: >-
|
|
4
|
+
Trigger on Remotion video projects, `remotion.config.ts`, video composition files. Use when creating programmatic videos with React. Apply for animations, sequencing, media handling, transitions, captions. Keywords: Remotion, video, React, animation, composition, useCurrentFrame, interpolate, spring, Sequence.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Remotion Coding Guidelines
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
- Remotion ≥ 4, React ≥ 18, TypeScript.
|
|
12
|
+
|
|
13
|
+
## Essentials
|
|
14
|
+
|
|
15
|
+
- **Frame-driven animations** - Use `useCurrentFrame()` for all motion; CSS transitions and Tailwind `animate-*` classes are forbidden, see [reference/animations.md](reference/animations.md)
|
|
16
|
+
- **Timing** - Write in seconds, multiply by `fps` from `useVideoConfig()`; use `interpolate()` or `spring()`, see [reference/timing.md](reference/timing.md)
|
|
17
|
+
- **Sequencing** - Use `<Sequence>` with `from`/`durationInFrames`; always add `premountFor` to preload, see [reference/sequencing.md](reference/sequencing.md)
|
|
18
|
+
- **Assets** - Use `staticFile()` for public assets; use `<Img>`, `<Video>`, `<Audio>` components, see [reference/assets.md](reference/assets.md)
|
|
19
|
+
- **Compositions** - Define in `Root.tsx` with `type` (not interface) for props; use `calculateMetadata()` for dynamic values, see [reference/compositions.md](reference/compositions.md)
|
|
20
|
+
- **Transitions** - Use `<TransitionSeries>` for scene changes; duration overlaps reduce total length, see [reference/transitions.md](reference/transitions.md)
|
|
21
|
+
- **Text** - Load fonts via `@remotion/google-fonts`; measure with `@remotion/layout-utils`, see [reference/text.md](reference/text.md)
|
|
22
|
+
|
|
23
|
+
## Example
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import {AbsoluteFill, interpolate, spring, useCurrentFrame, useVideoConfig} from "remotion";
|
|
27
|
+
|
|
28
|
+
export function FadeIn() {
|
|
29
|
+
const frame = useCurrentFrame();
|
|
30
|
+
const {fps} = useVideoConfig();
|
|
31
|
+
|
|
32
|
+
const opacity = interpolate(frame, [0, 0.5 * fps], [0, 1], {
|
|
33
|
+
extrapolateRight: "clamp",
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const scale = spring({
|
|
37
|
+
frame,
|
|
38
|
+
fps,
|
|
39
|
+
config: {damping: 200},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<AbsoluteFill style={{opacity, transform: `scale(${scale})`}}>
|
|
44
|
+
<h1>Hello Remotion</h1>
|
|
45
|
+
</AbsoluteFill>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Progressive Disclosure
|
|
51
|
+
|
|
52
|
+
- Read [reference/animations.md](reference/animations.md) - When creating motion with interpolate, spring, or easing
|
|
53
|
+
- Read [reference/timing.md](reference/timing.md) - When converting seconds to frames or working with durations
|
|
54
|
+
- Read [reference/sequencing.md](reference/sequencing.md) - When orchestrating multiple elements or scenes
|
|
55
|
+
- Read [reference/assets.md](reference/assets.md) - When loading images, videos, audio, or fonts
|
|
56
|
+
- Read [reference/compositions.md](reference/compositions.md) - When defining video structure or dynamic metadata
|
|
57
|
+
- Read [reference/transitions.md](reference/transitions.md) - When adding scene transitions like fade, slide, wipe
|
|
58
|
+
- Read [reference/text.md](reference/text.md) - When animating text, measuring dimensions, or loading fonts
|
|
59
|
+
- Read [reference/media.md](reference/media.md) - When trimming, adjusting volume, or manipulating audio/video
|
|
60
|
+
- Read [reference/captions.md](reference/captions.md) - When adding subtitles or TikTok-style captions
|
|
61
|
+
- Read [reference/three-d.md](reference/three-d.md) - When integrating Three.js 3D content
|
|
62
|
+
- Read [reference/charts.md](reference/charts.md) - When building animated data visualizations
|
|
63
|
+
- Read [reference/gifs.md](reference/gifs.md) - When displaying GIFs, APNG, WebP, or AVIF animations
|
|
64
|
+
- Read [reference/lottie.md](reference/lottie.md) - When embedding Lottie animations
|
|
65
|
+
- Read [reference/maps.md](reference/maps.md) - When creating map animations with Mapbox
|
|
66
|
+
- Read [reference/mediabunny.md](reference/mediabunny.md) - When getting video duration, dimensions, or extracting frames
|
|
67
|
+
- Read [reference/dom-measurement.md](reference/dom-measurement.md) - When measuring DOM elements with getBoundingClientRect
|