git:20260902.076114e to git:20260920.9375e0e

21 added, 101 removed. Audit A to A.

---
name: solidjs-v2-migration
- description: Migrate a Solid 1.x codebase, file, or component to SolidJS 2.0 (solid-js 2.x / next / RC). 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).
+ description: Convert a Solid 1.x project, component, or file to SolidJS 2.0. Use for an explicit version migration; solidjs-v2 covers new v2 code and solidjs-v2-reviewer covers reviews.
---
- # 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 `solid-js@2.x` /
- `@solidjs/web` prerelease the project declares (or the latest, if you're also
- bumping `package.json`).
- - Prereleases 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`, and the Solid compiler integration
- together. `babel-preset-solid` is replaced by `@solidjs/babel-plugin`; Vite
- uses `@solidjs/vite-plugin` (native `@solidjs/compiler` by default).
-
- ## Pass 1 — mechanical (grep-and-replace, low judgement)
-
- 1. Dependencies: `solid-js@2.x`, add `@solidjs/web`, and replace
- `babel-preset-solid` with matching `@solidjs/babel-plugin` (or use
- `@solidjs/vite-plugin`).
- 2. `tsconfig.json`: `"jsxImportSource": "@solidjs/web"`.
- 3. 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:
-
- 1. **Effects**: single-callback `createEffect` → split `(compute, apply)`;
- `on()` → compute phase; `initialValue` → default parameter; `onCleanup`
- inside effects → returned cleanup.
- 2. **`createComputed`** → `createMemo` / split effect / `createSignal(fn)` —
- pick by intent (derivation / side effect / writable derived).
- 3. **`batch`** → delete; add `flush()` only where code reads its own writes
- synchronously.
- 4. **`createResource`** → async `createMemo` (or `createProjection` for keyed
- collections) + `<Loading>`; `.loading`/`.error`/`refetch`/`mutate` each map
- differently — see the table.
- 5. **Mutations**: ad-hoc flag flipping / `startTransition` → `action()` +
- optimistic primitives + awaitable `refresh()` or `until()` live-source
- acknowledgement.
- 6. **Stores**: `produce` wrappers → plain drafts; path setters → drafts (or
- `storePath` compat); `reconcile` moves inside the draft; `createMutable` →
- `createStore`.
- 7. **Lists**: `<Index>` → `<For keyed={false}>`; audit default `<For>`
- callbacks — item is now raw, index is an accessor.
- 8. **DOM**: `use:` → ref factories; `on:`/`attr:`/`bool:`/`class:`/`style:`
- namespaces → standard forms; `/*@once*/` → reactive or `defaultValue`;
- camelCase attributes → lowercase.
- 9. **Context**: `.Provider` → context-as-component; delete `useX`-with-throw
- wrappers (`useContext` now returns `T` and throws without Provider).
- 10. **Server functions**: old `.GET`/`.withOptions` call sites → declaration
- wrappers, `prepareRequest`, or per-call `invoke`; audit module-level versus
- function-level wrapper trust boundaries.
- 11. **`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, or `untrack` deliberate one-shots.
- - `REACTIVE_WRITE_IN_OWNED_SCOPE` (throws) — 1.x effects that write signals.
- Rewrite as derivations or move writes to handlers/actions. `untrack()` is not
- an exemption: it suppresses dependency tracking, not ownership.
- - `ASYNC_OUTSIDE_LOADING_BOUNDARY` — async reads with no `<Loading>` ancestor;
- add boundaries where fallback UI is wanted.
- - `CLEANUP_IN_FORBIDDEN_SCOPE` — `onCleanup` inside `onSettled`; 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)
+ # Migrate Solid 1.x to 2.0
- 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, ...)`.
+ 1. **Establish source and target.** Read the installed version/lockfile and the
+ requested target. Apply this workflow when converting 1.x to major 2; keep
+ ordinary maintenance on its existing major. Match runtime, web renderer,
+ and compiler packages. Installed target typings outrank reference prose.
+ 2. **Read [migration-map](references/migration-map.md).** Update imports, JSX
+ config, and renamed APIs first. Then rewrite effects, async resources,
+ store setters, and lifecycle by intent using the map's examples.
+ 3. **Check semantics at each changed call site.** Track reads in JSX/compute;
+ perform writes in imperative callbacks; check list callback shapes, cleanup,
+ read-after-write ordering, and pending/saving state separately.
+ 4. **Validate.** Typecheck against the target, run project tests, and exercise
+ changed UI paths in dev. Repair diagnostics at their source. Check async
+ loading/error/retry, disposal, and hydration when those paths changed.
- ## Failure modes
+ Solid components set up once per mount; use tracked reads rather than React
+ rerenders/dependency arrays. Solid v2 commits writes on a microtask and splits
+ effect computation from side effects; adapting names alone is insufficient.
- - **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 `Loading`
- defers the root mount (`ASYNC_OUTSIDE_LOADING_BOUNDARY` in 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.
+ For a v1 API absent from the map, inspect installed exports/source and state
+ any gap explicitly. Finish with changed behavior, checks run, and remaining
+ runtime uncertainty.