How to set up a React project (the professional way)

Johannes KettmannPublished on 

When you start a new React app you might wonder how to set it up in a professional way. What tools should you use? What libraries do you need from the start?

Based on the most popular React tech stack this article will guide you through the setup of a new application using

  • Next.js
  • Typescript
  • ESLint
  • Prettier
  • styled-components
  • Cypress
  • Storybook

The video below shows how I set up the app for my upcoming Bootcamp for Self-Taught React Devs with exactly this tech stack. The screencast is nearly unedited to show the whole process and not only the polished outcome. If you're looking for a quick guide you can find all steps for the setup on this page.

Next.js & TypeScript

Next.js is the go-to React framework. It has a lot of neat features like server-side-rendering that are important for many professional apps. Many developers tend to use it for any new React project.

This command creates a new Next.js application using TypeScript. (Feel free to remove the --typescript option if you already have too much to learn.)

npx create-next-app@latest --typescript

You'll be prompted for a project name and the package manager of your choice. I simply went with npm.

Note: if you plan to host the project on GitHub you might want to rename the master branch to main with this command: git branch -m master main


The Next.js app is already set up with ESLint which is used to detect bugs by statically analyzing your code.

For my taste, the default rules that come with Next.js are not strict enough though. For example, unused variables don't cause an error. A standard set of rules found in the ESLint docs is eslint:recommended. We can extend it in the eslintrc.json config file.

"extends": [


Prettier is used to automatically format your code according to a standard. That makes your code more readable and saves you a lot of manual effort.

You can use a Prettier plugin for your IDE. I use VS Code and its Prettier extension with the following settings to auto-format when I save a file.

To integrate Prettier with ESLint you can use the eslint-config-prettier and add it to your eslintrc.json config. This way you don't get conflicts between Prettier and ESLint.

npm install --save-dev eslint-config-prettier
"extends": [

The Next.js app doesn’t use the Prettier format by default. Run npx prettier --write to format all files.


styled-components is a very popular library for writing custom CSS. Next.js doesn’t support it out of the box, but this official example repo shows us how to set it up. First, we install the library.

npm install styled-components

Then we add styledComponents: true to the compiler option in the next.config.js file.

const nextConfig = {
reactStrictMode: true,
compiler: {
styledComponents: true,

Additionally, we need to create the pages/_document.tsx file to avoid a "flash of unstyled content" on the initial page load according to the example repo.

import Document from "next/document";
import { ServerStyleSheet } from "styled-components";
import type { DocumentContext } from "next/document";
export default class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
const initialProps = await Document.getInitialProps(ctx);
return {
styles: (
} finally {

That's it. To use global styles or the ThemeProvider you need to edit the file pages/_app.tsx as shown here.


Cypress is a tool that’s commonly used to write end-to-end tests (meaning it tests the whole system from frontend to database just like a real user).

For the setup, the Next.js docs are again very helpful. First, we install Cypress.

npm install --save-dev cypress

Then we add "cypress": "cypress open" to the scripts section in our package.json file.

"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"cypress": "cypress open"

Finally, run npm run cypress to initialize the project. This creates a few folders and demo tests in your repository. Then the Cypress UI opens where you can run the demo tests.

When you open the test files you'll realize that ESLint complains that global functions like describe or it don't exist. To get rid of these errors we can install an ESLint plugin and adjust the eslintsrc.json config file.

npm install eslint-plugin-cypress --save-dev
"extends": [
"plugins": ["cypress"],
"env": {
"cypress/globals": true


Storybook is a tool widely used to document and visually test UI components. According to the docs we first need to initialize or project.

npx sb init

Then run Storybook. This will open a new browser tab where you can play around with some demo components.

npm run storybook
You don't feel "job-ready" yet?
Working on a full-scale production React app is so different from personal projects. Especially without professional experience.
Believe me! I've been there. That's why I created a program that exposes you to
  • a production-grade code base
  • realistic tasks & workflows
  • high-end tooling setup
  • professional designs.