styled-ppx is a PPX and runtime library that brings styled components to ReScript, Melange, and OCaml. It lets you create React components — or plainDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/davesnx/styled-ppx/llms.txt
Use this file to discover all available pages before exploring further.
className strings — backed by real CSS syntax, validated at compile time before your code ever runs.
Instead of learning a new DSL, you write actual CSS inside extension nodes like %styled.div or %cx. The PPX runs before compilation, parses your CSS, type-checks it, and expands the extension into valid OCaml/ReScript code. If your CSS has a typo or an invalid value, you get a compile-time error — not a silent style bug at runtime.
A quick example
Center module becomes a fully-typed React component whose className is generated at build time by hashing the CSS rules. No runtime CSS-in-JS parsing, no style objects, no API to memorise — just CSS.
Core extensions
styled-ppx exposes five extension points, each serving a distinct purpose:| Extension | What it produces |
|---|---|
%styled.div / [%styled.div] | A React component wrapping a <div> (any HTML tag is supported) |
%cx / [%cx] | A className string from one or more CSS declarations |
%css / [%css] | A single Css.rule value, composable with the Array API |
%keyframe / [%keyframe] | A typed keyframe name for use in animation-name |
%styled.global / [%styled.global] | Injects global styles (resets, base typography, etc.) |
The
%ext syntax is used in ReScript. The [%ext] syntax is the equivalent for Reason and OCaml. Both forms are fully supported — the PPX transformation operates on the shared AST.Dynamic styled components
Styled components accept labelled arguments that map directly to CSS interpolations, giving you type-safe dynamic styling without any runtime overhead:Why styled-ppx instead of bs-css or bs-emotion?
Libraries like
bs-css and bs-emotion are excellent, but they require you to learn a bespoke OCaml DSL that mirrors CSS — functions like backgroundColor, display \flex, px 16`, and so on. styled-ppx takes a different approach: write real CSS, get full type safety.- No new DSL to learn. If you know CSS, you already know how to use styled-ppx.
- Smaller runtime. The PPX resolves and hashes styles at compile time; the runtime only needs to inject the pre-computed stylesheet into the DOM.
- Better error messages. Parse errors and type errors are reported at the exact CSS source location, not as opaque OCaml type mismatches.
- Works without React.
%cxand%csscan be used in any context — UI frameworks, server-side rendering, or plain native programs.
Platform support
styled-ppx integrates with three distinct platforms. Pick the guide that matches your project:ReScript
Install via npm, configure
bsconfig.json, and use %styled.div in your ReScript project within minutes.Melange
Install via opam, add a dune stanza, and write Reason-syntax styled components for Melange React apps.
OCaml Native
Use
styled-ppx.native for server-side rendering with server-reason-react and CSS.get_stylesheet().Feature highlights
Zero abstraction over CSS
Write standard CSS syntax directly inside your source files. No wrapper functions, no style objects — the full CSS specification is available as-is.
Compile-time validation
The built-in CSS parser and type-checker reject invalid properties and values before your code compiles, eliminating an entire class of style bugs.
Component-based styling
%styled.div creates a real React component. It accepts all standard HTML props for its element, plus any labelled arguments you declare for dynamic styles.Pattern-matching friendly
Because styles are plain OCaml values and
className is a string, you can use pattern matching, composition, and labelled arguments just as you would with any other value.Multi-platform
The same extensions work in ReScript (via npm), Melange (via opam + dune), and OCaml native (via opam + dune). The PPX targets the shared AST.
Server-side rendering
The
styled-ppx.native runtime implements emotion’s hashing algorithm on the server. CSS.get_stylesheet() and CSS.style_tag let you collect and inject all styles for SSR.Editor support
A VSCode extension and a vim plugin provide CSS syntax highlighting inside extension nodes.
Labelled class hashes
Generated classNames include the component or variable name (e.g.
css-1xuw4bg-Link), making it easy to identify styles in browser DevTools.How the PPX works
A PPX is OCaml’s macro system — a small program that runs before the compiler and transforms the source AST. styled-ppx intercepts every occurrence of%styled.*, %cx, %css, %keyframe, and %styled.global, parses the embedded CSS string, validates it against its own CSS type-checker, and replaces the extension node with the equivalent OCaml/ReScript code that calls into the runtime.