· Maksim Valiantsiuk · My Talks · 19 min read
Create React App is Dead - What's Next?
Here I touch on the current state of Create React App and it's alternatives. Code and slides included.
Intro
Update: Latest update of the blog post was on August 30th 2023
Hello and welcome to my first blog post!
This post content is based on my recent tech talk, which I gave at company I work for (Vention). As promised to listeners in said company, I’ll share the slides and the code from the get go. I’ll also share the recording of the talk, once it’s ready.
Or once I’ll create a vid nyself, who knows?
Here’s the code and the slides
I’ll try to get everyone on the same page before we delve into more advanced topics, so if you already know what I’m onto, please bear with me, I’ll still try to make it interesting for y’all. Without further a do, let’s start with the latter.
Getting everyone on the same page. React learning experience
How it was?
You might have thought:
Max (yes, that’s me), why the hell you are talking about this right now? Isn’t it something everyone already knows?
Well, apparently not, and I’ll try to back it up as I tell you my story.
A while back when I started with learning React, it was a damn rollercoaster. Half the docs were written in class components, half in functional components (the default now!) - it was like learning React twice.
And don’t get me started on the key concepts around hooks and lifecycle methods. The info was sparse, and I had to roll up my sleeves and learn most of it by doing it myself and wading through API references.
For a newbie web-dev, some of these concepts were a mountain to scale, and the ‘escape hatches’ seemed like some sort of wizardry. And TypeScript with React? It wasn’t a match made in heaven, to say the least.
How is it now?
Fast forward to the present, React 18 with great features that come with it and the new Beta React Docs!
And the docs? They are absolutely fantastic! We’ve got more visual illustrations, over 600 interactive examples, and finally leaning towards Functional components is a breath of fresh air. Go check them out, if you haven’t! My personal favourite docs page is You Might Not Need an Effect.
But there was a bit of a hiccup – they initially recommended Create React App (CRA as shorthand).
Now, this recommendation ignited one of the most heated discussions I’ve ever seen.
It led to a fiery Pull Request by Theo @t3dotgg, which received thousands of impressions: both on Twitter and GitHub.
It was so intense that even Dan Abramov from the React Core team stepped in!
So, why did things get so spicy? And… what is Create React App, exactly? And why it was wanted gone from new React Docs?
What is Create React App? (in case you didn’t know)
Create React App (CRA) is a command-line tool from Meta (ex. Facebook) that allows you to generate a new React project and use a pre-configured Webpack build for development. If you happen to have configure that thing, you know it can be a pain.
Before CRA, developers needed to manually set up Webpack and Babel, which could be a complex and time-consuming process. CRA took care of all this setup behind the scenes, allowing developers to focus on coding their applications. However, while CRA has streamlined React project setup, it has also faced some criticism.
What are Create React App’s shortcomings?
Dan Abramov, one of the creators of Redux and part of the React Core team, elaborated on some of these criticisms. In short, his points are as follows:
- Speed and Tool Support: CRA can be slow and lacks support for some newer, popular tools. Alternatives like Vite are faster and offer more flexibility.
- Client-side App Design: CRA creates apps that load everything on the client-side, which can be slow and inefficient, especially on weak internet connections or less powerful devices.
- Lack of Web Leverage: CRA doesn’t provide enough structure to take full advantage of the web’s strengths, making it harder to create a fast, smooth user experience, forcing you to “eject”, which kills CRA purpose.
- Common Client-side App Issues: These problems aren’t unique to CRA. Any app built with only client-side rendering, like those made with Vue or Svelte, can have the same issues. Using server-side rendering or static site generation can help solve these problems. And inability for CRA to do so forces them to recommend other solutions.
P.S. All of the Dan’s sayings are transformed by me, using this PR comment by Dan as a source.
So what’s suggested?
Reasons above is why Theo, the author of this infamous Pull Request, suggested substituting Create React App with Create Vite App (CVA) in the docs. Which also happens to be a starter app that uses Vite under the hood.
Let’s make it very clear: Vite is opposed to Webpack - those are build tools. And CVA is an alternative to CRA - those are starter apps.
It’s often misinterpreted, because CRA internally uses Webpack, while CVA uses Vite.
What is Vite?
Vite is a build tool and development server designed to offer a faster and leaner development experience for modern web projects. It’s incredibly fast, as we’ll see further, and it’s growing in popularity.
The problem Vite aims to solve is the growing performance bottleneck in JavaScript-based tooling as we develop increasingly ambitious applications. Large scale projects with thousands of modules can result in long waits to spin up a dev server and even longer waits for file edits to be reflected in the browser. These slow feedback loops can affect developers’ productivity and happiness.
While my experience is not so much based on CRA, but all of the times it was a Webpack as a bundle tool! And I’m in on Vite promises: a lot of times I had to “compile code in my head” because each and every save could leave me waiting for ~20s and, in worst cases, up to 3+ minutes before dev server is served.
As a side note: I was using a pretty powerful machine, so it’s not a hardware issue. And those were production-grade projects for large companies.
But nevertheless, both Vite benchmarks and large portion of React community, including Dan Abramov, acknowledge that. And most modern tools are moving away from Webpack for that reason.
How does Vite work?
When cold-starting the dev server, a bundler-based build setup (like Webpack!) has to eagerly crawl and build your entire application before it can be served. When a file is edited in a bundler-based build setup, it is inefficient to rebuild the whole bundle for an obvious reason: the update speed will degrade linearly with the size of the app.
Vite addresses this issue by splitting your code into two parts - your dependencies and your source code. Dependencies are mostly plain JavaScript that do not change often during development, so Vite pre-bundles them as ES Modules (ESM). Using ESM is essentially letting the browser take over part of the job of a bundler.
Vite builds your project differently, depending on if you try to create a dev build or production build. During development, it serves your pre-bundled dependencies via esbuild
, which is significantly faster than other build tools and improves feedback loop speed. esbuild
is written in Go and pre-bundles dependencies 10-100x faster than JavaScript-based bundlers.
Have a look at esbuild home page to see how fast it is.
For production builds, hovewer, Vite still creates a bundle using Rollup, ensuring compatibility and performance, because esbuild
doesn’t currently have the same mature plugin ecosystem as Rollup does. Creators of Vite even consider switching production builds to esbuild
at some point in the future. But for the time being, Rollup is considered a good tradeoff between speed and compatibility.
Should you migrate to Vite?
Short answer - yes and no at the same time. The bigger your project and dependency list is, the harder it might be. Most common pitfalls are testing libraries, you might need to rewrite tests in other tools. Say, you had Cypress or Jest - you might need to move to something like Vitest, which is praised well, as far as I can tell.
Hey, what about browser compatibility? It’s not like it’s supported in every browser?
By default, Vite targets browsers which support the native ES Modules, native ESM dynamic import, and import.meta
:
- Chrome >=87
- Firefox >=78
- Safari >=14
- Edge >=88
But if you need polyfills, you can just use Rollup plugin (that’s the benefit!) and target any browser you want.
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import legacy from '@vitejs/plugin-legacy'; // <- this one
export default defineConfig({
plugins: [
legacy({
targets: ['defaults', 'not IE 11'], // <- here's the magic
}),
react(),
],
});
But don’t just take my word for it and let’s refer to stats.
State of JS 2022 really showed that Vite is here to stay, even though this competition is definitely fierce and we will hear more about Webpack competitors (I’m looking at you, Turbopack). Vite is just most adopted and ready to use at the current moment.
In the end, Vite is an opinionated tool that has some extremely performant defaults and can indeed be a good go-to solution instead of Webpack, especially if you start new project.
Recap on state of CRA and Vite
We have seen the much-anticipated release of React 18, which introduced new features and functionalities that will greatly enhance our development experience - Concurrency Mode, Suspense changes, support for Server Components and so on and so forth.
With it we got some new React docs! And they originally recommended CRA as a starting point. Friendly reminder:
This is significant because the learning experience with React has been, and in some ways still is, a mixed bag. A lot of the tutorials, guides, and courses available to learners are based on CRA, which has its own set of challenges and limitations if you want to grow your project to something bigger.
You might have noticed on the fact that I’ve been speaking about CRA in the past tense. And that is the catch.
Because React Core team has indeed removed CRA recommendation from the docs. But at the same time… CVA is nowhere to be seen?
And that’s the real elephant in the room, because… it’s somewhat hidden away. You might just skip it if you’re not actively looking for it.
Have a look at this dropdown. You have to scroll down really far just to see this:
If you’re still not convinced, or your app has unusual constraints not served well by these frameworks and you’d like to roll your own custom setup, we can’t stop you—go for it! Grab
react
andreact-dom
from npm, set up your custom build process with a bundler like Vite or Parcel, and add other tools as you need them for routing, static generation or server-side rendering, and more.
That’s why I want to draw your attention to this. CVA is a superb alternative to CRA, and it shouldn’t be overlooked.
This is particularly important because new React docs are indicating a new direction, giving us clues on “what’s next” for it. But they don’t answer on what should you do, if you want to build React apps as you did before. So if you’re still building single-page applications (SPAs), Vite or CVA should be your go-to tools as of today. CRA removal from the docs underscores the importance of considering alternatives to it, and CVA is certainly one of those. And I hope I got your interest.
If it’s so good, why is it not mentioned directly?
I think the main reason is that Vite is framework agnostic (isn’t React-exclusive) and doesn’t enable features that are in the new React agenda, unlike currently recommended way of starting new React app.
Because if you open React docs today and check, how to start a new React project, you’ll see at the very top that you should use “React-powered frameworks”. And the first of the bunch is something called Next.js! Which brings me to…
What is Next.js?
Next.js - is the full-stack meta-framework for React created by Vercel.
Okay, let’s get this meta-buzzword out of the way, that you might hear a lot this days.
What is meta-framework?
Let me share a mental model with you that I have regarding libraries, frameworks and meta-frameworks definitions.
Library
Library is a chunk of code I know I want to use whenever I feel like I need it.
It’s like a tool in my toolbox. I can use it whenever I want, but I don’t have to. It’s up to me to decide.
Framework
Framework, on the other hand, is a set of tools that I know I will use. We know that frameworks like React are some opinionated big chunks of code that provide us with a way to abstract from something. And most often than not there is one best way to achieve something. In case with React, we abstract from JS code and let React do some things for us like updating values, side-effects, hydration, DOM manipulations and all that. We can do all that stuff manually, using Browser APIs, but with React we don’t have to.
Think of it like having a plan to build a house, but you’re free to choose every part of it.
But, despite this, even React has some unopinionated stuff. It gives you way too much freedom in achieving same objective, say, fetching data from server (for ex. you may use Fetch API, you may use Axios, you may use GraphQL Client). Or routing. Because of that, React has this unique feeling - even if you start on different React projects (or joined already existing production-grade ones) - you will need some time to understand the codebase, because it achieves some results in a slightly different way.
Meta-framework
Now, the meta-framework is framework for frameworks. It fills those unopinionated gaps and may even provide alternative ways on doing same stuff. I will mention further what Next.js is capable of.
Think of it like a complete construction crew with a project manager and all the tools you need to build the house efficiently and effectively.
For that reason, Next.js is a meta-framework because it’s a framework on top of React. And React is, indeed, a framework. And Next.js does a lot of stuff behind the scenes so you don’t have to.
Next.js Features
- File-based Routing
- Diverse Rendering techniques
- Data Fetching
- Multiple Styling options
- SEO, Image, Font Optimizations
- TypeScript support
- and more!
Regarding App Router
Before I go full on some mentioned features I feel I should address, that Vercel, the company behind Next.js, recently had their ship week. And because Vercel probably loves Star Wars memes, new App Router was released on May 4th, enabling the usage of newest React advancements, that are not well documented yet (RSC).
And as much as I love cutting-edge tech, App Router is not mature enough to talk about it and might overwhelm you. For that reason I’ll touch on just Pages Router, that you’ll probably encounter much more often. If you want to know more about App Router - you can go seek knowledge in Next.js docs. I will definitely cover it in the future, be it my next talk (pun intended) or a blog post - or both.
Next.js Demo
So I covered most of the mentioned stuff above using a prepared demo. I will once again leave a link to it, so you can follow along (use README.md).
What about SPAs?
The main thing to know is that we’re not trying to strive away from SPAs. We’re trying to enable using different rendering modes when needed, hence it’s called hybrid rendering. And tools like Next.js enable us to do just that, that is THE reason it’s recommended now by React docs and not something like CRA or CVA - because both of them strive to do client-side rendering only. And React is striving towards RSC, which is a big bet that we’ll talk about in following years.
But why talk about Next.js?
I was living a bubble that CRA is not that popular and widely used anymore and Next.js is the best and popular thing out there, but…
According to Netlify blog post, most developers still use CRA in favor of Next.js to this day, despite everything I said up to this point.
Despite all the exciting features and improvements I’ve just outlined, it seems that Next.js is still lagging behind CRA in terms of popularity. This great technology that I’ve been raving about still has some catching up to do. So it’s the same as with Vite - I want you to take note of these great technologies and, if you’re willing to start your new project or to make a decision on existing one, I’d love you to consider this tech going forward.
Next.js… is an SPA
I think the reason for Next.js lagging behind is because people fail to grasp that Next in its default form is an SPA. When you use provided <Link />
component by Next.js, you basically emulate the same client-side routing behaviour as you would in SPA. And I don’t blame people for that, because Next.js is mostly known for other great stuff, thus is considered too advanced or hard to try.
You can learn more about this take here.
We’re approaching the destination and, as I promised, I need to refer back to Dan’s answer on what will happen to CRA? What is the future of React?
What’s next for CRA?
If you haven’t read Dan’s answer on your own, consider these 5 options.
What do you think React team would do?
- Create new framework?
- Deprecate CRA, maintain Vite template?
- Deprecate CRA, suggest React frameworks?
- Make CRA use single framework?
- Turn CRA in a launcher?
Take a moment to think through. What do you feel is the best thing to do?
The answer is
According to Dan, CRA will most likely be turned into a launcher. Which means, you’ll probably run a command, see the option for classic CRA, modern CRA (with Vite under the hood) and other official templates, which will be frequently revaluated by React team.
I imagine it something like this…
npx create-react-app my-app
What template would you like to use?
> Modern CRA
> Legacy CRA
> Framework template ✓
What framework would you like to use?
> Next.js ✓
> Gatsby
> Remix
Installing Next.js template... 69%
Meaning CRA is dead, but will be reborn as something new. Reincarnated, so to speak.
What’s next for React?
React will change a lot and you should be aware of it. The tech I have not touched on in this post is just not ready yet and is experimental, but it indeed will change a lot in the near future.
React Server Components (RSC) is one such topic worth of separate post in a future, but it’s so “not ready yet”. So much so even Dan Abramov acknowledges the frustration in uncertainty of where React is heading:
Just know, you are not alone. A lot of devs have expressed their concerns on where React is heading.
Final Thoughts
As we approach the end of our long journey today, I want to leave you with some thoughts. I talked a lot about the direction of React, about how the landscape is shifting beneath our feet. And, in many ways, this shift represents a new beginning.
The future of React is us
I recently watched keynote of Reactathon. And I want to share my biggest takeaway from it. Given these advancements, React is evolving, and the community plays a significant role in shaping its future. It seems more and more that React team is depending on us. We need to acknowledge the importance of community participation in discussions, asking questions, and helping to shape the server-first future of React. Now it’s true more than even. Whether you’re an experienced React developer or just starting out. Everyone in the React community has valuable experience to share. That’s why “The future of React is us”.
CRA is dead, long live CRA
Create React App, a tool some relied on and loved, is officially “dead”. But with every end, there’s a new beginning. It’s time for us to explore and elevate the next generation of solutions, and you are all part of this process.
We are just embarking on the exciting journey of React 18, and I want to extend an invitation to each and every one of you. Front-end developers, back-end developers, tech leads, join us on this ride, regardless of your background or experience level.
The future is bright
There’s a world of full-stack development waiting for you, thanks to the advent of React’s meta-frameworks. And the best part? You already have a head start. We are in an era of better bundle tools, of embracing meta-frameworks, and of constantly pushing the boundaries of what’s possible. Next.js, in particular, has shown us a glimpse of the future, and believe me when I say it: it just keeps on giving.
Now is the best time to build cool shit. Building projects, even side ones, you’ll learn more than you could imagine, and find sparks of inspiration and joy to this web dev craft along the way. I can vouch for it. It is THE reason I’m here. Learn React, try Next.js and Vite - you’ll love them. You can also try Astro and T3 Stack, I think they are cool.
Side-note. For T3 Stack I even translated docs to Russian with some folks, so you have less reasons to not check it out :)
Let’s learn React once again
Soon enough, it will be the time when we will have to learn React again. And, if you haven’t or it didn’t click for you with old docs, maybe, now is the best time. And I hope, more than anything, that you’re now with me on this journey.
Keep learning, keep building, and never stop exploring.
Thank you for your time. Let’s go out there and build amazing things.