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.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.
Does it support ReScript, Reason, and OCaml syntax?
Does it support ReScript, Reason, and OCaml syntax?
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 {|...|}]
Which ReScript versions are supported?
Which ReScript versions are supported?
ReScript v9 and v10 are officially supported. Support for v11 is in active development — you can follow progress and contribute at PR #482.
How does the PPX transformation work?
How does the PPX transformation work?
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:- Parses the CSS string embedded in the extension node using its own CSS parser.
- Validates every property/value pair against the supported CSS grammar, reporting any errors as standard compiler errors with accurate source locations.
- Rewrites the extension node into ordinary OCaml/ReScript code that calls the styled-ppx runtime library (which wraps emotion).
What is the runtime size overhead?
What is the runtime size overhead?
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.Can I use styled-ppx without React?
Can I use styled-ppx without React?
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.How do I handle unsupported CSS properties?
How do I handle unsupported CSS properties?
Use
CSS.unsafe(propertyName, value) to bypass the type checker for any property that styled-ppx does not yet support. For example: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.Can I migrate from bs-css?
Can I migrate from bs-css?
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.