Astro renderer integration for Solid 2.0 (solid-js@2.0.0-rc). The official
@astrojs/solid-js targets Solid 1.x; this integration renders Astro islands with the
2.0 runtime (@solidjs/web) and the new compiler plugin (@solidjs/vite-plugin).
npm i astro-solid-next solid-js@next @solidjs/web@next --legacy-peer-deps// astro.config.mjs
import { defineConfig } from 'astro/config'
import solidNext from 'astro-solid-next'
export default defineConfig({
integrations: [solidNext()],
})---
import Counter from '../components/Counter.tsx'
---
<Counter start={5} client:load>
<p>slotted content</p>
</Counter>Options: include / exclude (vite filter patterns) to scope which files the Solid
compiler transforms — needed when combining multiple JSX frameworks.
- Server islands render with
await renderToStream(fn, { renderId, noScripts })— awaiting the stream resolves the fully settled HTML, so async in the reactive graph (promises increateMemounder aLoadingboundary) settles before the island serializes. Server-only islands render insideNoHydrationwithnoScripts: true. - Hydration uses the same
renderIdon the client (hydrate(fn, el, { renderId })), scoping hydration keys per island. The hydration bootstrap is injected once per page via Astro'srenderHydrationScript→generateHydrationScript(). - Props updates (view transitions) patch a
createStorewithreconcile, same as the official 1.x renderer — stores are part of coresolid-jsin 2.0. - The compiler runs in legacy transform-only mode (
ssr: true, nostart): Astro owns the server and the document, the plugin only provides hydratable client output and string-mode SSR output per Vite environment.
Keep Solid components unstyled and share one styling system with the rest of the site — the island boundary should separate interactivity, not design.
The mechanics: Astro's <style> in .astro files is scoped (hash selector), so it
deliberately does not reach the HTML a Solid island renders. What both worlds share:
- Global stylesheets — imported in a layout or via
<style is:global>. - CSS imported from the component files — a Solid component can
import './counter.css'or use CSS modules; Astro extracts it into the page's CSS bundle at build time (shipped as a<link>with the page, so no FOUC).
Recommended setups, in order:
- Tailwind (or another utility system) — one config, and
.astrotemplates and.tsxislands write the same classes. For headless libraries like Kobalte, style state via the exposed data attributes:data-[expanded]:rotate-180,data-[highlighted]:bg-accent, etc. - Global design tokens + component classes — custom properties (
--color-accent,--radius) in one global file, plain classes written against them, used from both sides.
Avoid: inline style="" in components (can't see your tokens or theme), scoped Astro
styles targeting island internals (they silently won't match), and runtime CSS-in-JS
(payload and hydration cost).
examples/basic — a static Astro build with a server-only island and a hydrated
counter island with slotted content.
cd examples/basic && npm i --legacy-peer-deps && npm run build && npm run previewExperimental. Tracks the Solid 2.0 RC (peer ^2.0.0-rc.0) and Astro ≥ 5 (tested on
Astro 7 / Vite 8). Expect churn until Solid 2.0 is stable.