Simple Todo app with Node.js and Express

In this quick tutorial we will be creating a Todo app without Database. The application will be very basic but will have all features as a “real todo app” like:

  • Add and complete task on single page (routing)
  • We will use Express
  • Minimal CSS styling


  • Create an empty directory called TodoApp
  • Open console and run npm init
  • Fill out the required information
  • Create a file named index.js

To get our server up and running we need to use Express.js.  Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.

Now we will install Express.js

npm install express --save

In index.js we need to add the following code:

var express = require('express');
var app = express()
app.get('/', function (req, res) {
  res.send('Hello World!');
app.listen(8080, function () {
  console.log('Running on port 8080!')

Now we can test our server by running:

node index.js

If you open your browser and visit: localhost:8080 and you should see Hello World!
The next part is to set our view. I will use EJS (Embedded JavaScript templating). EJS is a simple templating language that lets you generate HTML markup with plain JavaScript. No religiousness about how to organize things. No reinvention of iteration and control-flow. It’s just plain JavaScript.

Install EJS by running:

npm install ejs --save

Then in our index.js we need to add this line of code:

app.set('view engine', 'ejs');

EJS is accessed by default in the views directory. We need to create that folder. Within that folder we will add file index.ejs.
Our file looks like this.

    <title> Todo app  </title>
    <link href="/styles.css" rel="stylesheet">
  <div class="container">
     <h2> Simple Todo app </h2>
<form action ="/addtask" method="POST">
       <input type="text" name="newtask" placeholder="add new task">        <button> Add Task </button>
    <h2> Added Task </h2>
<button formaction="/removetask" type="submit"> Remove </button>
    <h2> Completed task </h2>

Next we need to replace our app.get in index.jsin order to send the equivalent HTML to the client.

app.get('/', function(req, res){

Now, if you run node index.js you shloud see content of index.ejs.

Let’s add our task.

Curently our form is submitting a post request to /addtask so we need to modifed route in our index.js file.'/addtask', function (req, res) {

The next step is to use Express Middleware. I recently published a post about Express Middleware. Middlewares are functions that have access to the reqand resbodies in order to preform more advanced tasks. We need to use body-parsermiddleware. It allows us to make use of the key-value pairs stored on the req-body object.

So let’s install it.

npm install body-parser --save

Once installed, we can require it:

var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));

Let’s update our index.js to display a list of all the newtask added by the user.

var task = ["buy milk", "learn javascript", "learn express"];'/addtask', function (req, res) {
    var newTask = req.body.newtask;
app.get("/", function(req, res) {
    res.render(‘index’, { task: task, complete: complete});

The index.ejs file:

<h2> Added Task </h2>
   <% for( var i = 0; i < task.length; i++){ %>
<li><input type="checkbox" name="check" value="<%= task[i] %>" /> <%= task[i] %> </li>
<% } %>

You can test the app by adding the todo item.

Now we need to add the delete button.

<button formaction="/removetask" type="submit"> Remove </button>

In our index.js file:

var complete = ["finish learning nodejs"];"/removetask", function(req, res) {
     var completeTask = req.body.check;
if (typeof completeTask === "string") {
  task.splice(task.indexOf(completeTask), 1);
  } else if (typeof completeTask === "object") {
    for (var i = 0; i < completeTask.length; i++) {     complete.push(completeTask[i]);
    task.splice(task.indexOf(completeTask[i]), 1);

And finally, index.ejs

<h2> Completed task </h2>
    <% for(var i = 0; i < complete.length; i++){ %>
      <li><input type="checkbox" checked><%= complete[i] %> </li>
<% } %>

Last but not least we will add some CSS to our app.

* {
    font-family: "lato", sans-serif;
    font-weight: bold;

body {
    background: rgb(245, 245, 245);
    color: #555555;
    margin-top: 20px;

.container {
    display: block;
    width: 350px;
    margin: 0 auto;

ul {
    margin: 0;
    padding: 0;

We need to add another folder called public and inside of that folder we need to create style.css.
Express won’ t allow access to this file by default, so we need to expose it with the following line of code in our index.js file like this:


Thank you for reading.

You can also read this

Error handling with ExpressJS

Error Handling refers to how Express catches and processes errors...

app.get('/', function (req, res, next) {
  fs.readFile('/file-does-not-exist', function (err, data) {

How to write middleware for Express.Js apps

Middleware functions are functions that have access to the request...

var logger = function (req, res, next) {