Web App: Basics
Node File Structure

Before we dive into coding, we are going to take a look at the file structure we are going to use for our app. There are a few variations on the structure used in production apps, but you will almost always see these folders. One major variation is that our app does not utilize a front-end framework (you may have heard of tools like Angular, Vue, or React), which alters the hierarchy.

We will create these folders as we need them, to help you get an intuitive feel for their uses, but refer back to this list for an overview of how each part of our app works together, and what goes where.


This is the core of the server - we use it to configure the app, and it is responsible for actually serving the application to the client (your web browser). It is also often called ‘index.js’ - it is just preference. In truth, everything in the models, routes, and helpers folders could be in app.js, but we separate them out to keep it clean. Ultimately, everything that our application needs to function is set up in this file.


Assets is a folder with two subfolders: css and js. If your application also has images, there is a third folder called images. This is where everything that appears on the frontend lives, and the html pages reference the files that they need. This is another folder that exists for organization - we keep all of our flavor files separated from the content of our pages to keep each page as small and digestible for other coders as possible. Many apps call this folder ‘public’. Again, it is simply preference. Anything that your html files use live in this folder.


This one isn’t going to make sense until the very end of the app tutorial. We are going to use it to store the functions for our web API, which will allow other devices (the AmbiLamp and Nani) to interact with the server. It is called ‘helpers’ because the web API will call on it to help out with those interactions. Don’t worry - we’ll talk about it more later.


When you put entries into a database, you want the format of each entry to be consistent. Say you do a search through your database for entries where “temperature=70”, and only half of the entries have a field for temperature! Your results will be sketchy at best, and may even return an error. Having models solves that by imposing a structure for everything that you insert - rather, it is where you store the “model” for a database entry. There is a file for each type of data that you will be storing, and each one lives in this folder.


npm actually creates this for you. We’ll be using several libraries created by other people, and node_modules stores all the the code for them. Just know that all of the tools we install for our app will exist in node_modules, separated from our own code.

package.json and package-lock.json

These two files work together. First, imagine a scenario where you are working with a partner on a project. You are working on a Linux computer, which you’ve configured for this kind of project, and it has all of the most up-to-date version of everything. Your partner is on a Windows computer, and when they install the tools that you tell them you are using, they get slightly different versions of the packages. Later, something works when you try it, so you share it with your partner, and they tell you later that it is broken! After hours debugging, you discover that since their versions are different, the stuff you implemented isn’t supported.

That is where package.json comes in - if you have worked with Python virtual environments, you’ll recognize this as Node.js’s way of creating a virtual environment. Whenever you install a tool or dependency, it is added to package.json, and running ‘npm install’ reads package.json for everything it should instead. That way, when your collaborator runs npm install, you can be certain they they get the exact same packages that you do. There are other things you can do in package.json, which you’ll learn about as you need them in other projects, but that is its primary service to our app.

package-lock.json takes it one step further - where package.json saves the current tools you are using, bugfixes and minor version updates may vary between updates. package-lock.json keeps a record of the changes to package.json, describing the exact tree that is generated any time you make a change, to ensure that installs use precisely the same versions. You can read more about how these two files work together here, but functionally, it suffices to know that you don’t have to do anything to them manually - npm takes care of them for you.


Routes is a folder storing the different places a user can go on your site. If you have pages at mysite.com, mysite.com/signup, and mysite.com/about-me, each of those pages in a route. You could put routes directly in app.js, but when you have a lot of routes it gets messy fast - instead, we describe all routes in logically-organized files (for example, users.js would have all the code for routes like signing up, logging in, or viewing a user’s profile, while posts.js could have all the routes for viewing a posting, making a new one, editing, etc..), in this folder, and tell app.js to look at them whenever a user asks to visit a page.


Views holds all of the templates. These are the html files that describe what goes on a page. If, for example, your site had a directory where a user could look at profiles of other users, you wouldn’t make a page for every user. Instead, you would make a template for a profile page, and feed it information from the database about the specific user. That template lives in views. There is also a folder called partials inside views. It is for code that repeats across files, so that instead of having duplicate code across multiple files, you just include the partial in each page. A classic use case for this is a navigation bar - instead of writing code for the top menu on every page, you could make a partial called header, and include the header in every page.

With an understanding of the shape of our project, let’s start building it.