This tutorial is out of date and no longer maintained.
Beginning an application from scratch can sometimes be the hardest thing to do. Staring at an empty folder and a file with no code in it yet can be a very daunting thing.
In today’s tutorial, we will be looking at the starting setup for a Node.js, AngularJS, MongoDB, and Express application (otherwise known as MEAN). I put those in the wrong order, I know.
This will be a starting point for those that want to learn how to begin a MEAN stack application. Projects like mean.io and meanjs.org are more fully-fledged MEAN applications with many great features you’d want for a production project.
You will be able to start from absolute scratch and create a basic application structure that will allow you to build any sort of application you want.
Note: (7/8/14): Updated article for Express 4 support. Thanks to Caio Mariano for the help.
Note (10/12/14): Updated article to add Nerd model and make everything clearer.
This article has been updated to work with Express 4.0
A lot of the applications we’ve dealt with so far had a specific function, like our Node and Angular To-Do Single Page Application. We are going to step away from that and just a good old getting started application.
This will be very barebones but hopefully, it will help you set up your applications. Let’s just call it a starter kit.
This tutorial will be more based on application structure and creating a solid foundation for single-page MEAN stack applications. For more information on CRUD, authentication, or other topics in MEAN apps we’ll make sure to write other tutorials to fill those gaps.
Three letters out of the MEAN stack will be handled on the backend, our server. We will create our server, configure our application, and handle application routing.
We will need Node and to make our lives easier, we’ll use bower to pull in all our dependencies.
Bower isn’t really necessary. You could pull in all the files we need yourself (bootstrap
, angular
, angular-route
), but bower just gets them all for you! For more info, read our guide on bower to get a better understanding.
By the end of this tutorial, we will have a basic application structure that will help us develop our Node backend along with our Angular frontend. Here’s what it will look like.
- app
----- models/
---------- nerd.js <!-- the nerd model to handle CRUD -->
----- routes.js
- config
----- db.js
- node_modules <!-- created by npm install -->
- public <!-- all frontend and angular stuff -->
----- css
----- js
---------- controllers <!-- angular controllers -->
---------- services <!-- angular services -->
---------- app.js <!-- angular application -->
---------- appRoutes.js <!-- angular routes -->
----- img
----- libs <!-- created by bower install -->
----- views
---------- home.html
---------- nerd.html
---------- geek.html
----- index.html
- .bowerrc <!-- tells bower where to put files (public/libs) -->
- bower.json <!-- tells bower which files we need -->
- package.json <!-- tells npm which packages we need -->
- server.js <!-- set up our node application -->
We’ll be filling in our files into a folder structure. All backend work is done in server.js
, app
, and config
while all the frontend is handled in the public
folder.
All Node applications will start with a package.json
file so let’s begin with that.
{
"name": "starter-node-angular",
"main": "server.js",
"dependencies": {
"express" : "~4.5.1",
"mongoose" : "~3.8.0",
"body-parser" : "~1.4.2",
"method-override" : "~2.0.2"
}
}
That’s it! Now our application will know that we want to use Express and Mongoose.
Note: Since Express 4.0, body-parser
and method-override
are their own modules, which is why we have to include them here. For more information, here’s our guide to Express 4.
Express is a Node.js web application framework that will help us create our application. Mongoose is a MongoDB ORM that will help us communicate with our MongoDB database.
To install the dependencies we just setup, just go into your console and type:
npm install
You’ll see your application working to bring in those modules into the node_modules
directory that it creates.
Now that we have those, let’s set up our application in server.js
.
Since this is our starter kit for a single-page MEAN application, we are going to keep this simple. The entire code for the file is here and it is commented for help understanding.
// modules =================================================
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
// configuration ===========================================
// config files
var db = require('./config/db');
// set our port
var port = process.env.PORT || 8080;
// connect to our mongoDB database
// (uncomment after you enter in your own credentials in config/db.js)
// mongoose.connect(db.url);
// get all data/stuff of the body (POST) parameters
// parse application/json
app.use(bodyParser.json());
// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }));
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// override with the X-HTTP-Method-Override header in the request. simulate DELETE/PUT
app.use(methodOverride('X-HTTP-Method-Override'));
// set the static files location /public/img will be /img for users
app.use(express.static(__dirname + '/public'));
// routes ==================================================
require('./app/routes')(app); // configure our routes
// start app ===============================================
// startup our app at http://localhost:8080
app.listen(port);
// shoutout to the user
console.log('Magic happens on port ' + port);
// expose app
exports = module.exports = app;
We have now pulled in our modules, configured our application for things like database, some express settings, routes, and then started our server. Notice how we didn’t pull in mongoose
here. There’s no need for it yet. We will be using it in our model that we will define soon.
Let’s look at config
, a quick model
, and routes
since we haven’t created those yet. Those will be the last things that the backend side of our application needs.
I know it doesn’t seem like much now since we only are putting the db.js
config file here, but this was more for demonstration purposes. In the future, you may want to add more config files and call them in server.js
so this is how we will do it.
module.exports = {
url : 'mongodb://localhost/stencil-dev'
}
Now that this file is defined and we’ve called it in our server.js
using var db = require('./config/db');
, you can call any items inside of it using db.url
.
For getting this to work, you’ll want a local MongoDB database installed or you can just grab a quick one-off service like Modulus or Mongolab. Just go ahead and create an account at one of those, create a database with your own credentials, and you’ll be able to get the URL string to use in your own config file.
Next up, we’ll create a quick Mongoose model so that we can define our Nerds in our database.
This will be all that is required to create records in our database. Once we define our Mongoose model, it will let us handle creating, reading, updating, and deleting our nerds.
Let’s go into the app/models/nerd.js
file and add the following:
// grab the mongoose module
var mongoose = require('mongoose');
// define our nerd model
// module.exports allows us to pass this to other files when it is called
module.exports = mongoose.model('Nerd', {
name : {type : String, default: ''}
});
This is where we will use the Mongoose module and be able to define our Nerd model with a name attribute with data type String
. If you want more fields, feel free to add them here. Read up on the Mongoose docs to see all the things you can define.
Let’s move onto the routes and use the model we just created.
In the future, you can use the app folder to add more models, controllers, routes, and anything backend (Node) specific to your app.
Let’s get to our routes. When creating a single-page application, you will usually want to separate the functions of the backend application and the frontend application as much as possible.
To separate the duties of the separate parts of our application, we will be able to define as many routes as we want for our Node backend. This could include API routes or any other routes of that nature.
We won’t be diving into those since we’re not really handling creating an API or doing CRUD in this tutorial, but just know that this is where you’d handle those routes.
We’ve commented out the place to put those routes here.
// grab the nerd model we just created
var Nerd = require('./models/nerd');
module.exports = function(app) {
// server routes ===========================================================
// handle things like api calls
// authentication routes
// sample api route
app.get('/api/nerds', function(req, res) {
// use mongoose to get all nerds in the database
Nerd.find(function(err, nerds) {
// if there is an error retrieving, send the error.
// nothing after res.send(err) will execute
if (err)
res.send(err);
res.json(nerds); // return all nerds in JSON format
});
});
// route to handle creating goes here (app.post)
// route to handle delete goes here (app.delete)
// frontend routes =========================================================
// route to handle all angular requests
app.get('*', function(req, res) {
res.sendfile('./public/views/index.html'); // load our public/index.html file
});
};
This is where you can handle your API routes. For all other routes (*
), we will send the user to our frontend application where Angular can handle routing them from there.
Now that we have everything we need for our server to get set up! At this point, we can start our server, send a user the Angular app (index.html
), and handle 1 API route to get all the nerds.
Let’s create that index.html
file so that we can test out our server.
Let’s just open up this file and add some quick text so we can test our server.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Starter MEAN Single Page Application</title>
</head>
<body>
we did it!
</body>
</html>
With all the backend (and a tiny frontend piece) in place, let’s start up our server. Go into your console and type:
- node server.js
Now we can go into our browser and see http://localhost:8080
in action.
So simple, and yet so beautiful. Now let’s get to the frontend single-page AngularJS stuff.
With all of our backend work in place, we can focus on the frontend. Our Node backend will send any user that visits our application to our index.html
file since we’ve defined that in our catch-all route (app.get('*')
).
The frontend work will require a few things:
We will need certain files for our application like bootstrap and of course angular. We will tell bower to grab those components for us.
Bower is a great frontend tool to manage your frontend resources. You just specify the packages you need and it will go grab them for you. Here’s an article on getting started with bower.
First, we will need Bower installed on our machine. Just type in npm install -g bower
into your console.
After you have done that, you will now have access to bower globally on your system. We will need 2 files to get Bower working for us (.bowerrc
and bower.json
). We’ll place both of these in the root of our document.
.bowerrc will tell Bower where to place our files:
{
"directory": "public/libs"
}
bower.json is similar to package.json and will tell Bower which packages are needed.
{
"name": "starter-node-angular",
"version": "1.0.0",
"dependencies": {
"bootstrap": "latest",
"font-awesome": "latest",
"animate.css": "latest",
"angular": "latest",
"angular-route": "latest"
}
}
Let’s run it! In your console, in the root of your application, type:
- bower install
You can see bower pull in all the files we needed and now we have them in public/libs
!
Now we can get down to business and work on our Angular stuff.
For our Angular application, we will want:
Let’s create the files needed for our Angular application. This will be done in public/js
. Here is the application structure for our frontend:
- public
----- js
---------- controllers
-------------------- MainCtrl.js
-------------------- NerdCtrl.js
---------- services
-------------------- NerdService.js
---------- app.js
---------- appRoutes.js
Once we have created our controllers, services, and routes, we will combine them all and inject these modules into our main app.js
file to get everything working together.
We won’t go too far in-depth here so let’s just show off all three of our controllers and their code.
angular.module('MainCtrl', []).controller('MainController', function($scope) {
$scope.tagline = 'To the moon and back!';
});
angular.module('NerdCtrl', []).controller('NerdController', function($scope) {
$scope.tagline = 'Nothing beats a pocket protector!';
});
Of course in the future, you will be doing a lot more with your controllers, but since this is more about application setup, we’ll move onto the services.
This is where you would use $http
or $resource
to do your API calls to the Node backend from your Angular frontend.
angular.module('NerdService', []).factory('Nerd', ['$http', function($http) {
return {
// call to get all nerds
get : function() {
return $http.get('/api/nerds');
},
// these will work when more API routes are defined on the Node side of things
// call to POST and create a new nerd
create : function(nerdData) {
return $http.post('/api/nerds', nerdData);
},
// call to DELETE a nerd
delete : function(id) {
return $http.delete('/api/nerds/' + id);
}
}
}]);
That’s it for our services. The only function that will work in that NerdService
is the get
function. The other two are just placeholders and they won’t work unless you define those specific routes in your app/routes.js
file. For more on building APIs, here’s a tutorial for Building a RESTful Node API.
These services will call our Node backend, retrieve data in JSON format, and then we can use it in our Angular controllers.
Now we will define our Angular routes inside of our public/js/appRoutes.js
file.
angular.module('appRoutes', []).config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
// home page
.when('/', {
templateUrl: 'views/home.html',
controller: 'MainController'
})
// nerds page that will use the NerdController
.when('/nerds', {
templateUrl: 'views/nerd.html',
controller: 'NerdController'
});
$locationProvider.html5Mode(true);
}]);
Our Angular frontend will use the template file and inject it into the <div ng-view></div>
in our index.html
file. It will do this without a page refresh which is exactly what we want for a single page application.
For more information on Angular routing and templating, check out our other tutorial: Single Page Apps with AngularJS.
With all of the Angular routing ready to go, we just need to create the view files and then the smaller template files (home.html
, nerd.html
, and geek.html
) will be injected into our index.html
file inside of the <div ng-view></div>
.
Notice in our index.html
file we are calling the resources we pulled in using bower.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<base href="/">
<title>Starter Node and Angular</title>
<!-- CSS -->
<link rel="stylesheet" href="libs/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="css/style.css"> <!-- custom styles -->
<!-- JS -->
<script src="libs/angular/angular.min.js"></script>
<script src="libs/angular-route/angular-route.min.js"></script>
<!-- ANGULAR CUSTOM -->
<script src="js/controllers/MainCtrl.js"></script>
<script src="js/controllers/NerdCtrl.js"></script>
<script src="js/services/NerdService.js"></script>
<script src="js/appRoutes.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="sampleApp" ng-controller="NerdController">
<div class="container">
<!-- HEADER -->
<nav class="navbar navbar-inverse">
<div class="navbar-header">
<a class="navbar-brand" href="/">Stencil: Node and Angular</a>
</div>
<!-- LINK TO OUR PAGES. ANGULAR HANDLES THE ROUTING HERE -->
<ul class="nav navbar-nav">
<li><a href="/nerds">Nerds</a></li>
</ul>
</nav>
<!-- ANGULAR DYNAMIC CONTENT -->
<div ng-view></div>
</div>
</body>
</html>
<!-- public/views/home.html -->
<div class="jumbotron text-center">
<h1>Home Page 4 Life</h1>
<p>{{ tagline }}</p>
</div>
<!-- public/views/nerd.html -->
<div class="jumbotron text-center">
<h1>Nerds and Proud</h1>
<p>{{ tagline }}</p>
</div>
We have defined our resources, controllers, services, and routes and included the files in our index.html
. Now let’s make them all work together.
Let’s set up our Angular app to use all of our components. We will use dependency injection and set up our Angular application.
angular.module('sampleApp', ['ngRoute', 'appRoutes', 'MainCtrl', 'NerdCtrl', 'NerdService']);
Now we have an application that has a Node.js backend and an AngularJS frontend. We can use this foundation to build any sort of application moving forward. We can add authentication and CRUD functionality to create a good application.
Also, for those looking for this project with the addition of the Jade templating engine, Florian Zemke has created a Jade version at his GitHub repo.
Moving forward, I’d encourage you to take this and see if it fits your needs. The point of this was to have a foundation for starting applications so that we aren’t reinventing the wheel every time we start a new project.
This is a very barebones example and for something more in-depth, I’d encourage people to take a look at mean.io for a more in-depth starter application.
Check out the GitHub repo for this project and take from it what you need. Sound off in the comments if you have any questions about how to expand this into your own applications.
We’ve put this tutorial together as a starter kit at the GitHub repo. We’ll keep adding features to it on request and any updates we think will be helpful for applications.
Hopefully, it will be a good foundation for any sort of Single Page MEAN Stack Application.
npm install
bower install
node server.js
http://localhost:8080
Further Reading: When building MEAN stack apps, the backend Node application will usually be an API that we build. This will allow the Angular frontend to consume our API that we built through Angular services. The next step is to hash out building a Node API. This next tutorial will teach us that and then we can go further in-depth on how to build the frontend Angular application to consume our new API.
This article is part of our Getting MEAN series. Here are the other articles.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.