Solidjs v2 migration
Migrate a Solid 1.x codebase, file, or component to SolidJS 2.0 (solid-js 2.x / next / beta). Use when converting code that imports solid-js/web, solid-js/store, createResource, Suspense, onMount, batch, or other 1.x APIs to the 2.0 equivalents. Not for writing new v2 code from scratch (see solidjs-v2).From its SKILL.md
npx -y skills add khmm12/solidjs-v2-skills --skill solidjs-v2-migrationAssembled 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.
- 4 stars4 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.
SKILL.md
5.0 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
Migrate Solid 1.x → 2.0
Convert 1.x code to 2.0 in passes: mechanical first, then semantic, then
diagnostics-driven cleanup. The full rename/removal table with before/after
recipes is in references/migration-map.md — read it before starting; this
file is the workflow.
Step 0 — establish the direction
- Source must be Solid 1.x (imports like
solid-js/web,solid-js/store,createResource,Suspense). Target version: whatever[email protected]/@solidjs/webbeta the project declares (or the latest, if you're also bumpingpackage.json). - Betas drift. The installed typings (
node_modules/solid-js/types,@solidjs/web) outrank docs and this skill's references when they disagree. - Upgrade
solid-js,@solidjs/web, andbabel-preset-solidtogether.
Pass 1 — mechanical (grep-and-replace, low judgement)
- Dependencies:
[email protected], add@solidjs/web, matchingbabel-preset-solid. tsconfig.json:"jsxImportSource": "@solidjs/web".- Import paths and pure renames — tables at the top of
references/migration-map.md. Greppable:solid-js/web,solid-js/store,Suspense,SuspenseList,ErrorBoundary,mergeProps,splitProps,unwrap,onMount,createSelector,Context.Provider,classList,equalFn,getListener.
Mind the non-1:1 renames: Errored's fallback gets an error accessor
(err()), splitProps → omit inverts the result (rest-only), merge treats
undefined as an override, onSettled is a leaf owner.
Pass 2 — semantic rewrites (per call site, by intent)
Work through references/migration-map.md sections in this order — each names
the decision to make:
- Effects: single-callback
createEffect→ split(compute, apply);on()→ compute phase;initialValue→ default parameter;onCleanupinside effects → returned cleanup. createComputed→createMemo/ split effect /createSignal(fn)— pick by intent (derivation / side effect / writable derived).batch→ delete; addflush()only where code reads its own writes synchronously.createResource→ asynccreateMemo(orcreateProjectionfor keyed collections) +<Loading>;.loading/.error/refetch/mutateeach map differently — see the table.- Mutations: ad-hoc flag flipping /
startTransition→action()+ optimistic primitives +refresh(). - Stores:
producewrappers → plain drafts; path setters → drafts (orstorePathcompat);reconcilemoves inside the draft;createMutable→createStore. - Lists:
<Index>→<For keyed={false}>; audit default<For>callbacks — item is now raw, index is an accessor. - DOM:
use:→ ref factories;on:/attr:/bool:/class:/style:namespaces → standard forms;/*@once*/→ reactive ordefaultValue; camelCase attributes → lowercase. - Context:
.Provider→ context-as-component; deleteuseX-with-throw wrappers (useContextnow returnsTand throws without Provider). from/observable→ async iterables / push-out effects.
Pass 3 — run dev and fix diagnostics
2.0 ships structured dev diagnostics; the first dev run after migration is the real review. Typical wave, in order of volume:
STRICT_READ_UNTRACKED— top-level/destructured prop reads the old code tolerated. Move reads into JSX/memos, oruntrackdeliberate one-shots.REACTIVE_WRITE_IN_OWNED_SCOPE(throws) — 1.x effects that write signals. Rewrite as derivations or move writes to handlers/actions.ASYNC_OUTSIDE_LOADING_BOUNDARY— async reads with no<Loading>ancestor; add boundaries where fallback UI is wanted.CLEANUP_IN_FORBIDDEN_SCOPE—onCleanupinsideonSettled; return the cleanup instead.
Then run the test suite: assertions reading right after writes need flush(),
and reactive setups in tests need createRoot.
Pass 4 — behavioral audit (no grep pattern)
The "Behavioral changes that need an audit" section of the map: synchronous
read-after-write assumptions, undefined-as-override in merges, forever-roots
needing runWithOwner(null, ...).
Failure modes
- A 1.x API has no entry in the map → check the installed typings before
inventing a replacement; some conveniences (e.g.
observable,createDeferred) intentionally have none — surface the gap rather than papering over it. - App mounts blank after migration → pending async outside
Loadingdefers the root mount (ASYNC_OUTSIDE_LOADING_BOUNDARYin console). - Migration of one file pulls in half the app → migrate bottom-up (leaf components first), keep passes 1–2 per-file but expect pass 3 diagnostics to surface cross-file issues.
What ships with it: 1 file
11.8 KB alongside SKILL.md
references/
- migration-map.md11.8 KB