About

Author and maintainer: David Sancho

Maintainer: José Eduardo Monteiro


Motivation

There are a few reasons why this project exists and why 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 days (arround 2018), it wasn't possible to bind to styled-components neither emotion. Even (a few people were asking for it.

During that time, there were a few efforts on bringing type-safety on top of CSS with bs-css or bs-emotion. Even thought 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)width: calc(100% - 20px) became CssJs.width(calc(min, percent(100.), px(20)));CssJs.width(calc(min, percent(100.), px(20)));). For the real world usage I endup using CssJs.property("property", "value") most of the times.
  • The runtime is huge. The bundle-size of bs-css starts with 64kb and goes up considerably with the usage and ReScript death code elimiation.
  • The fact about having a runtime involved to only write safe CSS doesn't seem like a nice trade-off.

It's possible

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, 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 sort of integrations: Editors, DevTools, prototyping tools, Github Copilot, etc. Even for designers that don't want to understand neither care about ReScript.

It can bring more features than the JS

Enabling type-safety into CSS is more like a nice to have, rather than a hard requirement. Features that aren't implemented but are on the horizon are mostly related in extracting the CSS from the runtime and keep it in a separate file. Forcing to have a zero run-time application. Provide a safe way to access a shared theme without having to worry about the runtime, would be a killer feature, that I wished I had before.

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

Credits

Here's a list of people that helped me and couldn't make it without them:

  • Javier Chávarri: for the introduction to Reason. Teaching me all his knowledge about OCaml, AST, ppx rewritters and the help of boostrapping 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.
  • 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.