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.

Common questions about styled-ppx are collected here. If your question is not answered below, you can open an issue on GitHub or ask in the Reason Discord.
Yes. The PPX transformation operates on the Abstract Syntax Tree (AST), and ReScript, Reason, and OCaml share the vast majority of that tree structure — so a single PPX binary can support all three languages.ReScript has been the most challenging target because the project is actively diverging its AST from the upstream OCaml one. Support is maintained but may occasionally lag behind newly introduced syntax.The syntax you use for the extension node differs by language:
  • ReScript: %styled.div(...)
  • Reason / OCaml: [%styled.div {|...|}]
The VSCode extension provides CSS syntax highlighting for all three syntaxes.
ReScript v9 and v10 are officially supported. Support for v11 is in active development — you can follow progress and contribute at PR #482.
A PPX (PreProcessor eXtension) is an OCaml preprocessor plugin that runs as part of the compilation pipeline, before type-checking. When the compiler encounters a %styled.*, %cx, or %css extension node, it hands the node to styled-ppx.styled-ppx then:
  1. Parses the CSS string embedded in the extension node using its own CSS parser.
  2. Validates every property/value pair against the supported CSS grammar, reporting any errors as standard compiler errors with accurate source locations.
  3. Rewrites the extension node into ordinary OCaml/ReScript code that calls the styled-ppx runtime library (which wraps emotion).
The result is that type errors in your CSS surface at compile time just like type errors in your application code.
styled-ppx uses emotion under the hood. The PPX rewrites your CSS extension nodes into calls to the emotion runtime, which injects styles into the DOM at runtime.Unlike bs-css, there is no additional runtime DSL layer — styled-ppx’s own runtime is minimal. The dominant cost is the emotion runtime itself, which is shared across your entire application and is typically well under 10 kB gzipped.
Yes. The %cx and %css extension points work independently of React — they produce class name strings and CSS rule values that you can use with any rendering layer.Only %styled.* creates React components. If you are targeting a non-React context (server-side rendering, native OCaml, or a different UI framework), %cx and %css are the right tools.
Use CSS.unsafe(propertyName, value) to bypass the type checker for any property that styled-ppx does not yet support. For example:
let styles = CSS.unsafe("appearance", "none")
CSS.unsafe returns a CSS.rule value, so it can be combined freely with the Array API and other typed rules. This makes it straightforward to opt out of type checking on a per-property basis while keeping the rest of your styles fully typed.
Yes, and you can do it incrementally. The Array API accepts CSS.rule values, and CSS.unsafe provides an escape hatch for any properties that are not yet covered by styled-ppx.A common migration path is to keep existing bs-css call sites untouched while writing new components with styled-ppx string syntax, then gradually replacing the old sites when time allows. The two approaches can coexist in the same codebase without conflict.

Build docs developers (and LLMs) love