Adding decorator support to Create React App projects using

Michiel Sikma
Apr 20 · 4 min read
Read this post on my blog for syntax highlighting.

Any experienced frontend developer should be familiar with the number one complaint about frontend development in recent years: it’s too difficult to get started. You’ve heard of this thing called React and so you install it and give it a try; only to find that it doesn’t “just work” and requires Babel, Webpack, npm and Node just to get started.

To help people conquer that cliff, Facebook developer and Redux author Dan Abramov created Create React App, which handles most of the difficult configuration work without you ever having to even see it and lets you get right down to work. It’s an elegant solution that works well even for larger applications that get deployed to production environments: at my workplace we’ve been developing two applications with it for over two years now.

Of course, there’s a flipside to the magic of “it just works”, which is that if something doesn’t work, it “just doesn’t work”. By handling the bundling configuration under the hood it’s impossible to make even small adjustments, such as adding new Babel plugins.

It’s at that point where I found myself recently, working on one of those production applications and wanting to use the proposed decorator syntax. While CRA does let you “eject” the config files so you can edit them, this also means you basically stop using CRA; it’s a one-way operation that adds a ton of complicated files to your project, which now you have to maintain forever. Even as an experienced frontend developer, I’d rather not.

Fortunately, there is a way to make small changes to the bundling setup without having to give up the convenience of zero-config. To do so, we need to swap out the core scripting component of CRA with , which is an alternative that allows config overrides. Together with the convenience functions provided by you can add almost any feature you like with just a few lines.

Here’s a step by step guide to add decorators (although you can use any of the other plugins described in the readme file after this):

1. If you’re starting a new project, just run Create React App like normal.

$ npx create-react-app my-app

The following steps will work with any existing app as long as you’re using CRA 2.0 or up — check that your version of is above 2.0.0 in your file to verify this.

2. Add and , and any Babel plugins you want to use.

Since we’re adding decorators, we’ll also add the @babel/plugin-proposal-decorators package.

$ yarn add --dev customize-cra react-app-rewired @babel/plugin-proposal-decorators

3. Open your file and edit the start, build and test scripts.

   "scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
+ "start": "react-app-rewired start",
+ "build": "react-app-rewired build",
+ "test": "react-app-rewired test",

"eject": "react-scripts eject"
},

The eject script stays the way it is, since becomes unnecessary the moment you run it.

4. Create a file in your project root.

This is where we’ll define our modifications. For now, add the following:

const { override, addDecoratorsLegacy } = require('customize-cra')

// Adds legacy decorator support to the Webpack configuration.
module.exports = override(addDecoratorsLegacy())

And that’s it; we’re done. Not a second spent digging through Babel or Webpack documentation.

Now let’s run to boot up the dev server and give it a try. If you want a quick example to copypaste to see if it's working, try this:

import React from 'react'

// Decorator that passes on a 'message' property to a class.
const addMessage = (str) => (component) => {
component.prototype.message = str
}

@addMessage('Hello world!')
class DecoratorTest extends React.PureComponent {
render() {
return <div>{ this.message }</div>
}
}
export default DecoratorTest

If all went well, this component should evaluate to .


There’s one obvious caveat to this whole setup: the currently supported version of decorators is legacy and will eventually go away. The proposed new version will change how they work on a fundamental level and the syntax will be subtly different. For example, future decorators will need to come after the keyword, whereas legacy decorators can appear before it.

However, the intent is for future decorators to be fundamentally compatible with the widely used legacy ones, and one of the spec design goals is to allow upgrading to the new syntax automatically via a codemod.

Keep yourself apprised by following the decorator proposal Github repo.


Update 2019–04–23: just yesterday, the Create React App team released their long awaited new major version 3.0.0. I’ve only done a quick test so far, but it seems everything still works as before. You can set the peer dependency to 3.0.0 and still use the latest and packages like normal. I was able to add decorators and also Less support and both of them worked without a hitch. If problems do crop up later, I will update this post.


I’m a remote developer from Rotterdam, The Netherlands. I’ve been programming professionally since 2005 and am currently working for Syft as frontend developer, and I don’t talk about myself in the third person.
Follow me on Twitter at
@michielsikma.

Michiel Sikma

Written by

Programmer and graphic designer based in the Netherlands. 日本語もちょっと話せます。以前1年ほど東京に住んでいました。

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade