Node Express Part4

by Kuligaposten 2026-02-16

A guide in Node Express backend.

Part 4: Production-Ready Full-Stack Setup

By the end of this guide, your full-stack app will be ready for deployment with clean structure, environment safety, and production-level considerations.


1. Environment Variables

Never hardcode secrets (like database URIs, API keys, or ports). Instead, use environment variables.

  • Create a .env file in your Express backend:
PORT=3000
MONGO_URI=mongodb+srv://<username>:<password>@cluster0.mongodb.net/mydatabase?retryWrites=true&w=majority
  • Install dotenv (if not already):
npm install dotenv
  • Load variables at the top of your index.js:
require("dotenv").config();

const PORT = process.env.PORT || 3000;
const MONGO_URI = process.env.MONGO_URI;
  • Make sure to add .env to .gitignore so secrets aren’t committed.

2. API Versioning

Version your API to avoid breaking changes in production:

app.use("/api/v1/users", usersRouter);

Later, if you upgrade your API:

app.use("/api/v2/users", newUsersRouter);

Clients using v1 won’t break.


3. Middleware Best Practices

Error handling middleware for better production logging:

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: "Something went wrong!" });
});

Security middleware:

npm install helmet morgan compression
const helmet = require("helmet");
const morgan = require("morgan");
const compression = require("compression");

app.use(helmet()); // Secures HTTP headers
app.use(morgan("combined")); // Logs requests
app.use(compression()); // Compress responses

4. Serve React in Production

Instead of running React on a separate dev server, build it and serve via Express:

  • In your React project:
npm run build

This generates a dist folder (Vite) or build folder (CRA).

  • In Express index.js:
const path = require("path");

app.use(express.static(path.join(__dirname, "../my-react-app/dist")));

app.get("*", (req, res) => {
  res.sendFile(path.join(__dirname, "../my-react-app/dist", "index.html"));
});

Now your React app is served directly by Express, on the same domain, avoiding CORS issues.


5. MongoDB Atlas & Connection Pooling

  • Use MongoDB Atlas for cloud hosting. Set up IP whitelist and user credentials.
  • Use connection options for production:
mongoose.connect(MONGO_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  maxPoolSize: 50, // connection pool
  serverSelectionTimeoutMS: 5000,
});

6. Deployment Options

Backend

  • Render: Free tier supports Node.js apps.
  • Railway: Very simple setup, great for hobby projects.
  • Heroku: Classic option.
  • DigitalOcean App Platform: Scalable for production.

Frontend

  • Vercel: Excellent for React + Vite/CRA.
  • Netlify: Also excellent, can handle React builds.
  • Serving via Express: Already covered above.

7. Logging & Monitoring

  • Use winston or pino for logging:
npm install winston
  • Example setup:
const winston = require("winston");

const logger = winston.createLogger({
  level: "info",
  transports: [
    new winston.transports.File({ filename: "error.log", level: "error" }),
    new winston.transports.File({ filename: "combined.log" }),
  ],
});

module.exports = logger;
  • In production, consider PM2 for process management:
npm install pm2 -g
pm2 start index.js --name my-app
pm2 logs

8. Optional: Rate Limiting & Security

  • Prevent abuse with rate limiting:
npm install express-rate-limit
const rateLimit = require("express-rate-limit");

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP
});

app.use(limiter);
  • Consider helmet (already added) and CSP headers for extra security.

9. Recommended Project Structure for Production

backend/
├── models/
├── routes/
├── middleware/
├── db.js
├── index.js
├── package.json
└── .env

frontend/
├── src/
├── public/
├── package.json
└── vite.config.js (or CRA)
  • Keep frontend and backend in separate folders during development.
  • For deployment, you can either:
    • Serve React via Express (single server), or
    • Deploy frontend and backend separately and use environment variables for the API URL.

Conclusion

Now your full-stack app is production-ready:

  • Express + MongoDB backend with security and logging
  • React frontend, built and served efficiently
  • Environment variables for secrets
  • API versioning for maintainability
  • Deployment strategy and monitoring tips

With this setup, your app can scale safely, handle multiple users, and be deployed to the cloud efficiently.

Back to Home