About

Author and maintainer: David Sancho


Motivation

There are a few reasons why this project exists and why it came to live.

There was a need

In my experience, writing React with a CSS-in-JS library is one of the best combos for writing scalable design systems, UI libraries and applications. When I discovered Reason back in the day (around 2018), it wasn’t possible to bind to styled-components or emotion. Even a few people were asking for it.

During that time, there were a few efforts to bring type-safety to CSS with bs-css and bs-emotion. Even though I liked that approach, it had a few drawbacks:

  • The need for learning a new DSL on top of CSS was tedious. Very fancy for simple properties, but almost impossible for more complex ones (a classic example width: calc(100% - 20px) became CSS.width(calc(min, percent(100.), px(20))) CSS.width(calc(min, percent(100.), px(20)));). In real world usage I would end up using CSS.unsafe.
  • The runtime was huge. The bundle-size of bs-css starts with 64kb and goes up considerably with the usage, even with the dead code elimination made by the compiler.
  • The fact of having a runtime involved to only write safe CSS doesn’t seem like a nice trade-off.

It’s possible and a good solution

Embedding CSS inside Reason/OCaml seemed like a bad idea at first, mostly since most CSS-in-JS solutions that use native CSS relied on a JavaScript feature that isn’t available in Reason: template literals.

After discovering what a ppx was (“a mechanism to embed other languages inside Reason”), and it could mimic the template literals, I jumped straight into hacking a prototype that became this project.

Embedding languages inside others isn’t a new concept and has been happening for a long time. In fact, the most common case of an embedded language is usually CSS inside HTML. Using CSS enables all sorts of integrations: Editors, DevTools, prototyping tools, Github Copilot, etc. Even for designers that don’t want to understand or care about ReScript.

It can be more powerful than the JavaScript equivalents

Enabling type-safety in CSS is a nice to have, rather than a hard requirement, but nevertheless useful. styled-ppx brings an entire CSS compiler and type-chcker. This enables features from SASS (like supporting future CSS version features) with features from emotion to inline your styles and code together. Features that aren’t implemented but are on the horizon are mostly related in extracting the CSS from the runtime and making your styles static at runtime and have zero run-time.

To know more about how it works or what are the benefits I recommend you watch my talk at ReasonSTHLM Meetup.

Credits

Here’s a list of people that helped me and I couldn’t have made styled-ppx without them:

  • Javier Chávarri: for the introduction to Reason. Teaching me all his knowledge about OCaml, AST, ppx rewriters and the help of bootstrapping the project.
  • Alessandro Strada: this project started with inspiration from bs-css-ppx.
  • Eduardo Rafael: to teach me how to write a compiler and a type-checker. His initial implementation of the CSS Value definition and the parser combinator.
  • Rizo: for the help with the API design, discussions and great conversations about styling and CSS.
  • Max Lantas: for implementing the VSCode extension.
  • Egor Chemohonenko: for implementing the vim plugin.
  • This project builds on a long line of earlier work by clever folks in the JavaScript community from around the world. People from styled-components, emotion, compiledcssinjs, linaria, and many more.