React bindings for Styletron CSS-in-JS toolkit providing styled components and hooks
—
Context system for providing Styletron engine instances to styled components and hooks throughout the React component tree. The Provider component is essential for all Styletron React functionality.
Provides Styletron engine instance to all styled components and useStyletron hooks in the component tree.
/**
* Provides Styletron engine instance to styled components and hooks
* @param props.children - React children that will have access to the engine
* @param props.value - Styletron engine instance (StandardEngine)
* @param props.debugAfterHydration - Enable debug mode after SSR hydration (optional)
* @param props.debug - Debug engine instance for development tools (optional)
*/
const Provider: React.ComponentType<{
children: React.ReactNode;
value: StandardEngine;
debugAfterHydration?: boolean;
debug?: DebugEngine;
}>;Basic Usage:
import React from "react";
import { Provider, styled } from "styletron-react";
import { Client } from "styletron-engine-atomic";
// Create Styletron engine
const engine = new Client();
const StyledButton = styled("button", {
backgroundColor: "blue",
color: "white",
padding: "8px 16px",
});
function App() {
return (
<Provider value={engine}>
<div>
<h1>My App</h1>
<StyledButton>Click me</StyledButton>
</div>
</Provider>
);
}import React from "react";
import { renderToString } from "react-dom/server";
import { Provider, styled } from "styletron-react";
import { Server } from "styletron-engine-atomic";
// Server-side engine
const engine = new Server();
const App = () => (
<Provider value={engine}>
<styled.div $style={{ color: "red" }}>
SSR Content
</styled.div>
</Provider>
);
// Render on server
const html = renderToString(<App />);
// Get generated CSS
const css = engine.getCss();
// Send both HTML and CSS to client
const fullHtml = `
<html>
<head>
<style>${css}</style>
</head>
<body>
<div id="root">${html}</div>
</body>
</html>
`;import React from "react";
import { hydrateRoot } from "react-dom/client";
import { Provider, styled } from "styletron-react";
import { Client } from "styletron-engine-atomic";
// Client-side engine with SSR hydration
const engine = new Client({
hydrate: document.getElementsByTagName("style"),
});
const App = () => (
<Provider value={engine}>
<styled.div $style={{ color: "red" }}>
Hydrated Content
</styled.div>
</Provider>
);
// Hydrate on client
const container = document.getElementById("root");
hydrateRoot(container, <App />);import React from "react";
import { Provider, styled, DebugEngine } from "styletron-react";
import { Client } from "styletron-engine-atomic";
const engine = new Client();
const debugEngine = new DebugEngine();
const StyledComponent = styled("div", {
padding: "16px",
backgroundColor: "lightblue",
});
function App() {
return (
<Provider
value={engine}
debug={debugEngine}
debugAfterHydration={false}
>
<StyledComponent>
Debug-enabled component
</StyledComponent>
</Provider>
);
}import React from "react";
import { Provider, styled } from "styletron-react";
import { Client } from "styletron-engine-atomic";
// Different engines for different parts of the app
const mainEngine = new Client();
const isolatedEngine = new Client();
const MainButton = styled("button", { backgroundColor: "blue" });
const IsolatedButton = styled("button", { backgroundColor: "red" });
function App() {
return (
<Provider value={mainEngine}>
<div>
<h1>Main App</h1>
<MainButton>Main Button</MainButton>
{/* Nested provider with different engine */}
<Provider value={isolatedEngine}>
<div>
<h2>Isolated Section</h2>
<IsolatedButton>Isolated Button</IsolatedButton>
</div>
</Provider>
</div>
</Provider>
);
}interface StandardEngine {
/**
* Renders a style object to CSS class name
* @param styleObject - Style object to render
* @returns CSS class name string
*/
renderStyle(styleObject: StyleObject): string;
/**
* Renders keyframes animation to CSS
* @param keyframes - Keyframes object
* @returns Animation name string
*/
renderKeyframes(keyframes: KeyframesObject): string;
/**
* Renders font face declaration to CSS
* @param fontFace - Font face object
* @returns Font family name string
*/
renderFontFace(fontFace: FontFaceObject): string;
}class DebugEngine {
/**
* Creates debug information for styled components
* @param options - Debug options including stack information
* @returns Debug class name for development tools
*/
debug(options: {
stackInfo: {
stack: any;
message: any;
};
stackIndex: number;
}): string | undefined;
}When no Provider is found in the component tree, Styletron React will use a no-op engine and show a warning in development mode:
// This will trigger a warning in development
function ComponentWithoutProvider() {
const StyledDiv = styled("div", { color: "red" });
return <StyledDiv>No provider found</StyledDiv>;
// Warning: "Styletron Provider is not set up. Defaulting to no-op."
}Ensure the engine implements the StandardEngine interface:
import { Client, Server } from "styletron-engine-atomic";
// ✅ Compatible engines
const clientEngine = new Client();
const serverEngine = new Server();
// ❌ Incompatible - missing required methods
const invalidEngine = {
renderStyle: () => "class-name",
// Missing renderKeyframes and renderFontFace
};interface ProviderProps {
/** React children components */
children: React.ReactNode;
/** Styletron engine instance implementing StandardEngine interface */
value: StandardEngine;
/**
* Enable debug mode after SSR hydration (optional)
* Useful for avoiding hydration mismatches in development
*/
debugAfterHydration?: boolean;
/**
* Debug engine instance for development tools (optional)
* Only used in development mode for debugging and devtools integration
*/
debug?: DebugEngine;
}Use one Provider at the root of your application:
// ✅ Recommended
function App() {
return (
<Provider value={engine}>
<Router>
<Routes>
<Route path="/" component={Home} />
<Route path="/about" component={About} />
</Routes>
</Router>
</Provider>
);
}Initialize engines outside of render functions:
// ✅ Initialize outside component
const engine = new Client();
function App() {
return <Provider value={engine}>...</Provider>;
}
// ❌ Avoid initializing inside component
function App() {
const engine = new Client(); // Creates new engine on every render
return <Provider value={engine}>...</Provider>;
}Use different configurations for development and production:
const isDevelopment = process.env.NODE_ENV === "development";
const engine = new Client({
prefix: isDevelopment ? "dev_" : "",
});
const debugEngine = isDevelopment ? new DebugEngine() : undefined;
function App() {
return (
<Provider
value={engine}
debug={debugEngine}
debugAfterHydration={isDevelopment}
>
<AppContent />
</Provider>
);
}Install with Tessl CLI
npx tessl i tessl/npm-styletron-react