Project Structure

Organize code into clear folders as a project grows.

Small scripts fit in one file, but real projects need structure. A common layout separates concerns into folders:

  • src/ — your application code.
  • routes/ — HTTP route handlers.
  • services/ — business logic.
  • config/ — settings.
  • test/ — automated tests.

Guiding idea

Group files by responsibility, keep each module focused, and expose a clear entry point (often index.js or src/app.js).

Example

Example · bash
my-app/
  package.json
  index.js
  src/
    app.js
    routes/
      users.js
    services/
      userService.js
    config/
      index.js
  test/
    users.test.js

When to use it

  • A growing Express API separates routes, controllers, services, and models into distinct folders so each layer can be tested and changed independently.
  • A CLI tool places its commands in `src/commands/` and shared utilities in `src/lib/` so new commands can be added without touching existing ones.
  • A monorepo uses a `packages/` directory with individual `package.json` files so shared logic is published independently from the apps that consume it.

More examples

Recommended project layout

A typical layered structure for a Node.js REST API -- separates concerns so each folder has one responsibility.

Example · bash
my-api/
  src/
    routes/       # Express routers
    controllers/  # request handlers
    services/     # business logic
    models/       # DB schemas / entities
    middleware/   # auth, logging, etc.
    utils/        # shared helpers
    index.js      # entry point
  tests/
  .env
  package.json

Entry point that composes the app

Keeps the entry point minimal -- it loads config, imports the composed app, and starts the HTTP server.

Example · js
// src/index.js
require('dotenv').config();
const app    = require('./app');     // Express app setup
const config = require('./config');  // env vars

app.listen(config.port, () => {
  console.log(`API running on port ${config.port}`);
});

Barrel export pattern

Uses an `index.js` barrel file to re-export all utilities so callers import from one path instead of many.

Example · js
// src/utils/index.js -- re-exports all utilities
exports.slugify   = require('./slugify');
exports.paginate  = require('./paginate');
exports.parseDate = require('./parseDate');

// Consumer:
const { slugify, paginate } = require('./utils');

Discussion

  • Be the first to comment on this lesson.