Solidjs v2
Claude Code skills for SolidJS 2.0 — write, migrate, and review solid-js 2.x code without React/1.x reflexes
npx -y skills add khmm12/solidjs-v2-skills --skill solidjs-v2Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Answer SolidJS 2.0 API and beta-behavior questions, and write or edit SolidJS 2.0 code (solid-js 2.x / next / beta). Use for questions or implementation involving components, signals/effects/batching, async data/generators/actions and Loading, removed beta APIs, stores and nested store views, lazy SSR/hydration, server functions ("use server"), or DOM code for solid-js 2.x or @solidjs/web. Not for Solid 1.x projects and not for migrating 1.x code (see solidjs-v2-migration).
SKILL.md
6.3 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it
SolidJS 2.0
Solid 2.0 is not React and not Solid 1.x. Both priors are the dominant
bug sources in generated code. When in doubt, distrust pattern-matching and
check references/cheatsheet.md (official, ships with the package) or the
installed typings in node_modules.
Step 0 — confirm this is actually a v2 project
Check before applying anything below:
package.json:solid-jsmajor is2(e.g.2.0.0-beta.x), and/or@solidjs/webis a dependency.tsconfig.json:"jsxImportSource": "@solidjs/web".
If solid-js is 1.x (imports like solid-js/web, solid-js/store), stop —
these rules do not apply; that's a Solid 1.x project. If the task is to
convert it, use the solidjs-v2-migration skill instead.
Betas drift: when docs and the installed package disagree, trust the typings in
node_modules (solid-js, @solidjs/web, @solidjs/signals).
The ten rules that prevent most bugs
- Reads lag writes. Updates apply on the next microtask:
setCount(1); count()still returns0. Synchronous point:flush().batch()does not exist. createEffecttakes two functions —(compute, apply, options?). Compute tracks and returns a value; apply does side effects (untracked) and may return a cleanup. The 1.x single-callback form throws.on(),createComputed, initial-value args: all gone.- Never write signals/stores or invoke an action inside a reactive scope
(memo, compute, component body) — throws in dev. Define actions there if
useful, but invoke/write from event handlers, effect callbacks, actions, or
onSettled. Derive instead of writing back. - No top-level reactive reads in component bodies and no destructured
props — warns, value goes stale. Read via
props.xinside JSX / memos / effect computes;untrack(() => ...)for deliberate one-shots. - Props are values, not accessors. Call site:
<X v={count()} />, never<X v={count} />. Child:props.v, neverfunction X({ v }). This stays reactive — the compiler turnsv={count()}into{ get v() { return count() } }, so readingprops.vin the child re-runscount()in the child's tracking scope. Passing the accessor (v={count}+props.v()) to "keep reactivity" is a misconception: props have always been getters in Solid (1.x and 2.0 alike — value-passing didn't change), so it's unnecessary and just forces every consumer to call a function. - Async is just a computation:
const user = createMemo(() => fetchUser(id()))— nocreateResource. Wrap consumers in<Loading fallback={...}>; errors go to<Errored>. In-flight-change indicators:isPending(() => user())— fires for changed inputs andaffects()declarations; a barerefresh()is silent. - Store setters take a draft:
setStore(s => { s.a.b = 1; })(produce is the default). Store APIs (createStore,reconcile,snapshot…) are exported fromsolid-js—solid-js/storedoes not exist. - List rendering is
Forwith keying modes —<Index>is gone. Callback shapes differ per mode (see references);keyed={false}gives(itemAccessor, plainIndex). Fixed-count rendering:<Repeat>. - Lifecycle:
onSettled(() => { ...; return cleanup; })replacesonMount/onCleanupfor component-level setup-and-teardown. It's a leaf owner — no primitives oronCleanupinside. - Imports moved:
@solidjs/webforrender/hydrate/Portal/Dynamic(notsolid-js/web);jsxImportSource: "@solidjs/web"; DOM attributes are lowercase (tabindex);classtakes object/array forms (classListis gone); directives areref={factory(opts)}(use:is gone).
Reference routing
Read the file matching the task before writing code in that area:
| Task touches | Read |
|---|---|
| Quick API lookup, import list, full 1.x→2.0 footgun list | references/cheatsheet.md (official) |
Signals, memos, split/render effects and paint timing, createReaction, batching/flush, lifecycle, ownership, dev diagnostics | references/reactivity.md |
Data fetching, async iterator completion, Loading/Errored, isPending/latest/resolve/refresh, removed isRefreshing, action call scope/errors, optimistic UI | references/async-and-actions.md |
| createStore, reconcile, projections, nested store-view structural tracking, snapshot/deep, merge/omit, storePath | references/stores.md |
| For/Repeat/Show/Switch/Reveal, dynamic/lazy components, lazy SSR/hydration identity, class/attributes/events/refs/directives, render entries | references/control-flow-and-dom.md |
| tsconfig, JSX types, import paths, Context typing, test setup | references/typescript-setup.md |
| Composed patterns: SWR query, optimistic mutations, selection projections, global state, demand-driven resources | references/patterns.md |
Naming a primitive/composable (create* vs use*), cross-cutting conventions | references/conventions.md |
"use server" directive, server-function privacy/DCE, respond/redirect/reload, GET/withMeta, prepareRequest, single-flight, no-JS, getRequestEvent | references/server-functions.md |
Failure modes
- App renders nothing / mount seems stuck → pending async outside a
Loadingboundary defers the root mount; check the console forASYNC_OUTSIDE_LOADING_BOUNDARY. - Dev throws/warns with a diagnostic code (
REACTIVE_WRITE_IN_OWNED_SCOPE,STRICT_READ_UNTRACKED, …) → table of codes and fixes at the bottom ofreferences/reactivity.md. Fix the cause; never silence withownedWritefor app state. - Test asserts stale values → missing
flush()after writes, or reactive code created without an owner (createRootin tests). - An API from docs/examples doesn't exist → betas drift; verify against installed typings and prefer them over any doc, including these references.
What ships with it: 10 files
124.7 KB alongside SKILL.md
references/
- async-and-actions.md19.5 KB
- cheatsheet.md24.5 KB
- control-flow-and-dom.md10.9 KB
- conventions.md2.0 KB
- patterns.md15.6 KB
- reactivity.md18.6 KB
- server-components.md3.3 KB
- server-functions.md15.9 KB
- stores.md9.7 KB
- typescript-setup.md4.7 KB