So you just generated a new cool side project and now you are wondering how one changes the default port in a create-react-app project. After all, we have other ports available, right? And there could be a case that 3000 port is already taken. But how can you do that? There are several ways to do that, so let’s check the basic ones.

Using package.json#

One way is to go to your package.json file and change your port through your scripts options, in this case, we are adding PORT=3001 to denote that we want our app to run in port 3001

"scripts": {
  "start": "PORT=3001 react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject"
},

Using the command line#

In certain scenarios, you may find it necessary to specify the port directly via the command line when executing your run command. You could do that by typing in your terminal

PORT=3001 npm start

Keep in mind that if you have a port defined on your package.json and you try adding it inline through the terminal, your package.json port setting will override any port passed through the terminal.

Using .env file#

In case you are working on a more complex project or a project that you will be deploying for the world to see your awesome work, you’ll need to set the port to a dynamic value. Why is that? Because the system that will handle your deployment will also be handling the ports.

In this case, you just need to tell your app, where to find the port’s value that will be used, when deployed.

Let’s start by creating a file called .env. Type in your terminal

touch .env

Now open your .env file and type

PORT=3001

According to the advanced configuration documentation, of Create-React-App, the app’s listening port is determined by reading the value of PORT from the .env file by default.

As a result, our application will utilize the PORT value specified in the .env file to run, so there is no need to make any more changes to our code.

If you’re curious about the order of precedence in case someone adds a port to every possible option, I’ve conducted experiments that reveal the following respected order.

  • package.json
  • command line
  • .env file

Before you go further: Create React App is deprecated ⚠️#

If you’re reading this while starting something brand new, you should know this first, because it changes the answer.

On February 14, 2025 the React team deprecated Create React App. In their words: “Today, we’re deprecating Create React App for new apps, and encouraging existing apps to migrate to a framework, or to migrate to a build tool like Vite, Parcel, or RSBuild.”

Their recommendations are Next.js, React Router or Expo if you want a framework, and Vite, Parcel or Rsbuild if you just want a build tool. CRA itself keeps working — it’s in maintenance mode and a version was published that works with React 19 — so nothing you already built is going to stop running tomorrow. But npx create-react-app my-app is no longer the thing to type on a Monday morning.

Everything above still applies to your existing project — as does our guide to adding Sass to a Create React App project, which is in exactly the same boat. If you’re starting fresh, here’s the same job in Vite.

Changing the port in Vite 🚀#

Vite’s dev server defaults to 5173, not 3000, so the first thing to know is that the number in your bookmark bar is going to look different.

The quickest way is on the command line:

npm run dev -- --port 3001

(The extra -- is npm’s way of saying “everything after this belongs to the script, not to npm”.)

To make it stick, put it in vite.config.js:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  server: {
    port: 3001,
    strictPort: true,
  },
})

strictPort is the option worth knowing about. By default, if 3001 is busy Vite quietly moves to the next free port and carries on — friendly, until an OAuth callback or a CORS allowlist is pinned to a specific port and you spend twenty minutes debugging a redirect. With strictPort: true, Vite exits instead of moving, which is what you want the moment anything else depends on that number.

The trap when you migrate from CRA#

PORT=3001 in a .env file does nothing in Vite. That’s the single most common surprise coming from CRA, and it doesn’t error — the server just starts on 5173 and you assume the file isn’t being read at all.

Two different things are going on. CRA treats PORT as configuration for its dev server. Vite takes its port from server.port in the config file or the --port flag, and it only exposes environment variables to your app if they start with VITE_. So .env is still useful in Vite — for API keys and endpoints, as covered in our guide to environment variables with dotenv — just not for this.

“Something is already running on port 3000” 😅#

Sooner or later you get this instead of a running app. Usually it’s an earlier dev server that never actually died — you closed the terminal tab, the process didn’t get the message.

Find out who has it:

lsof -nP -i :3000

You’ll get a line naming the command and a PID. If it’s a stray node, end it:

kill 84128

Use the real PID from the previous command, and try kill on its own before reaching for kill -9 — the polite version lets the process clean up after itself.

One macOS-specific trap while you’re here: don’t move your app to port 5000. On a modern Mac, AirPlay Receiver is already listening there — and on 7000 — under the ControlCenter process. You can see it for yourself with lsof -nP -i :5000. You can turn AirPlay Receiver off in System Settings, but picking a different port is a lot less disruptive. 3001, 4000 and 8080 are all quiet.

Frequently asked questions#

What is the default port for a React app?#

3000 for Create React App, and 5173 for Vite. Neither number is special — they’re just what the tool picked, and both are easy to change.

Why does my React app still open on port 3000 after I changed it?#

Almost always one of three things: another config is overriding you (in CRA, the PORT set inside package.json wins over the one you typed in the terminal), you edited .env in a Vite project where it has no effect, or the dev server was never restarted. Port changes are read at startup — stop the server and start it again.

How do I run two React apps at the same time?#

Give each one its own port and run them in separate terminal tabs. This is the usual reason people go looking for this setting at all: an API on 3000 and a frontend on 3001, talking to each other.

Can I use a port below 1024?#

Not without sudo, and you don’t want to. Ports below 1024 are privileged on macOS and Linux, which is why nobody runs a dev server on port 80. Stay above 1024 and let a proxy handle port 80 in production.

Don’t forget to have fun with your new project!! You got this! 😎

Keep reading#