styled-ppx is a ppx and a library that brings styled components to OCaml and Reason, for both Melange and native (server-reason-react ). Write plain CSS inside your components and get React components or class names back — parsed, validated and type-checked at compile time.
module Center = [%styled.div {|
height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
|}];
<Center> {React.string("Hello from the future!")} </Center>
module Center = [%styled.div {|
height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
|}]
let app = <Center> (React.string "Hello from the future!") </Center>
styled-ppx ships its own CSS parser and type-checker. Every property and value is validated against the CSS spec while you compile: a typo in a property name, an invalid value, or a wrongly-typed interpolation is a compile error, not a broken page. This is a huge time-saver when working with CSS at scale.
Unlike CSS-in-JS libraries, styled-ppx does not generate styles at runtime. All CSS is extracted while your project compiles:
styled-ppx.generate) collects every rule in your project and writes a single, deduplicated styles.css.$(expr) interpolations) become CSS custom properties supplied through the style attribute.No style injection, no hashing at runtime, no flash of unstyled content, no double-rendering for SSR. Read more in How it works.
.css asset at build time$( ... ), type-checked against the property it’s used inreason-react and native OCaml with server-reason-reactcss-<hash>-<binding>), minified in productionGenerally speaking, a ppx is OCaml’s system for macros, similar to babel plugins : a small program that runs before compilation and transforms your source code.
styled-ppx expands four extensions:
| Extension | What you get |
|---|---|
[%css "..."] | a CSS.styles value: class names plus (optionally) inline custom-property values |
[%styled.<tag> "..."] | a React component for the given HTML tag |
[%styled.global "..."] | global styles as a React component (@font-face, resets, :root variables) |
[%keyframe "..."] | a typed @keyframes animation name |
If you are curious about the actual transformation, check the snapshot tests .
You can learn more about ppxes in Tarides blog: Introduction to OCaml ppx ecosystem .