Creating truly universal React component systems

Announcing styled-components/primitives, an experimental entry point combining styled-components and react-primitives

Max Stoiber
Jun 19, 2017 · 4 min read

Creating truly universal React components that can be rendered on the web and in React Native is hard. There are different primitives: vs. , vs. / etc, and the styling also works entirely differently: ReactNative has it’s own CSS-like styling solution with JS objects, .

Until now your only option was to use React Native platform extensions to target specific platforms with your components. This allows you to share the logic and structure, which is already amazing, but it still means writing your styling multiple times.

Leland Richardson (Airbnb) has been working to create a shared set of primitives to be used to build truly cross-platform React apps. It’s called react-primitives and it’s a collection of six core components that are all you need to build everything you can dream of and render them consistently across the web, native and even Sketch.

Thanks to @MathieuDutour we’ve now combined the best of react-primitives and styled-components and we’re excited to bring you an experimental release of : Build your styled components once and use them on the web, on native and even render them to Sketch!

See the release notes if you want to know more, but let’s talk about the journey of getting here.


After finishing the first prototype of styled-components, Glen and I realised that it’d be nice to use it for ReactNative apps too. So we sat down and built a converter from CSS strings to ReactNative style objects (now it’s own package, ) and added an entry point, , that gave you access to the ReactNative primitives.

Creating ReactNative apps with styled-components

That worked well and lots of folks are using styled-components today to build their ReactNative apps with great success.


Meanwhile, Leland Richardson started hacking on react-primitives. The goal was to define and implement the smallest subset of primitives on all platforms that would allow users to cover 99% of use cases. He boiled it down to six APIs:

  1. : Declarative animations.
  2. : Styling the primitives.
  3. : A base component for Layout.
  4. : A base component for Text rendering.
  5. : A base component for Image rendering.
  6. : A base component for interaction.

These six APIs are then implemented and work the same way on the web, native and since recently even in Sketch, allowing us to create truly universal and reusable components. (see his talk at ReactEurope for a more in-depth explanation)

The issue was that you couldn’t use styled-components together with react-primitives. While this was something on the core teams’ mind, nobody had actually investigated or even tried adding a “react-primitives mode” to styled-components, it was all just faint dreams.


Mathieu Dutour submitted a PR to with a hacked version of styled-components combined with react-primitives to make it compatible with react-sketchapp. Just a day later we had a cleaned up PR against styled-components and here we are:

styled-components rendered to Sketch using react-sketchapp (example courtesy of Jon Gold)

These components don’t just render to Sketch though:

These are the exact same styled components, the exact same code, rendering in the browser, as a mobile app and in Sketch! 😱 💅

Try it out!

All you have to do to get started is install the two packages with , then and you’re good go! (assuming you have Node.js installed)

Note that this is an experimental release: There might be bugs and there also isn’t a massive amount of documentation (check out the react-primitives repo) for it yet. That being said, we’re super excited to finally have a first version of this in styled-components and we’re looking forward to hearing how you use to build your apps.

Stay stylish! 💅

💅 styled-components

Visual primitives for the component age.