EffectorJS Skill
Use this skill to produce deterministic, scope-safe Effector solutions for new features, refactors, and code reviews.
Workflow
- Classify the request:
modeling: create or extend stores/events/effects.refactor: replace anti-patterns with declarative flows.ssr: implement or debug scope-safe SSR.review: assess risks, regressions, and missing tests.legacy-migration: move old patterns to modern v23+ safely.
- Load only required references:
- Always start with
references/core-patterns.md. - Always load
references/lint-derived-best-practices.mdafter core patterns to enforce plugin-backed best practices. - Add
references/explicit-start.mdwhen task touches app bootstrap, startup logic, initialization order, tests, scope, or SSR. - Add
references/computation-priority.mdwhen task touches ordering,watch, sequencing, race-like behavior, or side effects placement. - Add
references/react-ssr-scope.mdwhen React/SSR/scope appears. - Add
references/solid-scope.mdwhen Solid integration appears. - Add
references/vue-scope.mdwhen Vue integration appears. - Add
references/anti-patterns-and-fixes.mdwhen fixing or reviewing existing logic. - Add
references/legacy-migration-map.mdwhen deprecated APIs/imports are present. - End with
references/checklists.mdfor acceptance criteria.
- Build solution in this order:
- Model atomic stores and explicit events.
- Define explicit app start (
appStarted) and keep startup wiring declarative. - Move side effects to effects.
- Connect units with
samplefirst; useattachfor effect composition. - Apply scope-first rules (
fork,allSettled) for tests, SPA bootstrap boundaries, and SSR. - For UI frameworks, use
useUnitand correct provider wiring.
- Produce output contract:
- Proposed model topology (stores/events/effects and responsibilities).
- Wiring snippets (
sample,attach,splitif needed). - Scope/SSR notes when applicable.
- Lint-derived conformance notes for naming/dataflow/scope/react constraints.
- Test scenarios and acceptance checklist.
Defaults
- Target Effector modern v23+.
- Treat deprecated/legacy patterns as migration targets, not defaults.
- Prefer minimal, explicit unit graph over clever abstractions.
- Treat lint-derived practices from
eslint-plugin-effectoras baseline constraints. - Use glossary-consistent terminology in explanations and reviews.
Glossary Alignment (Effector)
Unit: includeStore,Event,Effect,Domain,Scope.Common unit: onlyStore,Event,Effect(reactive update sources for many APIs).Derived store: read-only store built from other stores (map,combine, effect-derived stores like.pending).Derived storeconstraints: do not mutate directly and do not use astargetinsample.Reducer:store.on(...)handlers must return next state;undefinedor same reference (===) means no store update.Watcher: side effects/debug observability only; watcher return value is ignored.Subscription: treat unsubscribe handlers as infrastructure concern; avoid manual subscription management in business logic.Purity: pure functions (map,.on, transform callbacks) must not imperatively call events/effects.Domain: namespace for units;onCreate*hooks are acceptable for infra-level cross-cutting concerns (logging/instrumentation), not business orchestration.
Guardrails
- Do not place business logic in
watch. - Prefer
sampleoverforward/guardfor orchestration. - Respect computation priority: keep
map/.onpure and avoid side effects in pure computation stages. - Do not call events/effects imperatively from effect bodies when declarative wiring can express the flow.
- Do not use
$store.getState()for business dataflow; pass state throughsamplesource. - Do not use derived stores as
targetinsample; target writable units/events/effects only. - Keep
sample/guardoptions in semantic order:clock -> source -> filter -> fn -> target. - Avoid ambiguous
targetusage (no simultaneous result assignment and explicittarget). - Avoid duplicate units in
clock/sourcearrays and duplicate.onhandlers for one store-event pair. - Do not use
sample/guardwithout runtime effect (must have target or captured result). - Do not create units dynamically at runtime.
- Keep naming explicit (
$store,eventHappened,someFx). - In React, bind callable units with
useUnit; avoid raw event/effect usage in JSX handlers.
Legacy Handling
If legacy code is present:
- Keep behavior unchanged first.
- Mark legacy section explicitly.
- Propose modern replacement with a migration-safe diff strategy.
- Add tests that prove parity before cleanup.