Solid
Use yak with Solid 2 and Vite through @yak/solid. Static styles compile to classes, and dynamic styles become CSS variables driven by signals.
@yak/solid brings the yak API to Solid. The SWC plugin extracts your CSS at build time,
as it does for React. The thin runtime that remains follows Solid's model, where components run once and dynamic
styles follow signals instead of re-renders.
Install dependencies
Install @yak/solid together with the Solid 2 line of the Vite plugin (npm tag next):
npm i @yak/solid
npm i -D @solidjs/vite-plugin@next@yak/solid needs solid-js and @solidjs/web 2.0.0-rc.15 or later, Vite 7 or later and Node.js 22.18 or later.
Configure Vite
Add the yak plugin before solid(), so that it sees your original source:
import { defineConfig } from "vite";
import solid from "@solidjs/vite-plugin";
import { yak } from "@yak/solid/vite";
export default defineConfig({
plugins: [yak(), solid()],
});yak() takes the same options as the React Vite plugin, such as minify, prefix, contextPath, basePath,
foldStatic and debug. The API reference lists them all.
Write styled components
The API is the one you know from @yak/react. Interpolations that read props are tracked like any other reactive read
in Solid:
import { styled, css } from "@yak/solid";
import { createSignal } from "solid-js";
const Button = styled.button<{ $primary?: boolean }>`
color: #009688;
${(props) =>
props.$primary &&
css`
border-width: 2px;
`}
`;
const Progress = styled.div<{ $percent: number }>`
height: 8px;
background: #e5e5ef;
&::before {
content: "";
display: block;
height: 100%;
width: ${(props) => props.$percent}%;
background: #009688;
}
`;
export function App() {
const [percent, setPercent] = createSignal(30);
return (
<>
<Progress $percent={percent()} />
<Button $primary onClick={() => setPercent((p) => Math.min(p + 10, 100))}>
More
</Button>
</>
);
}A styled component without interpolations compiles to a plain CSS class. Dynamic interpolations become CSS variables
on the element's inline style, all computed in one memo per element, so a prop change updates the class and
style bindings without re-creating the element.
The css prop works on every intrinsic element and maps to Solid's class attribute. Its types become available as
soon as you import @yak/solid:
<p
css={css`
color: green;
`}
/>Theming
Create a yak.context.ts next to your vite.config.ts. The plugin picks it up automatically, and the module declaration
gives the theme its type:
export function getYakThemeContext() {
return { highContrast: false };
}
declare module "@yak/solid" {
export interface YakTheme extends ReturnType<typeof getYakThemeContext> {}
}Wrap your app in YakThemeProvider. Its theme prop is reactive, so signal reads inside it stay live and a theme
change only updates the themed styles:
import { render } from "@solidjs/web";
import { YakThemeProvider } from "@yak/solid";
import { createSignal } from "solid-js";
import { App } from "./App";
const [highContrast, setHighContrast] = createSignal(false);
render(
() => (
<YakThemeProvider theme={{ highContrast: highContrast() }}>
<App />
</YakThemeProvider>
),
document.getElementById("root")!,
);useTheme() returns an accessor, like a signal getter, and so does props.theme inside an interpolation:
import { styled, useTheme } from "@yak/solid";
const Label = styled.span`
color: ${(props) => (props.theme().highContrast ? "#000" : "#555")};
`;
function Toolbar() {
const theme = useTheme();
return <Label>{theme().highContrast ? "High contrast" : "Default"}</Label>;
}SolidStart
The Solid 2 Vite plugin has SolidStart built in. Turn it on with the start option, and yak works with it like with any
other Solid app:
import { defineConfig } from "vite";
import solid from "@solidjs/vite-plugin";
import { yak } from "@yak/solid/vite";
export default defineConfig({
plugins: [yak(), solid({ start: true })],
});Differences to @yak/react
If you come from @yak/react, the API stays the same apart from a few Solid-shaped details:
useTheme()andprops.themereturn accessors, so you readtheme().highContrastinstead oftheme.highContrast.- Use
classinstead ofclassName, also inside.attrs({ ... }). - Components run once, and Solid's reactivity updates the styles instead of a re-render.
Example project
examples/vite-solid shows a full setup
with theming, keyframes, .attrs() and the css prop.
Next steps
- Features: the shared API, shown with React
- API reference: all plugin options
- Troubleshooting: build errors and missing styles