Back to Blog
Lesson 39 of the Node.js: Build Your First Server & CLI course
Node.jsAugust 27, 20264 min read

Deployment Preparation: Setting Up Node.js for Production

Learn how to prepare your Node.js application for deployment. Master environment flags, dependency optimization, and build scripts to ensure a stable launch.

Node.jsdeploymentproductionnpmbackend
Close-up image of tactical gear and pouches mounted on a green vest.

Previously in this course, we covered Security Basics for APIs to protect our endpoints from common vulnerabilities. Now that our API is secured, we need to shift our focus to the "last mile": preparing our codebase to run reliably on a live server.

Deploying an application is more than just pushing code to a server. It involves transforming your "development" project—which is optimized for your local workflow—into a "production" artifact that is optimized for performance, security, and reliability.

The Role of NODE_ENV in Production

The most important configuration step in any Node.js deployment is setting the NODE_ENV environment variable to production. Many libraries, including Express.js, check this variable to toggle performance-heavy features.

When NODE_ENV is set to development (the default), frameworks often enable verbose logging, detailed error stack traces, and "watch" modes. In production, these behaviors are disabled to improve speed and prevent sensitive system information from leaking to end users.

You can verify your current environment using process.env.NODE_ENV in your server entry point:

JAVASCRIPT
// index.js
if (process.env.NODE_ENV === CE9178">'production') {
  console.log(CE9178">'Running in production mode');
} else {
  console.log(CE9178">'Running in development mode');
}

Verifying Production Dependencies

Focused view of a computer screen displaying code and debug information.

In Managing Dependencies, we learned the difference between dependencies and devDependencies. When you deploy, you want to ensure your production server only installs the packages required to run the code, not the tools used to build or test it.

Tools like nodemon, jest, or eslint are unnecessary in production and can even introduce security risks if they contain vulnerabilities. To install only production-ready packages, use the following command:

Bash
npm install --omit=dev

This command skips everything listed under devDependencies in your package.json. If you are using a CI/CD pipeline, this is the standard command to run during the build phase.

Optimizing Build and Startup Scripts

Your package.json file serves as the manifest for your deployment. To make deployment consistent, move your startup logic into specific scripts. Avoid relying on global tools like nodemon in your production start command.

Update your package.json to include a clean start script:

JSON
{
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js"
  }
}

By explicitly using node index.js for the start command, you ensure your production environment isn't trying to run development tools. If your project requires a build step (like transpiling TypeScript or bundling assets), add a build script and ensure it runs before the start command.

Hands-on Exercise: Preparing the Project

To prepare your current REST API project for its upcoming deployment, follow these steps:

  1. Clean your manifest: Open your package.json and ensure all test and build tools are correctly moved to devDependencies.
  2. Standardize the entry point: Ensure your start script is set to node [your-entry-file].js.
  3. Simulate a production install: Run npm install --omit=dev in your terminal. Observe the node_modules folder; you should notice that dev-specific packages are removed.
  4. Test the production mode: Run your server with the variable set: NODE_ENV=production node index.js. Confirm that your application starts without any development-only logs.

Common Pitfalls

Close-up of a triangular warning sign indicating a slippery surface, fixed to a wooden post.

  • Committing Secrets: Never include your .env file in version control. Use a .gitignore file to exclude it, and use your hosting provider’s dashboard to inject environment variables at runtime.
  • Assuming Dev Tools are Available: Never use nodemon or ts-node in your production start script. They are designed for developer ergonomics, not production stability.
  • Ignoring Warnings: If you see warnings during npm install, address them. A production build should be clean and predictable.

FAQ

Q: Should I set NODE_ENV in my code? A: No. Always set it via your environment or command line (e.g., NODE_ENV=production node app.js). Hardcoding it limits your ability to change environments without editing the source code.

Q: How do I handle environment variables in production? A: Use the same dotenv strategy we discussed in Environment Variables, but ensure the actual values are injected by your hosting provider (like Render or Heroku) rather than a local file.

Q: Does npm install --omit=dev delete my devDependencies? A: It tells npm not to install them. If they are already installed, they will remain, but the package-lock.json will be updated to reflect a production-only dependency tree.

Recap

Team members presenting a project in a modern office setting with a focus on collaboration.

Preparing for production requires shifting from a "convenience" mindset to a "stability" mindset. By setting NODE_ENV=production, pruning your node_modules with --omit=dev, and using explicit node commands, you minimize attack surfaces and maximize performance.

Up next: We will take this prepared code and push it to the cloud in Deploying to Render.

Similar Posts