Skip to main content

Documentation 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.

styled-ppx supports Melange through the standard opam and dune toolchain. Once installed, the PPX binary integrates with dune’s (preprocess (pps ...)) stanza and the styled-ppx.melange runtime library supplies the CSS module that the generated code depends on.
This guide assumes you already have a working Melange project with opam and dune. If you’re starting from scratch, follow the official Melange getting started guide first.
1

Install styled-ppx via opam

Install the styled-ppx opam package. This provides both the PPX binary and all runtime libraries:
opam install styled-ppx
The package exposes two libraries:
  • styled-ppx — the PPX that transforms [%styled.div {|...|}], [%cx {|...|}], and related extensions at compile time.
  • styled-ppx.melange — the runtime library that exposes the CSS module required by styled components at runtime.
2

Update your dune build files

You need to do two things in your dune configuration:
  1. Add styled-ppx under (preprocess (pps ...))
  2. Add styled-ppx.melange under (libraries ...)
If your project uses a (library ...) stanza with (modes melange):
(library
  (name ...)
  (modes melange)
  (libraries
+   styled-ppx.melange
    reason-react)
  (preprocess
    (pps
+     styled-ppx
      melange.ppx
      reason-react-ppx)))
If your project uses a (melange.emit ...) stanza:
(melange.emit
  (libraries
+   styled-ppx.melange
    reason-react)
  (preprocess
    (pps
+     styled-ppx
      melange.ppx
      reason-react-ppx)))
reason-react and reason-react-ppx are optional. They are only required if you use styled components ([%styled.div {||}]). If you only use [%cx] or [%css] to generate classNames, you can omit them.
3

Write your first styled component

With dune configured, every Reason file in your library can use the styled-ppx extensions. Here is a complete example showing a dynamic Link component with a default colour prop, alongside a [%cx] layout className:
/* This is a ReasonReact module with those styles encoded as a unique className */
module Link = [%styled.a (~color=CSS.hex("4299E1")) => {|
  font-size: 1.875rem;
  line-height: 1.5;
  text-decoration: none;
  margin: 0px;
  padding: 10px 0px;
  color: $(color);
|}];

/* This is a unique className generated by the styles */
let layout = [%cx {|
  display: flex;
  width: 100%;
  height: 100%;
  justify-content: center;
  align-items: center
|}];

/* Later in a component */
<div className=layout>
  <Link
    color={CSS.hex("333333")}
    href="https://sancho.dev"
    rel="noopener noreferrer">
    {React.string("sancho.dev")}
  </Link>
</div>;
The Link module is a fully typed React <a> component. The labelled argument ~color defaults to CSS.hex("4299E1") and is interpolated into the CSS via $(color). The layout binding is a plain string containing a hashed className computed by the PPX at compile time.

Next steps

Once your Melange project is styled and building, explore the full reference documentation:

Build docs developers (and LLMs) love