Skip to content

Instantly share code, notes, and snippets.

@BunHouth
Last active February 6, 2025 09:18
Show Gist options
  • Save BunHouth/55ac9f0ef99db637b30c167bdbcc098f to your computer and use it in GitHub Desktop.
Save BunHouth/55ac9f0ef99db637b30c167bdbcc098f to your computer and use it in GitHub Desktop.

πŸ— ** Node.js Express Project Structure**

/project-root
│── /src
β”‚   β”œβ”€β”€ /config           # Configuration files (DB, env, etc.)
β”‚   β”‚   β”œβ”€β”€ db.config.js
β”‚   β”‚   β”œβ”€β”€ env.config.js
β”‚   β”‚   β”œβ”€β”€ logger.config.js
β”‚   β”œβ”€β”€ /loaders          # Application bootstrapping (DB, Express, etc.)
β”‚   β”‚   β”œβ”€β”€ express.js
β”‚   β”‚   β”œβ”€β”€ database.js
β”‚   β”‚   β”œβ”€β”€ security.js
β”‚   β”‚   β”œβ”€β”€ routes.js
β”‚   β”œβ”€β”€ /models
β”‚   β”‚   β”œβ”€β”€ users.ts
β”‚   β”œβ”€β”€ /modules          # Feature-based modular services
β”‚   β”‚   β”œβ”€β”€ /auth
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.controller.js
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.service.js
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.routes.js
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.middleware.js
β”‚   β”‚   β”œβ”€β”€ /user
β”‚   β”‚   β”‚   β”œβ”€β”€ user.controller.js
β”‚   β”‚   β”‚   β”œβ”€β”€ user.service.js
β”‚   β”‚   β”‚   β”œβ”€β”€ user.routes.js
β”‚   β”‚   β”‚   β”œβ”€β”€ user.middleware.js
β”‚   β”‚   β”œβ”€β”€ /order
β”‚   β”‚   β”‚   β”œβ”€β”€ order.controller.js
β”‚   β”‚   β”‚   β”œβ”€β”€ order.service.js
β”‚   β”‚   β”‚   β”œβ”€β”€ order.routes.js
β”‚   β”‚   β”‚   β”œβ”€β”€ order.middleware.js
β”‚   β”œβ”€β”€ /middlewares      # Global middlewares
β”‚   β”‚   β”œβ”€β”€ auth.middleware.js
β”‚   β”‚   β”œβ”€β”€ error.middleware.js
β”‚   β”‚   β”œβ”€β”€ validation.middleware.js
β”‚   β”œβ”€β”€ /shared           # Reusable utilities/helpers
β”‚   β”‚   β”œβ”€β”€ jwt.helper.js
β”‚   β”‚   β”œβ”€β”€ logger.helper.js
β”‚   β”‚   β”œβ”€β”€ apiResponse.js
β”‚   β”œβ”€β”€ /database         # Database connections and migrations
β”‚   β”‚   β”œβ”€β”€ migrations/
β”‚   β”‚   β”œβ”€β”€ seeders/
β”‚   β”‚   β”œβ”€β”€ connection.js
β”‚   β”œβ”€β”€ /tests            # Unit & integration tests
β”‚   β”‚   β”œβ”€β”€ auth.test.js
β”‚   β”‚   β”œβ”€β”€ user.test.js
β”‚   β”œβ”€β”€ app.js            # App initialization
β”‚   β”œβ”€β”€ server.js         # Server entry point
│── /public               # Static files
│── /views                # Templating engine views (if applicable)
│── .env                  # Environment variables
│── .gitignore            # Git ignore file
│── package.json          # Project metadata & dependencies
│── README.md             # Documentation

πŸ”₯ Why This Structure?

This architecture mimics a framework and allows scalability like a full-fledged system.

πŸ— Key Concepts

  1. /config β†’ Centralized configuration files.
  2. /loaders β†’ Handles Express, database, security, etc., ensuring modular startup.
  3. /modules (Feature-Based Structure)
    • Each module (Auth, User, Order) is self-contained.
    • Contains:
      • controller.js β†’ Handles HTTP requests.
      • service.js β†’ Business logic layer.
      • routes.js β†’ Defines Express routes.
      • model.js β†’ Database schema/model.
      • middleware.js β†’ Module-specific middleware.
  4. /middlewares β†’ Global middlewares like authentication and validation.
  5. /shared β†’ Reusable helpers (e.g., JWT, logging, API response formatting).
  6. /database β†’ Handles database connection, migrations, and seeders.
  7. /tests β†’ Organized test structure for unit/integration testing.
  8. server.js β†’ Starts the application.

πŸš€ Example Usage

πŸ“Œ server.js

const express = require("express");
const loaders = require("./src/loaders/express");
const database = require("./src/loaders/database");

async function startServer() {
  await database.connect(); // Initialize DB
  const app = express();
  loaders(app); // Initialize middlewares, routes, etc.
  
  const PORT = process.env.PORT || 5000;
  app.listen(PORT, () => console.log(`πŸš€ Server running on port ${PORT}`));
}

startServer();

πŸ“Œ src/loaders/express.js

const express = require("express");
const cors = require("cors");
const helmet = require("helmet");
const morgan = require("morgan");
const authRoutes = require("../modules/auth/auth.routes");
const userRoutes = require("../modules/user/user.routes");

module.exports = (app) => {
  app.use(cors());
  app.use(helmet());
  app.use(morgan("dev"));
  app.use(express.json());

  // Register routes
  app.use("/api/auth", authRoutes);
  app.use("/api/users", userRoutes);
};

πŸ“Œ src/modules/auth/auth.controller.js

const AuthService = require("./auth.service");

exports.login = async (req, res, next) => {
  try {
    const { email, password } = req.body;
    const token = await AuthService.authenticate(email, password);
    res.status(200).json({ success: true, token });
  } catch (error) {
    next(error);
  }
};

πŸ“Œ src/modules/auth/auth.service.js

const UserModel = require("../user/user.model");
const jwtHelper = require("../../shared/jwt.helper");

exports.authenticate = async (email, password) => {
  const user = await UserModel.findOne({ email });
  if (!user || user.password !== password) throw new Error("Invalid credentials");
  return jwtHelper.generateToken(user);
};

routes.js

fs.readdirSync(__dirname).forEach((file) => {
    if (file !== "index.js" && file.endsWith(".routes.js")) {
      const route = require(path.join(__dirname, file));
      app.use("/api", route);
    }
  });

πŸ† Benefits of This Structure

βœ… Modular & Scalable – Feature-based architecture for large applications.
βœ… Separation of Concerns – Clear division between routes, controllers, and services.
βœ… Easy to Maintain – Each module is self-contained and easy to extend.
βœ… Security & Performance – Uses helmet, cors, and morgan.
βœ… Database Flexibility – Supports MongoDB (Mongoose) or SQL (Sequelize/TypeORM).
βœ… Testing-Ready – Structured for easy unit/integration testing.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment