Last August, I joined a small team in building a small web application. Before this, I'd never worked on an app that would actually be deployed to a production environment; I had only worked on small personal projects for fun. Of course, I've learned a lot about building serious apps that hold up in the wild.

If you have worked on "real" projects before, none of this will be news. However, if you're new to programming professionally, maybe this will keep you from tripping where I did.


When I'm building apps for fun, it's easy to go into "hack mode," and spend all my time writing code. But as a developer managing a real-world app, there are other tasks that you need to take care of. You can automate much of these tasks.

The biggest one, of course, is deployment. It's tedious and error-prone to manually deploy your application every time you're ready to release a new feature into the wild. Instead, automate this process. Using Git means it only takes a single command to push our app to the server; then, there's a git hook on the server that runs the deployment script. Deployment becomes as easy as cd or ls.

Of course, you can automate more than deployment. You probably already use npm scripts (or Grunt/Gulp/etc.) to compile and minify parts of your projects. You can also write scripts that perform backup/cleanup jobs for your database and assets, both locally and on your servers. If you do it more than once, think about automating it.

A Staging Server

I remember a time when I didn't get the point of a staging server: no more. The staging server is one of the most important parts of our workflow.

A staging server, or staging site, is an actual, running version of our application, the sole purpose of which is testing and review. Ideally, your staging site should run on the same setup (software versions, etc.) that your production site will run on. This was easy for us: since our app is so small, we're running both on the same VPS.

When a feature is ready for deployment, it first goes to the staging server. There, members of the team and other testers can look for bugs and edge cases that might have been missed during development. It's only once a feature has been signed off on the staging server that it gets pushed to the production server.

Environment Variables

When I'm building "toy" apps, I rarely think about running my code anywhere but on my laptop. Now, I need to write code that runs in three environments (development, staging, and production). If you're doing this for the first time, you'll quickly run into a wall: what do you do with values that differ from environment to environment? We're talking about API keys, database URIs, directory paths, port numbers, and so on.

The answer is to give each environment a file (often named .env) for its own environment variables1. It might look something like this:


Use a package like dotenv to load this file when your app starts. Then, all your environment variables will be properties of process.env.


We all know it: every projects should have tests. But I sometimes "forget" them on toy projects, when I know I'm the only one using the code. I shouldn't do that. NEVER do that on real projects.

Bug Tracking

Tests won't take care of every bug. Your project, no matter how small, should have a bug list. And it's important that you make it easy for your users/testers to submit bugs. Believe me, they'll find edge cases in spades.


It's important to have a record of the features you've built and the bugs you've fixed. Regularly document what you've done; we work in small feature sets, so it makes sense for us to document our work after each set is complete, but do what works for you. If you're having trouble with this, I've found that commit messages are a good place to start.

  1. You don't want to check your .env files into source control; they probably includes secrets you want to keep safe. Instead, each one should live in its environment. Probably, a script will copy it into place during deployment.