What is Create-React-App and why does it exist?
Create-React-App (CRA) was a popular CLI tool to quickly create React-based web applications. Maintained by the React team at Facebook, it provides a set of preconfigured tools and dependencies that allowed developers to start building React applications without having to setup a complex build system.
CRA was released in 2016 when React tools were fragmented and not integrated. At this time, there was no clear path to start a React project from scratch. CRA solved this by combining several tools under a single package. Following a reasonable default config, there was now a clear way to start a fresh React project. This model became popular and today there is an entire category of tools working like this.
The goal of CRA was to provide the best way to start React projects for the majority of developers; supporting a set of features that worked together. Over time though the baseline of tools offered would change as the ecosystem evolved.
Problems with Create-React-App
As the years passed CRA has stagnated, and the community have been quick to point out alternatives that were faster and provided out-of-the-box support for popular tools they wanted to use. Currently there are only a few maintainers of the CRA repository, which currently has 1600 logged issues and over 400 pull requests. However there is a deeper problem with CRA than some missing features.
By design, CRA produces a purely client-side application, which has a rather inefficient load process:
- The browser requests the app which returns and empty HTML file with a script tag.
- Then browser then has to wait while for the React code as well as the entire application to download. This could be slow on low-bandwidth devices and the user does not see anything.
- Once the code is downloaded, the browser needs to run all of it. Which can be slow on underpowered devices.
- At last, the user can see something on the screen, but apps often load data from external sources.
- So the code sends a request, and the user waits for a response.
- Finally, the data is loaded and the React component re-renders and the user sees the result.
This is called a Network Waterfall, and is quite inefficient. However, it’s hard to do any better with React running purely on the client-side. Compare this to a server framework, which would start the data fetch immediately then generate the page with all the data, or during the build phase (in the case of SSG). In both cases the user would see some HTML while the data loads.
Since HTML is the cornerstone of the web, this raised questions, like: Why does a React app produce an empty HTML file? Why not take advantage of being able to load content quickly and then interactivity? Why wait until after all client-side code is finished loading to start a data lookup?
During its infancy, CRA only solved part of the problem when creating React web-apps; it provided a good developer experience, but didn’t impose enough structure to leverage the stronger sides of the web for a good user experience. Any truly efficient React app had to eject from the CRA model, which defeated its point. These user experience problems are not specific to CRA and are also exist in other templates. They are in fact inherit in any app that is purely client-side and has no SSR or SSG.
The Rise of React Frameworks
Nowadays the use of SSR/SSG is important if you want to build an entire app with React. The lack of this support in CRA is glaring, but it’s not the only place where CRA has fallen behind. Even sites that wouldn't benefit from SSR/SSG, likely suffer from network waterfalls, which is the performance problem for most client-side apps. Data fetching and code loading could be done in parallel, if only the web-app 'knew' how to start the fetch while the code is loading, but to do this apps would have to integrate data fetching with routing, which CRA doesn’t do.
This problem grows with every new feature or dependency, which could be mitigated with code splitting; and only render what is needed as its needed, however this is not an ultimate solution as routes will still suffer from network waterfalls, but on a smaller scale. To solve this well, an app would need to integrate data fetching with routing and bundling, which CRA doesn’t do. So you see, this isn't about a single missing feature; SSR, SSG, data fetching, bundling and routing are all interconnected.
React was very young when CRA was released and there was still a lot to figure out about how best to tackle these features in isolation, let alone the best way for them to work together. Integrating all these features yourself would be hard (to say the least). However tools like Next.js, Gatsby, and Remix have taken it further and integrated compilation with rendering, routing, and data fetching. This category of tools is called "frameworks" or "meta frameworks". These frameworks impose some opinions about structure, routing and data fetching that provide a better user experience that many developers find ergonomic.
Alternatives to Create-React-App
Using CRA is simple and great for beginners. With 3 commands, you can be up and running with a new application and not worry about the overwhelming config that is happening in the background. But as React become more popular, alternatives were introduced with newer tools.
1. Vite
Vite is a recently released, blazingly fast build tool. It's developer experience is great, and offers a wide range of plugins to extend is capability. Vite is the closest one-to-one replacement of CRA. Instead of Webpack, it uses Rollup under the hood to bundle you application into a single static source. If your application doesn’t require SSR or SSG, and is small or an SPA, Vite is a great solution.
Migration from CRA to Vite is quite straight-forward as they are both CSR frameworks. There are a number of articles that can help with this.
2. Nx
Nx is a smart, fast and extensible build system with first class monorepo support and powerful integrations.
Nx is a powerful toolkit that can help developers create scalable and high-quality applications using modern front-end and back-end frameworks. Focusing on monorepo-based development makes it an excellent choice for large and complex projects that requires efficient code organization and management.
Its benefits include improved organization for shared libraries and modules, faster development and testing by providing a suite of code generators to reduce manual setup and better scalability and performance by leveraging task caching as well as support for multiple front-end and back-end frameworks.
Migration from CRA is officially documented.
3. NextJS
Used by some of the world's largest companies, Next.js enables you to create full-stack Web applications.
NextJS is a production ready full-stack JavaScript framework, providing powerful features and tools for building SSR or static web applications with React. Its main advantage is its ability to handle SSR, improving performance and SEO. However it can be configured to handle SSG, CSR and ISR on a per-page basis.
NextJS is one of the most popular React frameworks, and includes a range of features including automatic code splitting, file based routing, optimized performance for static sites as well as an extensive plugin system. Suited to both simple static sites as well as complex dynamic web applications, NextJS provides tools to build any modern web application.
Migration from CRA to NextJS is officially documented.
4. Remix
Remix is also a production ready full-stack JavaScript framework. The competitor to NextJS, it offers a lot of similar features, however does not support SSG or ISR out of the box. It differs from NextJS in that while nested routing is in beta for NextJS, its fully stable in Remix (which probably has something to do with Remix being created by the same team that brought us React-Router :D). A negative is that while Remix supports SSR, it does not use React Server Components like NextJS does. Overall, Remix is a powerful and flexible web framework, allowing the creation of fast, scalable and maintainable web-apps using SSR.
Documentation for migrating from CRA to Remix is sparse.
5. Gatsby
Gatsby, while similar to NextJS and Remix, is a Static Site Generator that uses React and GraphQL to build fast and modern websites. Gatsby includes out-of-the-box support for SSG, preloading data, and optimizing performance, making it an excellent choice for static sites like blogs and documentation sites. Focusing on performance and SEO, Gatsby sites load faster, provided better user experience and boost search engine rankings. Gatsby also has a vast plugin library to customize your site and integrate it with their tools and services.
Migration from CRA to Gatsby is officially documented.
Conclusion
Deciding on a framework can depend on many factors, like:
- Project Requirements: What features and functionality do you need? Does the app need SSR, API routing, or integration with a CMS? What devices are you targeting?
- Scalability: Is you project small with limited traffic, or will it be large with heavy traffic?
- Development Team: Consider the skills and experience of your development team. Familiarity with one framework may save time, effort and improve productivity.
- Learning Curve: Account for the learning curve of a new framework, some are more beginner friendly than others.
Consider these factors so you can make an informed decision about which framework will work best for your project. Its important to research and evaluate each option carefully to ensure you choose the best framework for your project's needs.
Top comments (0)