About

Author and maintainer: David Sancho (opens in a new tab)


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 (opens in a new tab) f (opens in a new tab)e (opens in a new tab)w (opens in a new tab) p (opens in a new tab)e (opens in a new tab)o (opens in a new tab)p (opens in a new tab)l (opens in a new tab)e (opens in a new tab) were asking for it.

During that time, there were a few efforts to bring type-safety to CSS with bs-css (opens in a new tab) and bs-emotion (opens in a new tab). 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 CssJs.width(calc(min, percent(100.), px(20))) CssJs.width(calc(min, percent(100.), px(20)));). In real world usage I would end up using CssJs.unsafe.
  • The runtime was huge. The bundle-size of bs-css starts with 64kb and goes up considerably with the usage, even with ReScripts dead code elimination.
  • 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 (opens in a new tab).

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 (opens in a new tab).

Credits

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