Migration from React
Use migration from react with the current published Askr packages.
@askrjs/askr0.0.59
How to use migration from react
Move local values to state, computed values to derive, and effect-owned asynchronous work to cancellable resources before changing routing or rendering mode.
- Import the published @askrjs/askr entrypoint.
- Keep migration from react configuration next to the component, route, or server composition root that owns it.
- Handle pending, unavailable, cancellation, and failure states, then verify the production path.
import { derive, state } from '@askrjs/askr';
import { resource } from '@askrjs/askr/resources';
const projectId = state(initialProjectId);
const project = resource(({ signal }) => loadProject(projectId(), signal), [projectId]);
const title = derive(() => project.data?.name ?? 'Loading project');Goal and architecture
The core mental shift moving from React is that Askr components are not re-executed on every state change — `state()` returns a `StateTuple` backed by fine-grained reactivity, and reading it inside JSX subscribes that specific expression to updates rather than re-running the whole component function. There's no dependency array to get wrong and no `useMemo`/`useCallback` tax for referential stability, because there's no re-render to guard against in the first place; `derive()` and `selector()` compute values reactively instead.
Implementation
Where React code branches with `{condition && <X/>}` or ternaries, Askr provides `<Show when={...}>`, `<Match>`/`<Case>`, and `<For each={...}>` as components specifically because plain JS conditionals inside JSX don't get the same fine-grained update tracking — using them keeps updates scoped to just the changed piece of the tree. Data fetching maps `useQuery`-style hooks onto `createQuery`/`defineQuery`, which return a query object with `consistency`, `refreshing`, and stale-reason fields instead of a `{ data, isLoading, error }` tuple, and route-level data uses `defer()` plus `<Resolve>` in place of a Suspense boundary.
Failure states
The most common porting mistake is treating a `state()` read like a React value snapshot and destructuring it once at the top of a function — that breaks reactivity, because the fine-grained system needs the read to happen where it's actually used (inside JSX or a `derive()`), not stored in a plain variable ahead of time. Similarly, effects that assumed React's re-render-then-effect ordering may need reworking against Askr's direct reactive update model, since there's no render phase to schedule after.
Verification
After porting a component, verify that updating one piece of state only touches the DOM nodes that actually depend on it — in React that's an optimization you'd check with a profiler, but in Askr's fine-grained model it's the expected baseline behavior and a good smoke test that the port is wired correctly. Re-run existing behavioral tests (form submission, list filtering, route navigation) unchanged where possible, since Askr's `@askrjs/askr/testing` mocks are designed to slot into the same assertion style as React Testing Library patterns.