Using with React frameworks
Notes for Next.js, Remix, Vite, TanStack Start, and Astro.
Using with React frameworks
Section titled “Using with React frameworks”Cynosure is a plain React package — it works with every major React framework. A few framework-specific notes below.
Next.js (App Router)
Section titled “Next.js (App Router)”-
Import the stylesheets once in
app/globals.cssor at the top ofapp/layout.tsx:import '@arshad-shah/cynosure-tokens/css';import '@arshad-shah/cynosure-tokens/css/dark';import '@arshad-shah/cynosure-react/styles.css'; -
Mark the file that hosts
ThemeProvideras a client boundary:app/providers.tsx 'use client';import { ThemeProvider, TooltipProvider } from '@arshad-shah/cynosure-react';export function Providers({ children }) {return (<ThemeProvider defaultTheme="system"><TooltipProvider>{children}</TooltipProvider></ThemeProvider>);} -
Render the theme init script in
<head>to avoid a flash on reload:import { getThemeInitScript } from '@arshad-shah/cynosure-react';export default function RootLayout({ children }) {return (<html lang="en" suppressHydrationWarning><head><script dangerouslySetInnerHTML={{ __html: getThemeInitScript() }} /></head><body><Providers>{children}</Providers></body></html>);}
suppressHydrationWarning on <html> silences the benign warning that
arises from the data-theme attribute being set by the init script
before React hydrates.
-
Put the stylesheet imports in
root.tsxand export them vialinks:import styles from '@arshad-shah/cynosure-react/styles.css?url';import tokens from '@arshad-shah/cynosure-tokens/css?url';export const links = () => [{ rel: 'stylesheet', href: tokens },{ rel: 'stylesheet', href: styles },]; -
Wrap
<Outlet />in the providers as in the Next.js example.
Vite + React Router
Section titled “Vite + React Router”Plain client-side. Follow the quickstart — no framework-specific changes.
TanStack Start
Section titled “TanStack Start”Treat like Next.js. The 'use client' directive is not required, but the
theme init script + suppressHydrationWarning pattern applies.
Astro (islands only)
Section titled “Astro (islands only)”Render Cynosure inside a React island (client:load or client:idle). Keep
the island container small so hydration cost stays proportional.
Tree-shaking
Section titled “Tree-shaking”- Use per-component entries in hot paths:
@arshad-shah/cynosure-react/button,@arshad-shah/cynosure-react/combobox, … - Root barrel (
@arshad-shah/cynosure-react) works fine with modern bundlers (Vite, Next.js with Webpack 5 / Turbopack, Rollup) —sideEffects: false+ per-component modules keep tree-shaking effective.
CSS in SSR
Section titled “CSS in SSR”Bundlers pick up the per-component CSS through the ESM imports, so SSR
frameworks emit the right <link> tags automatically. If you are building
your own SSR pipeline, collect the generated CSS chunks as you would for
any Vanilla-Extract library.