The Question :
546 people think this question is useful
I’m using the ExpressJS web framework for NodeJS.
People using ExpressJS put their environments (development, production, test…), their routes etc on the app.js
. I think that it’s not a beautiful way because when you have a big application, app.js is too big!
I would like to have this directory structure:
| my-application
| -- app.js
| -- config/
| -- environment.js
| -- routes.js
Here’s my code:
app.js
var express = require('express');
var app = module.exports = express.createServer();
require('./config/environment.js')(app, express);
require('./config/routes.js')(app);
app.listen(3000);
config/environment.js
module.exports = function(app, express){
app.configure(function() {
app.use(express.logger());
});
app.configure('development', function() {
app.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));
});
app.configure('production', function() {
app.use(express.errorHandler());
});
};
config/routes.js
module.exports = function(app) {
app.get('/', function(req, res) {
res.send('Hello world !');
});
};
My code works well and I think that the structure of the directories is beautiful. However, the code had to be adapted and I’m not sure that it’s good/beautiful.
Is it better to use my structure of directories and adapt the code or simply use one file (app.js)?
Thanks for your advices!
The Question Comments :
The Answer 1
320 people think this answer is useful
OK, it’s been a while and this is a popular question, so I’ve gone ahead and created a scaffolding github repository with JavaScript code and a long README about how I like to structure a medium-sized express.js application.
focusaurus/express_code_structure is the repo with the latest code for this. Pull requests welcome.
Here’s a snapshot of the README since stackoverflow doesn’t like just-a-link answers. I’ll make some updates as this is a new project that I’ll continue updating, but ultimately the github repo will be the up-to-date place for this information.
Express Code Structure
This project is an example of how to organize a medium-sized express.js web application.
Current to at least express v4.14 December 2016


How big is your application?
Web applications are not all the same, and there’s not, in my opinion, a single code structure that should be applied to all express.js applications.
If your application is small, you don’t need such a deep directory structure as exemplified here. Just keep it simple and stick a handful of .js
files in the root of your repository and you’re done. Voilà.
If your application is huge, at some point you need to break it up into distinct npm packages. In general the node.js approach seems to favor many small packages, at least for libraries, and you should build your application up by using several npm packages as that starts to make sense and justify the overhead. So as your application grows and some portion of the code becomes clearly reusable outside of your application or is a clear subsystem, move it to it’s own git repository and make it into a standalone npm package.
So the focus of this project is to illustrate a workable structure for a medium-sized application.
What is your overall architecture
There are many approaches to building a web application, such as
- Server Side MVC a la Ruby on Rails
- Single Page Application style a la MongoDB/Express/Angular/Node (MEAN)
- Basic web site with some forms
- Models/Operations/Views/Events style a la MVC is dead, it’s time to MOVE on
- and many others both current and historical
Each of these fits nicely into a different directory structure. For the purposes of this example, it’s just scaffolding and not a fully working app, but I’m assuming the following key architecture points:
- The site has some traditional static pages/templates
- The “application” portion of the site is developed as a Single Page Application style
- The application exposes a REST/JSON style API to the browser
- The app models a simple business domain, in this case, it’s a car dealership application
And what about Ruby on Rails?
It will be a theme throughout this project that many of the ideas embodied in Ruby on Rails and the “Convention over Configuration” decisions they have adopted, though widely accepted and used, are not actually very helpful and sometimes are the opposite of what this repository recommends.
My main point here is that there are underlying principles to organizing code, and based on those principles, the Ruby on Rails conventions make sense (mostly) for the Ruby on Rails community. However, just thoughtlessly aping those conventions misses the point. Once you grok the basic principles, ALL of your projects will be well-organized and clear: shell scripts, games, mobile apps, enterprise projects, even your home directory.
For the Rails community, they want to be able to have a single Rails developer switch from app to app to app and be familiar and comfortable with it each time. This makes great sense if you are 37 signals or Pivotal Labs, and has benefits. In the server-side JavaScript world, the overall ethos is just way more wild west anything goes and we don’t really have a problem with that. That’s how we roll. We’re used to it. Even within express.js, it’s a close kin of Sinatra, not Rails, and taking conventions from Rails is usually not helping anything. I’d even say Principles over Convention over Configuration.
Underlying Principles and Motivations
The app symlink trick
There are many approaches outlined and discussed at length by the community in the great gist Better local require() paths for Node.js. I may soon decide to prefer either “just deal with lots of ../../../..” or use the requireFrom modlue. However, at the moment, I’ve been using the symlink trick detailed below.
So one way to avoid intra-project requires with annoying relative paths like require("../../../config")
is to use the following trick:
- create a symlink under node_modules for your app
- cd node_modules && ln -nsf ../app
- add just the node_modules/app symlink itself, not the entire node_modules folder, to git
- git add -f node_modules/app
- Yes, you should still have “node_modules” in your
.gitignore
file
- No, you should not put “node_modules” into your git repository. Some people will recommend you do this. They are incorrect.
- Now you can require intra-project modules using this prefix
var config = require("app/config");
var DealModel = require("app/deals/deal-model")
;
- Basically, this makes intra-project requires work very similarly to requires for external npm modules.
- Sorry, Windows users, you need to stick with parent directory relative paths.
Configuration
Generally code modules and classes to expect only a basic JavaScript options
object passed in. Only app/server.js
should load the app/config.js
module. From there it can synthesize small options
objects to configure subsystems as needed, but coupling every subsystem to a big global config module full of extra information is bad coupling.
Try to centralize creation of DB connections and pass those into subsystems as opposed to passing connection parameters and having subsystems make outgoing connections themselves.
NODE_ENV
This is another enticing but terrible idea carried over from Rails. There should be exactly 1 place in your app, app/config.js
that looks at the NODE_ENV
environment variable. Everything else should take an explicit option as a class constructor argument or module configuration parameter.
If the email module has an option as to how to deliver emails (SMTP, log to stdout, put in queue etc), it should take an option like {deliver: 'stdout'}
but it should absolutely not check NODE_ENV
.
Tests
I now keep my test files in the same directory as their corresponding code and use filename extension naming conventions to distinguish tests from production code.
foo.js
has the module “foo”‘s code
foo.tape.js
has the node-based tests for foo and lives in the same dir
foo.btape.js
can be used for tests that need to execute in a browser environment
I use filesystem globs and the find . -name '*.tape.js'
command to get access to all my tests as necessary.
How to organize code within each .js
module file
This project’s scope is mostly about where files and directories go, and I don’t want to add much other scope, but I’ll just mention that I organize my code into 3 distinct sections.
- Opening block of CommonJS require calls to state dependencies
- Main code block of pure-JavaScript. No CommonJS pollution in here. Don’t reference exports, module, or require.
- Closing block of CommonJS to set up exports
The Answer 2
157 people think this answer is useful
UPDATE (2013-10-29): Please see my other answer as well which has JavaScript instead of CoffeeScript by popular demand as well as a boilerplate github repo and an extensive README detailing my latest recommendations on this topic.
Config
What you are doing is fine. I like to have my own config namespace set up in a top-level config.coffee
file with a nested namespace like this.
#Set the current environment to true in the env object
currentEnv = process.env.NODE_ENV or 'development'
exports.appName = "MyApp"
exports.env =
production: false
staging: false
test: false
development: false
exports.env[currentEnv] = true
exports.log =
path: __dirname + "/var/log/app_#{currentEnv}.log"
exports.server =
port: 9600
#In staging and production, listen loopback. nginx listens on the network.
ip: '127.0.0.1'
if currentEnv not in ['production', 'staging']
exports.enableTests = true
#Listen on all IPs in dev/test (for testing from other machines)
exports.server.ip = '0.0.0.0'
exports.db =
URL: "mongodb://localhost:27017/#{exports.appName.toLowerCase()}_#{currentEnv}"
This is friendly for sysadmin editing. Then when I need something, like the DB connection info, it`s
require('./config').db.URL
Routes/Controllers
I like to leave my routes with my controllers and organize them in an app/controllers
subdirectory. Then I can load them up and let them add whatever routes they need.
In my app/server.coffee
coffeescript file I do:
[
'api'
'authorization'
'authentication'
'domains'
'users'
'stylesheets'
'javascripts'
'tests'
'sales'
].map (controllerName) ->
controller = require './controllers/' + controllerName
controller.setup app
So I have files like:
app/controllers/api.coffee
app/controllers/authorization.coffee
app/controllers/authentication.coffee
app/controllers/domains.coffee
And for example in my domains controller, I have a setup
function like this.
exports.setup = (app) ->
controller = new exports.DomainController
route = '/domains'
app.post route, controller.create
app.put route, api.needId
app.delete route, api.needId
route = '/domains/:id'
app.put route, controller.loadDomain, controller.update
app.del route, controller.loadDomain, exports.delete
app.get route, controller.loadDomain, (req, res) ->
res.sendJSON req.domain, status.OK
Views
Putting views in app/views
is becoming the customary place. I lay it out like this.
app/views/layout.jade
app/views/about.jade
app/views/user/EditUser.jade
app/views/domain/EditDomain.jade
Static Files
Go in a public
subdirectory.
Github/Semver/NPM
Put a README.md markdown file at your git repo root for github.
Put a package.json file with a semantic version number in your git repo root for NPM.
The Answer 3
51 people think this answer is useful
The following is Peter Lyons’ answer verbatim, ported over to vanilla JS from Coffeescript, as requested by several others. Peter’s answer is very able, and anyone voting on my answer should vote on his as well.
Config
What you are doing is fine. I like to have my own config namespace set up in a top-level config.js
file with a nested namespace like this.
// Set the current environment to true in the env object
var currentEnv = process.env.NODE_ENV || 'development';
exports.appName = "MyApp";
exports.env = {
production: false,
staging: false,
test: false,
development: false
};
exports.env[currentEnv] = true;
exports.log = {
path: __dirname + "/var/log/app_#{currentEnv}.log"
};
exports.server = {
port: 9600,
// In staging and production, listen loopback. nginx listens on the network.
ip: '127.0.0.1'
};
if (currentEnv != 'production' && currentEnv != 'staging') {
exports.enableTests = true;
// Listen on all IPs in dev/test (for testing from other machines)
exports.server.ip = '0.0.0.0';
};
exports.db {
URL: "mongodb://localhost:27017/#{exports.appName.toLowerCase()}_#{currentEnv}"
};
This is friendly for sysadmin editing. Then when I need something, like the DB connection info, it`s
require('./config').db.URL
Routes/Controllers
I like to leave my routes with my controllers and organize them in an app/controllers
subdirectory. Then I can load them up and let them add whatever routes they need.
In my app/server.js
javascript file I do:
[
'api',
'authorization',
'authentication',
'domains',
'users',
'stylesheets',
'javascripts',
'tests',
'sales'
].map(function(controllerName){
var controller = require('./controllers/' + controllerName);
controller.setup(app);
});
So I have files like:
app/controllers/api.js
app/controllers/authorization.js
app/controllers/authentication.js
app/controllers/domains.js
And for example in my domains controller, I have a setup
function like this.
exports.setup = function(app) {
var controller = new exports.DomainController();
var route = '/domains';
app.post(route, controller.create);
app.put(route, api.needId);
app.delete(route, api.needId);
route = '/domains/:id';
app.put(route, controller.loadDomain, controller.update);
app.del(route, controller.loadDomain, function(req, res){
res.sendJSON(req.domain, status.OK);
});
}
Views
Putting views in app/views
is becoming the customary place. I lay it out like this.
app/views/layout.jade
app/views/about.jade
app/views/user/EditUser.jade
app/views/domain/EditDomain.jade
Static Files
Go in a public
subdirectory.
Github/Semver/NPM
Put a README.md markdown file at your git repo root for github.
Put a package.json file with a semantic version number in your git repo root for NPM.
The Answer 4
47 people think this answer is useful
My question was introduced in April 2011, it’s quiet old. During this time, I could improve my experience with Express.js and how to architecture an application written using this library. So, I share here my experience.
Here’s my directory structure:
├── app.js // main entry
├── config // The configuration of my applications (logger, global config, ...)
├── models // The model data (e.g. Mongoose model)
├── public // The public directory (client-side code)
├── routes // The route definitions and implementations
├── services // The standalone services (Database service, Email service, ...)
└── views // The view rendered by the server to the client (e.g. Jade, EJS, ...)
App.js
The goal of the app.js
file is to bootstrap the expressjs application. It loads the configuration module, the logger module, wait for database connection, …, and run the express server.
'use strict';
require('./config');
var database = require('./services/database');
var express = require('express');
var app = express();
module.exports = app;
function main() {
var http = require('http');
// Configure the application.
app.configure(function () {
// ... ... ...
});
app.configure('production', function () {
// ... ... ...
});
app.configure('development', function () {
// ... ... ...
});
var server = http.createServer(app);
// Load all routes.
require('./routes')(app);
// Listen on http port.
server.listen(3000);
}
database.connect(function (err) {
if (err) {
// ...
}
main();
});
routes/
The routes directory has a index.js
file. Its goal is to introduce a kind of magic to load all other files inside the routes/
directory. Here’s the implementation:
/**
* This module loads dynamically all routes modules located in the routes/
* directory.
*/
'use strict';
var fs = require('fs');
var path = require('path');
module.exports = function (app) {
fs.readdirSync('./routes').forEach(function (file) {
// Avoid to read this current file.
if (file === path.basename(__filename)) { return; }
// Load the route file.
require('./' + file)(app);
});
};
With that module, creating a new route definition and implementation is really easy. For examples, hello.js
:
function hello(req, res) {
res.send('Hello world');
}
module.exports = function (app) {
app.get('/api/hello_world', hello);
};
Each route module is standalone.
The Answer 5
18 people think this answer is useful
I like to use a global “app”, rather than exporting a function etc
The Answer 6
17 people think this answer is useful
I think it’s a great way to do it. Not limited to express but I’ve seen quite a number of node.js projects on github doing the same thing. They take out the configuration parameters + smaller modules (in some cases every URI) are factored in separate files.
I would recommend going through express-specific projects on github to get an idea. IMO the way you are doing is correct.
The Answer 7
17 people think this answer is useful
it is now End of 2015 and after developing my structure for 3 years and in small and large projects. Conclusion?
Do not do one large MVC, but separate it in modules
So…
Why?
Usually one works on one module (e.g. Products), which you can change independently.
You are able to reuse modules
You are able to test it separatly
You are able to replace it separatly
They have clear (stable) interfaces
-At latest, if there were multiple developers working, module separation helps
The nodebootstrap project has a similar approach to my final structure. (github)
How does this structure look like?
Small, capsulated modules, each with separate MVC
Each module has a package.json
Testing as a part of the structure (in each module)
Global configuration, libraries and Services
Integrated Docker, Cluster, forever
Folderoverview (see lib folder for modules):

The Answer 8
9 people think this answer is useful
I am giving MVC style folder structure please find bellow .
We used bellow folder structure for our big and medium web applications .
myapp
|
|
|____app
| |____controllers
| | |____home.js
| |
| |____models
| | |___home.js
| |
| |____views
| |___404.ejs
| |___error.ejs
| |___index.ejs
| |___login.ejs
| |___signup.ejs
|
|
|_____config
| |___auth.js
| |___constants.js
| |___database.js
| |___passport.js
| |___routes.js
|
|
|____lib
| |___email.js
|
|____node_modules
|
|
|____public.js
| |____css
| | |__style.css
| |
| |____js
| | |__script.js
| |
| |____img
| | |__img.jpg
| |
| |
| |____uploads
| |__img.jpg
|
|
|
|_____app.js
|
|
|
|_____package.json
I have created one npm module for generation express mvc folder structurer.
Please find the bellow https://www.npmjs.com/package/express-mvc-generator
Just simple steps to generate and use this modules .
i) install module npm install express-mvc-generator -g
ii) check options express -h
iii) Generate express mvc structure express myapp
iv) Install dependencies: npm install
:
v)Open your config/database.js , Please configure your mongo db.
vi)Run the application node app
or nodemon app
vii)Check URL http://localhost:8042/signup OR http://yourip:8042/signup
The Answer 9
7 people think this answer is useful
It’s been quite a while since the last answer to this question and Express has also recently released version 4, which added a few useful things for organising your app structure.
Below is a long up to date blog post about best practices on how to structure your Express app.
http://www.terlici.com/2014/08/25/best-practices-express-structure.html
There is also a GitHub repository applying the advice in the article. It is always up to date with the latest Express version.
https://github.com/terlici/base-express
The Answer 10
7 people think this answer is useful
I don’t think it’s a good approach to add routes to config. A better structure could be something like this:
application/
| - app.js
| - config.js
| - public/ (assets - js, css, images)
| - views/ (all your views files)
| - libraries/ (you can also call it modules/ or routes/)
| - users.js
| - products.js
| - etc...
So products.js and users.js will contain all your routes will all logic within.
The Answer 11
6 people think this answer is useful
Well I put my routes as a json file, that I read at the beginning, and in a for-loop in app.js set up the routes. The route.json includes which view that should be called, and the key for the values that will be sent into the route.
This works for many simple cases, but I had to manually create some routes for special cases.
The Answer 12
6 people think this answer is useful
I have written a post exactly about this matter. It basically makes use of a routeRegistrar
that iterates through files in the folder /controllers
calling its function init
. Function init
takes the express app
variable as a parameter so you can register your routes the way you want.
var fs = require("fs");
var express = require("express");
var app = express();
var controllersFolderPath = __dirname + "/controllers/";
fs.readdirSync(controllersFolderPath).forEach(function(controllerName){
if(controllerName.indexOf("Controller.js") !== -1){
var controller = require(controllersFolderPath + controllerName);
controller.init(app);
}
});
app.listen(3000);
The Answer 13
5 people think this answer is useful
This may be of interest:
https://github.com/flatiron/nconf
Hierarchical node.js configuration with files, environment variables, command-line arguments, and atomic object merging.
The Answer 14
4 people think this answer is useful
1) Your Express project filesystem maybe like:
/ ...
/lib
/node_modules
/public
/views
app.js
config.json
package.json
app.js – you global app container
2) Module main file (lib/mymodule/index.js):
var express = require('express');
var app = module.exports = express();
// and load module dependencies ...
// this place to set module settings
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');
// then do module staff
app.get('/mymodule/route/',function(req,res){ res.send('module works!') });
3) Connect module in main app.js
...
var mymodule = require('mymodule');
app.use(mymodule);
4) Sample logic
lib/login
lib/db
lib/config
lib/users
lib/verify
lib/
/api/
...
lib/
/admin/
/users/
/settings/
/groups/
...
- Best for testing
- Best for scale
- Separate depends by module
- Grouping route by functionality (or modules)
tj says/show on Vimeo interesting idea how modularize express application –
Modular web applications with Node.js and Express. Powerful and simple.
The Answer 15
4 people think this answer is useful
http://locomotivejs.org/ provides a way to structure an app built with Node.js and Express.
From the website:
“Locomotive is a web framework for Node.js. Locomotive supports MVC
patterns, RESTful routes, and convention over configuration, while
integrating seamlessly with any database and template engine.
Locomotive builds on Express, preserving the power and simplicity
you’ve come to expect from Node.”
The Answer 16
3 people think this answer is useful
I recently embraced modules as independent mini-apps.
|-- src
|--module1
|--module2
|--www
|--img
|--js
|--css
|--#.js
|--index.ejs
|--module3
|--www
|--bower_components
|--img
|--js
|--css
|--#.js
|--header.ejs
|--index.ejs
|--footer.ejs
Now for any module routing (#.js), views (*.ejs), js, css and assets are next to each other.
submodule routing is set up in the parent #.js with two additional lines
router.use('/module2', opt_middleware_check, require('./module2/#'));
router.use(express.static(path.join(__dirname, 'www')));
This way even subsubmodules are possible.
Don’t forget to set view to the src directory
app.set('views', path.join(__dirname, 'src'));
The Answer 17
1 people think this answer is useful
This is how most of my express project directory structure looks.
I usually do a express dirname
to initialise the project, forgive my laziness, but it’s very flexible and extendable. PS – you need to get express-generator
for that (for those who’re looking for it sudo npm install -g express-generator
, sudo because you’re installing it globally)
|-- bin
|-- www //what we start with "forever"
|-- bower_components
|-- models
|-- database.js
|-- model1.js //not this exact name ofcourse.
|-- .
|-- node_modules
|-- public
|-- images
|-- javascripts
|-- controllers
|-- directives
|-- services
|-- app.js
|-- init.js //contains config and used for initializing everything, I work with angular a lot.
|-- stylesheets
|-- routes
|-- some
|-- hierarchy
.
.
|-- views
|-- partials
|-- content
|-- .env
|-- .env.template
|-- app.js
|-- README.md
You must be wondering why .env files? Because they work! I use dotenv
module in my projects (a lot recently) and it works! Pop in these 2 statements in app.js
or www
var dotenv = require('dotenv');
dotenv.config({path: path.join(__dirname + "/.env")});
And another line to quickly set /bower_components
to serve static content under the resource /ext
app.use('/ext', express.static(path.join(__dirname, 'bower_components')));
It probably can be a fit for people who’re looking to use Express and Angular together, or just express without that javascripts
hierarchy of course.
The Answer 18
1 people think this answer is useful
My structure express 4.
https://github.com/odirleiborgert/borgert-express-boilerplate
Packages
View engine: twig
Security: helmet
Flash: express-flash
Session: express-session
Encrypt: bcryptjs
Modules: express-load
Database: MongoDB
ORM: Mongoose
Mongoose Paginate
Mongoose Validator
Logs: winston + winston-daily-rotate-file
Nodemon
CSS: stylus
Eslint + Husky
Structure
|-- app
|-- controllers
|-- helpers
|-- middlewares
|-- models
|-- routes
|-- services
|-- bin
|-- logs
|-- node_modules
|-- public
|-- components
|-- images
|-- javascripts
|-- stylesheets
|-- views
|-- .env
|-- .env-example
|-- app.js
|-- README.md
The Answer 19
1 people think this answer is useful
Sails.js structure looks nice and clean to me, so I use MVC style structure for my express projects, similar to sails.js.
project_root
|
|_ _ app
|_ _ |_ _ controllers
|_ _ |_ _ |_ _ UserController.js
|_ _ |_ _ middlewares
|_ _ |_ _ |_ _ error.js
|_ _ |_ _ |_ _ logger.js
|_ _ |_ _ models
|_ _ |_ _ |_ _ User.js
|_ _ |_ _ services
|_ _ |_ _ |_ _ DatabaseService.js
|
|_ _ config
|_ _ |_ _ constants.js
|_ _ |_ _ index.js
|_ _ |_ _ routes.js
|
|_ _ public
|_ _ |_ _ css
|_ _ |_ _ images
|_ _ |_ _ js
|
|_ _ views
|_ _ |_ _ user
|_ _ |_ _ |_ _ index.ejs
App folder – contains overall login for application.
Config folder – contains app configurations, constants, routes.
Public folder – contains styles, images, scripts etc.
Views folder – contains views for each model (if any)
Boilerplate project could be found here,
https://github.com/abdulmoiz251/node-express-rest-api-boilerplate
The Answer 20
0 people think this answer is useful
A simple way to structure ur express app:
The Answer 21
0 people think this answer is useful
Best Way To MVC Structure for ExpressJs Project with handlebar & Passportjs
- app
-config
-passport-setup.js
-controllers
-middleware
-models
-routes
-service
-bin
-www
-configuration.js
-passport.js
-node_modules
-views
-handlebars page
-env
-.gitignore
-package.json
-package-lock.json