DEV Community

greg lobinski
greg lobinski

Posted on • Originally published at dev.greglobinski.com

Use styled-jsx in create-react-app without ejection

I like styled-jsx. I build a GatsbyJS starter with it.

If you do not know, GatsbyJS is a static site generator for ReactJS.

I assume you know what styled-jsx is, otherwise you would not be interested in the title. Just in case, styled-jsx is a 'CSS in JS' library.

As I wrote, I got some experience with styled-jsx working with GatsbyJS, but a couple of days ago I wanted to use the library in an app based on create-react-app. I am pretty sure you know what create-react-app is. :)

There was one problem however.

To make styled-jsx work we have to edit the project's babel config. Nothing complicated, but create-react-app does not allow any changes like that, without ejecting. Ejecting however was not a thing I wanted.

I got stuck.

React App Rewired

Fortunately, react-app-rewired came to the rescue.

Tweak the create-react-app webpack config(s) without using 'eject' and without creating a fork of the react-scripts. All the benefits of create-react-app without the limitations of "no config". You can add plugins, loaders whatever you need.

So let's make styled-jsx work in an unejected create-react-app based application.

Rewire create-react-app to use styled-jsx

First, create an app with create-react-app.

npx create-react-app my-styled-jsx-app 

Move to the newly created folder.

cd my-styled-jsx-app 

Then install react-app-rewire as a dev dependency.

yarn add react-app-rewired --dev 

And styled-jsx as a dependency.

yarn add styled-jsx 

It's time to rewire create-react-app. Open the package.js file and edit from this...

"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", } 

... to this.

"scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test --env=jsdom" } 

Now we are able to edit the babel's config, as we want.

Create a new file called config-overrides.js in the root directory of the app.

const { injectBabelPlugin } = require("react-app-rewired"); module.exports = function override(config, env) { config = injectBabelPlugin(["styled-jsx/babel"], config); return config; }; 

That's it. We have an app build on create-react-app in which we can use styled-jsx without ejecting.

Restyle the app with styled-jsx

Move CSS style rules from outer css files into the App component's file.

import React, { Component } from "react"; import logo from "./logo.svg"; class App extends Component { render() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h1 className="App-title">Welcome to React</h1>  </header>  <p className="App-intro"> To get started, edit <code>src/App.js</code> and save to reload.  </p>  {`/* global styles */`} <style jsx global> {` body { margin: 0; padding: 0; font-family: sans-serif; } `} </style>  {`/* local styles */`} <style jsx>{` .App { text-align: center; } .App-logo { animation: App-logo-spin infinite 20s linear; height: 80px; } .App-header { background-color: #222; height: 150px; padding: 20px; color: white; } .App-title { font-size: 1.5em; } .App-intro { font-size: large; } @keyframes App-logo-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } `}</style>`  </div>  ); } } export default App; 

Clearing

The last thing to do is to make some clearing.

Remove needless CSS files.

remove src/index.css scr/App.css 

And their import statements from App.js and index.js.

Demo

There is a repo on Github - example-create-react-app-styled-jsx - with a live demo.

Top comments (2)

Collapse
 
liranh85 profile image
Liran Harary

Looked promising, but be warned: react-app-rewired doesn't support create-react-app v2, and they have no plan to do so.

I tried one of the alternatives - craco (Create React App Configuration Override) - but unfortunately it's broken at the moment following a change in how create-react-app organises its webpack configs: github.com/sharegate/craco/issues/61

So I'm sticking to Aphrodite for the moment for CSS-in-JS, as it doesn't require any special Babel configuration.

Collapse
 
wuddupdok profile image
Alex Goodwin

Awesome! Thanks, Greg.