This guide covers how to set up Reef in a SolidStart application with full SSR support and StyleX integration.
Add the required dependencies to your project:
# Using bun bun add @228-co/reef @stylexjs/stylex @stylexjs/unplugin
Configure the StyleX Vite plugin in your app.config.ts:
import { defineConfig } from "@solidjs/start/config";
import stylex from "@stylexjs/unplugin";
export default defineConfig({
server: {
preset: "cloudflare_module",
},
vite: {
plugins: [
stylex.vite({
useCSSLayers: true,
enableDevClassNames: true,
treeshakeCompensation: true,
unstable_moduleResolution: {
type: "commonJS",
},
}),
],
},
});Wrap your application with ReefProvider inside a Suspense boundary. The Suspense wrapper is required for proper SSR hydration.
// src/app.tsx
import "@228-co/reef/css-reset.css";
import { ReefProvider, ScrollRestoration } from "@228-co/reef/components";
import { chalkboardColors } from "@228-co/reef/themes/chalkboard.stylex";
import { textPageSizing } from "@228-co/reef/themes/text-page.stylex";
import { Router } from "@solidjs/router";
import { FileRoutes } from "@solidjs/start/router";
import { Suspense } from "solid-js";
export default function App() {
return (
<Router
root={(props) => (
<Suspense>
<ReefProvider
theme={{ sizing: textPageSizing, colors: chalkboardColors }}
>
<ScrollRestoration storageKey="my-app-scroll" />
{props.children}
</ReefProvider>
</Suspense>
)}
>
<FileRoutes />
</Router>
);
}Suspense - Required wrapper for SSR hydration. Without it, you'll see hydration mismatch errors.
css-reset.css - Provides consistent baseline styles across browsers. Import this before any other styles.
ScrollRestoration - Optional component that persists scroll position across page refreshes.
To prevent a flash of unstyled content during SSR, apply the theme classes directly to the <html> element in your entry-server.tsx:
// src/entry-server.tsx
import { createHandler, StartServer } from "@solidjs/start/server";
import * as stylex from "@stylexjs/stylex";
import { rootStyle } from "@228-co/reef/root-styles.stylex";
import { chalkboardColors } from "@228-co/reef/themes/chalkboard.stylex";
import { textPageSizing } from "@228-co/reef/themes/text-page.stylex";
const themeProps = stylex.props(
rootStyle.root,
chalkboardColors,
textPageSizing,
);
export default createHandler(() => (
<StartServer
document={({ assets, children, scripts }) => (
<html lang="en" class={themeProps.className} style={themeProps.style}>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
{assets}
</head>
<body>
<div id="app">{children}</div>
{scripts}
</body>
</html>
)}
/>
));This ensures the theme variables are available immediately when the page loads, eliminating any visual flash. The rootStyle.root applies base styles like background color and text color, while the theme overrides (chalkboardColors, textPageSizing) customize the visual appearance.
chalkboardColors - Dark theme with chalk-like colors, supports light/dark mode
whitePaperColors - Light theme optimized for readability
textPageSizing - Larger typography for content-heavy pages (blogs, docs, landing pages)
appPageSizing - Denser UI with smaller fonts for web applications
Once set up, you can import and use Reef components in your routes:
import { Text, Button, Container } from "@228-co/reef/components";
import * as stylex from "@stylexjs/stylex";
const styles = stylex.create({
page: {
padding: "2rem",
maxWidth: "800px",
margin: "auto",
},
});
export default function Home() {
return (
<main {...stylex.props(styles.page)}>
<Text.H1>Welcome</Text.H1>
<Text.body>
This is a Reef-powered page with full SSR support.
</Text.body>
<Container status="info">
<Text status="info">
Components automatically use theme colors and sizing.
</Text>
</Container>
<Button status="success">Get Started</Button>
</main>
);
}If you see hydration mismatch errors, ensure ReefProvider is wrapped in <Suspense>. This is required because some providers use client-side APIs.
If you see a flash when the page loads, make sure you've added the theme props to the <html> element in entry-server.tsx as shown above.
Ensure the StyleX Vite plugin is configured correctly and that you've imported @228-co/reef/css-reset.css at the top of your app.tsx.