React has been around for a while. Since then, a well-rounded yet overwhelming ecosystem of libraries evolved around the component driven library. Developers coming from other programming languages or libraries/frameworks often have a hard time figuring out all the libraries for creating web applications with React.
At its core, React enables one to create component-driven user interfaces with function components. It comes with a couple of built-in solutions though, for instance, React Hooks for local state, side-effects, and performance optimizations. But after all, you are only dealing with functions (components and hooks) to create a UI here.
The following article will give you guidance on how to choose libraries for building a React application.
Table of Contents
- How to create a React project
- Package Manager for React
- React State Management
- React Data Fetching
- Routing with React Router
- CSS Styling in React
- React UI Libraries
- React Animation Libraries
- Visualization and Chart Libraries in React
- Form Libraries in React
- React Type Checking
- React Code Structure: Style and Format
- React Authentication
- React Hosting
- Testing in React
- React and Immutable Data Structures
- React Internationalization
- Rich Text Editor in React
- Payments in React
- Time in React
- React Desktop Applications
- File Upload in React
- Mobile Development with React
- React VR/AR
- Design Prototyping for React
- React Component Documentation
How to create a React project
There is this unknown for every React beginner on how to set up a React project when joining the React world. There are many frameworks to choose from. The most popular choice in the React community is Vite which allows you to create projects with various library (e.g. React) + opt-in TypeScript combinations. It comes with incredible performance.
If you are already familiar with React, you can choose one of its most popular (meta) frameworks as alternative: Next.js which builds up on top of React, hence you should already be familiar with React's fundamentals. Another popular yet newer framework in this arena is Remix.
While Next.js has been initially used for server-side rendering (web applications), it can also be used for static site generation (e.g. websites). However, if you are looking for a framework with the best performance in mind for static content, you need to check out Astro which is framework agnostic and therefore can be used with React.
If you just want to understand how tools like Vite work under the hood, try to set up a React project yourself. You will start with a bare bones HTML with JavaScript project and add React with its supportive tools (e.g. Webpack, Babel) yourself. It's not something you will have to deal with in your day to day work, but it's a great learning experience to get to know the underlying tooling.
Recommendations:
- Vite for client-side React applications
- Next.js server-side rendered React applications
- Astro for static-side generated React applications
- optional learning experience: create a React project
Package Manager for React
The default and most widely used package manager in the JavaScript ecosystem (and therefore React) is npm (which comes with a Node.js installation). When installing dependencies (read: libraries) in a React application, you will usually use it. However, for the last years yarn has been a successful alternative. Last but not least, pnpm is the newest kid on the block which comes with a great performance boost.
If you happen to create multiple React applications which depend on each other or which share a common set of custom UI components, you may want to check out the concept of a monorepo. All previously mentioned package managers allow you to create monorepos by using their in-house workspaces feature, however, I had the best developer experience using yarn/pnpm. In combination with monorepo pipeline tools such as Turborepo the monorepo experience becomes perfect.
Recommendations:
- choose one package manager and stick to it
- default and most widely used -> npm
- if monorepo, check out Turborepo
React State Management
React comes with two built-in hooks to manage local state: useState and useReducer. If state needs to be managed globally, one can opt-in React's built-in useContext Hook to tunnel props from top-level components to components below them without using props and therefore avoiding the problem of props drilling.
All three React hooks enable developers to implement powerful state management in React which is either co-located in components by using React's useState/useReducer Hooks or globally managed by combining them with React's useContext Hook.
If you find yourself using React's Context too often for shared/global state, you should definitely check out Redux as the most popular state management library out there. It allows you to manage global application state which can be read and modified by any React component that is connected to its global store.
If you happen to use Redux, you should definitely check out Redux Toolkit as well. It improves the developer experience of using Redux tremendously by being a great API on top of Redux's core.
As alternatives, if you like the general idea of a global store but do not like how Redux approaches it, check out other popular local state management solutions such as Zustand, Recoil, XState, or Jotai.
Recommendations:
- useState/useReducer for co-located or shared state
- opt-in useContext for enabling little global state
- optional learning experience: learn how to combine useState/useReducer with useContext
- Redux (or an alternative) for lots of global state
React Data Fetching
React's built-in hooks are great for UI state, but when it comes to state management of remote data (and therefore data fetching), I would recommend using a dedicated data fetching library such as TanStack Query (formerly React Query). While TanStack Query itself is not seen as a state management library, because it is primarily used to fetch your remote data from APIs, it takes care of all the state management (e.g. caching, optimistic updates) of this remote data for you.
TanStack Query was designed for consuming REST APIs. However, these days it supports GraphQL too. But if you are looking for a dedicated GraphQL library for your React frontend, check out either Apollo Client (popular), urql (lightweight), or Relay (by Facebook).
If you are already using Redux and want to add data fetching with integrated state management in Redux, instead of adding TanStack Query, you may want to check out RTK Query which integrates data fetching neatly into Redux.
Last but not least, check out tRPC for end-to-end type typesafe APIs if you are in control of your TypeScript written backend.
Recommendations:
- TanStack Query (REST APIs, GraphQL APIs)
- with axios as fetching library
- Apollo Client (GraphQL APIs)
- optional learning experience: learn how TanStack Query works under the hood
Routing with React Router
If you are using a React framework like Next.js, routing is already taken care of for you. However, if you are using React without a framework and only for client-side rendering (e.g. Vite without SSR), the most powerful and popular routing library out there is React Router. A new alternative with full TypeScript support in mind is TanStack Router.
If you are using client-side routing in React with React Router, it's not much work introducing code splitting on a route level. If you happen to introduce this kind of optimization, you could substitute React.lazy()
with @loadable/component which gives you a better UX and more options.
Before you introduce a router in your React project, when you are just about to learn React, you can give React's conditional rendering a shot first. It is not a replacement for routing, but in small applications, it is often used to exchange components that way.
Recommendations:
- React Router
- fairly new, but check out TanStack Router if you like TypeScript and TanStack Query
CSS Styling in React
There are many options and even more opinions about styling/CSS in React out there, so putting everything in one section here does not suffice. If you want to get deeper into this topic and get to know all the options, check out the following guide.
But let's give you a brief overview. As a React beginner, it is just fine to start with inline styles and bare bones CSS by using a style object in JSX:
const Headline = ({ title }) =><h1 style={{ color: 'blue' }}>{title}</h1>
Whereas inline style can be used to add style dynamically with JavaScript in React's JSX, an external CSS file can hold all the remaining style for your React application:
import './Headline.css';const Headline = ({ title }) =><h1 className="headline" style={{ color: 'blue' }}>{title}</h1>
Once your application grows, there are many other styling options though. First, I would recommend you to have a look into CSS Modules as one of many CSS-in-CSS solutions. CSS Modules are supported by Vite and give you a way to encapsulate your CSS into component scoped modules. This way, it doesn't leak accidentally into the styling of other React components. Whereas some parts of your application can still share style, other parts don't have to get access to it. In React, CSS Modules are most often co-located CSS files to your React component files:
import styles from './style.module.css';const Headline = ({ title }) =><h1 className={styles.headline}>{title}</h1>
Second, I want to recommend you so-called Styled Components as one of many CSS-in-JS solutions for React. This approach is brought to you by a library called styled-components (or alternatives such as emotion which co-locates styling with JavaScript next to your React components in your component's JavaScript file or a co-located file:
import styled from 'styled-components';const BlueHeadline = styled.h1`color: blue;`;const Headline = ({ title }) =><BlueHeadline>{title}</BlueHeadline>
And third, I want to recommend Tailwind CSS as the most popular Utility-First-CSS solution. It comes with pre-defined CSS classes that you can use without defining them yourself. This makes you more efficient as a developer and streamlines the design system of your React application, but comes with the tradeoff of getting to know all the classes and verbose inlining of many CSS classes:
const Headline = ({ title }) =><h1 className="text-blue-700">{title}</h1>
Whether you choose CSS-in-CSS, CSS-in-JS, or Utility-First-CSS is up to you. All strategies scale well for larger React applications. One last hint: If you want to apply a className conditionally in React, use a utility like clsx.
Recommendations:
- CSS-in-CSS with CSS Modules
- Utility-First-CSS with Tailwind CSS
- CSS-in-JS with Styled Components (most popular)
- alternatives: Emotion
- optional: clsx for conditional CSS classes
React UI Libraries
As a beginner, it is a great and recommended learning experience to build reusable components from scratch. Whether it is a dropdown, a select, a radio button, or a checkbox, you should know how to create these UI components yourself eventually.
However, if you don't have the resources to come up with all the components yourself at your company, you want to use a UI library which gives you access to lots of pre-built components which share the same design system. All of the following UI libraries come with essential components like Buttons, Dropdowns, Dialogs and Lists:
- Material UI (by MUI) (most popular)
- Mantine UI (most recommended)
- Chakra UI (most recommended)
- Radix (unstyled design system)
- Tailwind
- Headless UI
- Daisy UI
- Tailwind UI (not free)
- Ant Design
- Semantic UI
- React Bootstrap
- Reactstrap
- NextUI
- Primer
Even though all of these UI libraries come with lots in-house components, they cannot make each component as powerful as libraries which focus only on one UI component. For example, react-table-library allows you to create powerful table components in React while also offering you themes (e.g. Material UI) for blending nicely into popular UI component libraries.
React Animation Libraries
Any animation in a web application starts with CSS. Eventually you will notice that CSS animations aren't enough for your needs. Usually developers check out React Transition Group then, which gives them the possibility to perform animations with React components. Other well known animation libraries for React are:
- Framer Motion (most recommended)
- react-spring (also often recommended)
- react-motion
- react-move
- Animated (React Native)
Visualization and Chart Libraries in React
If you really want to build charts from the ground up yourself, there is no way around D3. It's a low level visualization library that gives you everything you need to create amazing charts. However, learning D3 is a whole other adventure, thus many developers just pick a React charting library which does everything for them in exchange for flexibility. These are some popular solutions:
- Recommendation: Recharts (great composability) (comes with customization due to opt-in composability)
- visx (leaning more towards low-level D3 than high-level abstraction, therefore steeper learning curve)
- off the shelf charts, more difficult to customize
Form Libraries in React
The most popular library for forms in React is React Hook Form. It comes with everything needed from validation (most popular integrations is zod) over submission to form state management. As alternative there are Formikand React Final Form. If you are already using a React UI library, you could also check out their built-in form solution.
Recommendations:
- React Hook Form
- with zod integration for validation
- If you use a UI library, check whether built-in form supports all your requirements
- React Hook Form comes with a clean API for a UI library integration
React Type Checking
React comes with an in-house type checking called PropTypes. By using PropTypes, you are able to define the props for your React components. Whenever a prop with a wrong type is passed to the component, you will get an error message when running the application:
import PropTypes from 'prop-types';const List = ({ list }) =><div>{list.map(item => <div key={item.id}>{item.title}</div>)}</div>List.propTypes = {list: PropTypes.array.isRequired,};
However, PropTypes are not included in the React core library anymore. Over the last years, PropTypes got less popular in favor of TypeScript:
type Item = {id: string;title: string;};type ListProps = {list: Item[];};const List: React.FC<ListProps> = ({ list }) =><div>{list.map(item => <div key={item.id}>{item.title}</div>)}</div>
If you truly want to embrace types in React, TypeScript is the way to go these days. If you want to go beyond TypeScript for typed form validation, API input/output validation and more, check out Zod.
Recommendations:
- If typed JavaScript is wanted, use TypeScript
React Code Structure: Style and Format
Essentially there are two ways to follow for a common sense for code structure:
If you want to embrace a unified and common sense code style, use ESLint in your React project. A linter such as ESLint enforces a particular code style in your React project. For example, you can make it a requirement with ESLint to follow a popular styleguide (e.g. Airbnb Style Guide). Afterward, integrate ESLint with your IDE/editor and it will point you to every mistake.
If you want to embrace a unified code format, use Prettier in your React project. It is an opinionated code formatter with only a handful of opt-in configurations. You can integrate it in your editor or IDE so that it formats your code every time you save a file. Prettier doesn't replace ESLint though, but it integrates nicely with it.
Recommendations:
- ESLint + Prettier
React Authentication
In a React application, you may want to introduce authentication with functionalities such as sign up, sign in, and sign out. Other features like password reset and password change features are often needed as well. These features go far beyond React, because a backend application manages these things for you.
The best learning experience would be implementing a backend application with authentication (e.g. GraphQL backend) yourself. However, since authentication comes with lots of security risks and nitty gritty details not everyone knows about, I advice to use one of many authentication/backend-as-a-service solutions that are out there:
Recommendations:
- choose an authentication service or BaaS (e.g. Firebase/Supabase)
- optional learning experience: Custom Backend
React Hosting
You can deploy and host a React application like any other web application. If you want to have full control, choose something like Digital Ocean. If you want to have someone taking care of everything, Netlify or Vercel (especially for Next.js) are popular solutions. If you are already using a third-party backend as a service like Firebase/Supabase, you can check whether they offer hosting as well. Other popular hosting providers are Render, Fly.io, or Railway.
Testing in React
If you want to get a deep dive about testing in React, read this: How to test components in React. Here comes the gist: The backbone of testing a React application is a test framework like Jest. It gives you test runner, assertion library and spying/mocking/stubbing functionalities. Everything that's needed from a comprehensive test framework. If you are a fan of Vite, you should check out Vitest as viable Jest alternative thoguh.
At the minimum, you can render React components in your testing framework with react-test-renderer. This is already sufficient to perform so-called Snapshot Tests with Jest or Vitest. A snapshot test works the following way: Once you run your tests, a snapshot of your rendered DOM elements of the React component is created. When you run your tests again at some point in time, another snapshot is created which is used as diff for the previous snapshot. If the diff is not identical, the test framework will complain and you either have to accept the snapshot or change the implementation of your component.
Eventually you will find yourself using the popular React Testing Library (RTL) -- which is used within your testing framework's environment -- for a more elaborate testing library for React. RTL makes it possible to render your components and to simulate events on HTML elements. Afterward, your test framework (e.g. Jest/Vitest) is used for the assertions on the DOM nodes.
If you are looking for a testing tool for React end-to-end (E2E) tests, Playwright and Cypress are the most popular choices.
Recommendations:
- Unit/Integration: Jest/Vitest + React Testing Library (most popular)
- Snapshot Tests: Jest/Vitest
- E2E Tests: Playwright or Cypress
React and Immutable Data Structures
Vanilla JavaScript gives you plenty of built-in tools to handle data structures as if they are immutable. However, if you and your team feel the need to enforce immutable data structures, one of the most popular choices is Immer. Personally I don't use it, because JavaScript can be used for managing immutable data structures, but any time someone asks about immutability in JS, someone will recommend it.
React Internationalization
When it comes to internationalization i18n for your React application, you need to think not only about translations, but also about pluralizations, formattings for dates and currencies, and a handful of other things. These are the most popular libraries for dealing with it:
Rich Text Editor in React
When it comes to Rich Text Editors in React, I can only think of the following, because I haven't used any others in React:
Payments in React
Like in any other web application, the most common payment providers are Stripe and PayPal. Both can be neatly integrated into React. This is a working Stripe Checkout with React integration.
Time in React
JavaScript itself got pretty awesome dealing with dates and times over the recent years. So there is no real need to use a library for dealing with them. However, if your React application deals heavily with dates, times, and timezones, you could introduce a library which manages these things for you. These are your options:
React Desktop Applications
Electron is still the go to framework for cross-platform desktop applications. However, there exist alternatives such as:
- Tauri (great alternative, very popular)
- Neutralino.js
- NW.js
File Upload in React
Mobile Development with React
The go-to solution for bringing React from the web to mobile is still React Native. If you want to help a framework for creating React Native applications, check out Expo.
React VR/AR
It's possible to dive into virtual reality or augmented reality with React. To be honest, I haven't used any of these libraries, but they are the ones I know from the top of my head when it comes to AR/VR in React:
- react-three-fiber (popular 3d library, however, I have seen VR examples too)
- react-360
- aframe-react
Design Prototyping for React
If you are coming from a UI/UX background, you may want to use a tool for fast prototyping for new React components, layouts, or UI/UX concepts. I used Sketch in the past, but switched to Figma. Zeplin is another alternative. For rough yet lightweight sketches, I like to use Excalidraw. If you are looking for interactive UI/UX designs, check out InVision.
React Component Documentation
If you are in charge of writing the documentation for your components, there are various neat React documentation tools out there. I have used Storybook in many projects and can only recommend, but I have heard good things about these other solutions too:
After all, the React ecosystem can be seen as a framework for React, but it stays flexible with React at its core. It is a flexible framework where you can make your own well-informed decisions about which libraries you want to opt-in. You can start small and add only libraries to solve specific problems. In contrast, if React is all you need, you can stay lightweight by using only the library.