Right now your project only exists while you are looking at it. You type npm run dev, a starts, and the site appears at http://localhost:3000. Close the laptop and it is gone. Nobody else could have reached it anyway.

Deploying is the work of changing that. The word covers two separate steps that beginners tend to run together, which is why the first attempt usually fails in a confusing way.

The idea

Deploying puts a copy of your project on a computer that is always on and has a public address, then starts it there. First a build turns your source files into the compressed, rearranged output a browser can actually load. Then a run step starts that output on a and keeps it running after you disconnect.

code
  YOUR LAPTOP                            A SERVER SOMEWHERE
  ------------                           --------------------

  src/  package.json
     |
     |  step 1: build
     |  npm run build
     v
  .next/   dist/  ------ upload ------>  /var/www/app/
                                              |
                                              |  step 2: run
                                              |  node server.js
                                              v
                                         listening on port 3000
                                              |
                                         https://yourapp.com

How it works

  • The build is a translation. Your TypeScript becomes JavaScript, twelve CSS files become one, images get resized, and anything unused gets dropped. The output folder (.next for Next.js, dist for Vite) is what gets shipped. Your src folder never goes to the server.
  • The run step is a process that has to survive. On a plain server, closing your SSH connection kills whatever you started, so something has to restart the process when it crashes or when the machine reboots. On Linux that job usually belongs to systemd. Managed platforms do it for you and never mention it.
  • Some sites skip the run step entirely. If every page can be generated at build time, the output is just files, and a can be served by anything. Sites with logins, databases or payments need a running process.
  • The dev server is a different program from the production one. It is slower, it shows you friendly error pages, and it tolerates mistakes that the real build rejects.

What to do

  1. Run npm run build on your own machine before you deploy anything. Most first deploys fail at the build, not at the server. A type error or an import with the wrong capitalisation will pass in dev and fail in the build, because macOS treats Button.tsx and button.tsx as the same file and Linux does not.
  2. Write down the exact Node version you are using (node --version) and set the same one on the host. Version drift between your machine and the server is the most common cause of a build that works in one place and fails in the other.
  3. Ask your AI assistant for the two commands separately. "What is the build command and what is the start command for this project?" Knowing those two strings is most of what deploying is.

Where it breaks

"It works on my machine" is almost always something your machine has that the server does not: a file that never got committed, a package you installed globally a month ago, a database running on localhost, or an environment variable sitting in a .env file that git ignores. The server starts from a clean checkout of your repository and nothing else, which is exactly what makes it a useful test and exactly what makes the first attempt painful.

The other trap is treating deployment as the last task. A project that has never been deployed has an unknown amount of work hiding in it. Deploy an empty page in week one, while the only thing that can be wrong is the deployment itself.