Preact
Preact does not get an adapter of its own. gridla/react is written against the React API surface that preact/compat implements (forwardRef, useSyncExternalStore, useLayoutEffect, useId, context), so a Preact app uses the React adapter unchanged: import from gridla/react, point react and react-dom at preact/compat, and everything the React quickstart describes applies.
Appearance is yours: see the styling guide for every data-gridla-* attribute, resize handle sizing, the preview outline, and a starter stylesheet.
Install
react is an optional peer dependency of gridla. It is never installed when you alias it away; the alias is the only extra step.
Alias react to preact/compat
Pick the variant that matches your toolchain. Each one redirects the three module ids the adapter imports: react, react-dom, and the JSX runtime your compiler emits (react/jsx-runtime).
Vite
@preact/preset-vite already adds these aliases; the explicit block is shown so the mapping is visible.
Rsbuild
The $ suffix makes the alias exact, so react/jsx-runtime keeps its own mapping instead of being rewritten to preact/compat/jsx-runtime.
package.json
Without a bundler, or when a bundler should not know about the alias, install @preact/compat under the react names. Every resolver, including Node and Bun, then lands on Preact:
This is the variant the package contract suite uses (see Verification).
TypeScript
Type-check against Preact's types rather than @types/react:
paths only affects type resolution. The runtime alias still comes from one of the sections above.
Minimal example
The component is the React quickstart's; only the mount call is Preact's.
Controlled mode (layout plus onLayoutChange), nested providers, and transfers between canvases work as documented for React; see controlled state and transfer.
Server rendering
gridla/react touches no browser API at import time and GridCanvas measures itself in a layout effect, so preact-render-to-string renders the layout at its authored size and the client takes over after hydration. The rendered markup carries every data-gridla-* attribute:
Turn off responsive when the server output must match the authored coordinates exactly; otherwise the first client paint projects the layout onto the measured canvas, as in the browser.
Verification
The package contract suite (bun run test:package) packs the gridla tarball and installs it into a Preact consumer that has react and react-dom aliased to @preact/compat through package.json. The fixture asserts that the adapter's react import resolves to @preact/compat, then renders GridProvider, GridCanvas, and GridItem with preact-render-to-string in a process without window or document and checks the emitted attributes and children. A demo app built on the Rsbuild alias runs the shared browser contract suite (drag with strategy readout, resize, keyboard nudge) under /adapters/preact/.
Caveats
useSyncExternalStorecomes from compat. The adapter's store subscription uses it;preact/compatimplements it on top of Preact's own scheduler, which batches differently from React. Selected slices still update once per store change.- Layout effects run after the DOM is committed.
GridCanvasmeasures itself inuseLayoutEffect. Preact runs layout effects synchronously after the commit, the same as React, so the first paint is at the measured size; the effect order across siblings can differ from React, which the adapter does not depend on. - Hooks are
preact/hooks.useState,useRef,useMemo,useCallback,useId, and context all come from Preact through compat. The adapter uses no React-only API (nouse, no server components, nouseInsertionEffect). forwardRefis supported.GridCanvasandGridItemforward theirrefto the underlyingdiv; compat implementsforwardRef, so refs behave as in React.- No signals integration.
@preact/signalsis not used by the adapter. Read layout state through the adapter's hooks (useGridStore,useGridItemView), or throughcontroller.store.subscribeif you want to bridge it into a signal yourself. - Alias everything the adapter imports. A partial alias (for example
reactbut notreact/jsx-runtime) loads a second renderer next to Preact and context lookups fail withthis component must be rendered inside <GridProvider>. The three variants above map all module ids.