The highlights of this release:

Smaller and much faster, going from 16.1kB to less than 15kB (depending on your bundler and usage of the babel plugin) and speeding up mounting by ~25% and re-rendering by ~7.5% (potentially more if this PR is merged)

going from 16.1kB to less than 15kB (depending on your bundler and usage of the babel plugin) and speeding up mounting by ~25% and re-rendering by ~7.5% (potentially more if this PR is merged) A brand new createGlobalStyle API , the hot-reloadable and themable replacement for the old injectGlobal

, the hot-reloadable and themable replacement for the old Support for the "as" prop, a more flexible alternative to .withComponent()

a more flexible alternative to Removal of Comp.extend , with an automatic codemod to move your entire codebase to the unified styled(Comp) notation

, with an automatic codemod to move your entire codebase to the unified notation Full StrictMode compliance for React v16, which also means we had to drop support for React v15 and lower (you may be able to use polyfills to get v15 working with styled-components v4)

which also means we had to drop support for React v15 and lower (you may be able to use polyfills to get v15 working with styled-components v4) Native support for ref on any styled component, no more innerRef thanks to React v16

Why is it a beta?

We want to make sure people have enough time to stress test the changes and to get updated typings and syntax highlighting support for all the new APIs in place. We are planning on the beta period to last about a month.

Performance, Performance, Performance!

Back when we released v2 we promised to focus on performance after nailing our core APIs, and have since delivered with speedups in various patch releases and a massive 10x boost in v3.1.

We’re happy to announce that we’re continuing the trend with this release! Thanks to internal optimizations around memory usage, JS engine implementation details, and various refactorings, styled-components v4 mounts faster by ~25% for both deep and wide component trees, and updates dynamic styles faster by ~7%:

styled-components v3 compared to v4 in three benchmarks: the first two are mounting component trees, the last is updating components with dynamic styles

While that’s great in isolation, lets look at how v4 compares to other libraries in the wider CSS-in-JS ecosystem with its mounting speed:

As you can see, styled-components v4 is blazing fast™️. We’re within a standard deviation of all the fastest libraries out there, both in terms of mounting as well as updating speed, which means performance is officially no longer an issue! 🎉

While this is a great evolution that’s been a long time in the works, we’re nowhere near done — we’ll always continue keeping an eye on potential optimizations to improve our performance.

New Global Styles API

We’ve been cooking a new global styling API behind the scenes for a while. The old injectGlobal had three big issues: it couldn’t be dynamically updated, it wasn’t hot-reloadable and it wasn’t contextually themable.

We’re excited to introduce you to createGlobalStyle , our new dynamically updateable API for global styles! Here’s what it looks like:

import { createGlobalStyle } from "styled-components"; const GlobalStyle = createGlobalStyle`

html {

color: red;

}

`; export default function App() {

return (

<div>

<GlobalStyle />

This is my app!

</div>

);

}

With createGlobalStyle , your global styles are now part of the React component tree. While that might not sound like a big difference it makes it possible to dynamically update, hot-reload, and contextually theme your global styles, exactly like you would any other styled component! 😍

import { createGlobalStyle, ThemeProvider } from "styled-components"; // Global styles but theme- and update-able!

const GlobalStyle = createGlobalStyle`

html {

background: ${p => p.backgroundColor};

color: red;

font-family: ${p => p.theme.fontFamily};

}

`; export default function App() {

return (

<ThemeProvider theme={{ fontFamily: "Helvetica Neue" }}>

<GlobalStyle backgroundColor="turquoise" />

</ThemeProvider>

);

}

Adios .extend, hello origami magic!

This release also includes an internal rework so that wrapped styled components now automatically “fold” and only a single component is rendered.

“Okay, but… what does that mean for me?”

We introduced the StyledComp.extend API because it lets us do some optimizations based on the fact that the component you’re extending was a styled component. Thanks to the internal work to automatic folding, using styled(StyledComp) automatically applies the same optimizations StyledComp.extend used to do! That means .extend isn’t a useful part of the API anymore, so we’re removing it. One less API to think about and less code to ship — win-win! ✨

The new “as” polymorphic prop

There’s one more thing that we’re really stoked about in this v4 release: native support for the as prop on any styled component to change what is rendered dynamically at runtime! It is best explained with an example:

import styled from "styled-components"

import { Link } from "react-router-dom" // <Component /> renders a div to the DOM

const Component = styled.div`

color: red;

`

<Component>Hello World!</Component> // But we can also make it render any other HTML tag or component!

<Component as="span">Hello World!</Component>

<Component as={Link} to="home">Hello World!</Component>

Compared to our existing .withComponent(something) this is way more flexible since you don’t have to define the replacement ahead of time, and with our new internal folding mechanism you don’t lose any styling if your base component is a styled-component!

import styled from "styled-components" const RedColor = styled.div`

color: red;

` const BlueBackgroundRedColor = styled(RedColor)`

background: blue;

` <BlueBackgroundRedColor as="span">Hello!</BlueBackgroundRedColor>

// Even though we switch to rendering a `span` from rendering

// <RedColor />, this will still have a red color on top of

// the blue background!! (.withComponent couldn't do that)

As you can see, the as prop is super awesome and will make it much easier to render semantic HTML everywhere in your applications. 💯 No more excuses for <div> soups!

Note that we’re not deprecating .withComponent just yet while we make sure the as prop is a suitable replacement for all use cases. Assuming it turns out to be, .withComponent will be removed in the next major release.

React v16 and refs

During our internal migration to the new React v16 APIs, we also found that innerRef could be done away-with via the new React.forwardRef API 👏 We never enjoyed this workaround because it felt so hacky… but thanks to the lovely work by the React team, now native ref can be used:

import styled from "styled-components" const Component = styled.div`

color: red;

` // Later in your render function

<Component ref={element => { this.myRef = element; }}

TypeScript improvements

We’re not directly responsible for this, but we’re very excited about the new @babel/preset-typescript since it means that y’all TypeScript users can finally use the styled-components babel plugin with all its benefits, including easier debugging with the component names in the classes, server-side rendering support and smaller bundle sizes! Highly recommended. 👏

The types are now migrated to DefinitelyTyped!