Node.js

Project Init – Express.js App Setup

Bootstrap a production-ready Express.js project from scratch: package setup, folder structure, server entry point, nodemon dev workflow, and environment configuration.

Init & Install: Run npm init -y to scaffold package.json, then install core dependencies and dev tools.
📄terminal
BASH
npm init -y

# Core dependencies
npm install express dotenv cors helmet morgan

# Dev dependencies
npm install --save-dev nodemon
Folder Structure: Organize code into routes/, controllers/, and middleware/ to keep concerns separated and the codebase scalable.
📄project-structure
TEXT
my-app/
├── src/
│   ├── controllers/
│   │   └── userController.js
│   ├── middleware/
│   │   └── authMiddleware.js
│   ├── routes/
│   │   └── userRoutes.js
│   └── config/
│       └── db.js
├── .env
├── .gitignore
├── package.json
└── server.js
Entry Point: server.js wires up middleware, routes, and starts listening. Keep it lean — delegate logic to route files.
📄server.js
JS
require('dotenv').config();
const express = require('express');
const cors    = require('cors');
const helmet  = require('helmet');
const morgan  = require('morgan');

const userRoutes = require('./src/routes/userRoutes');

const app  = express();
const PORT = process.env.PORT || 3000;

// ── Middleware ──────────────────────────────────────
app.use(helmet());
app.use(cors());
app.use(morgan('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// ── Routes ──────────────────────────────────────────
app.use('/api/users', userRoutes);

// ── 404 handler ─────────────────────────────────────
app.use((req, res) => {
  res.status(404).json({ message: 'Route not found' });
});

// ── Global error handler ─────────────────────────────
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(err.status || 500).json({ message: err.message || 'Server Error' });
});

app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Nodemon: Add dev and start scripts to package.json so npm run dev hot-reloads on file changes.
📄package.json
JSON
{
  "name": "my-app",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "start": "node server.js",
    "dev":   "nodemon server.js"
  },
  "dependencies": {
    "cors":    "^2.8.5",
    "dotenv":  "^16.0.0",
    "express": "^4.18.0",
    "helmet":  "^7.0.0",
    "morgan":  "^1.10.0"
  },
  "devDependencies": {
    "nodemon": "^3.0.0"
  }
}
Environment Variables: Use dotenv to load a .env file. Never commit secrets — add .env to .gitignore.
📄.env
ENV
PORT=3000
NODE_ENV=development

DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASS=secret
DB_NAME=myapp

JWT_SECRET=supersecretkey
JWT_EXPIRES_IN=7d
Route File: Define an Express Router in its own file and map HTTP verbs to controller functions.
📄src/routes/userRoutes.js
JS
const express    = require('express');
const router     = express.Router();
const userCtrl   = require('../controllers/userController');
const { protect } = require('../middleware/authMiddleware');

router.get('/',       protect, userCtrl.getAll);
router.get('/:id',    protect, userCtrl.getOne);
router.post('/',      userCtrl.create);
router.put('/:id',    protect, userCtrl.update);
router.delete('/:id', protect, userCtrl.remove);

module.exports = router;