Node.js for e-commerce: benefits, tools, and a killer Koa.js demo

Francis Cote
We’ve moved to freeCodeCamp.org/news
8 min readFeb 13, 2019
Photo by Scott Webb on Unsplash

The Snipcart team has spent a lot of time lately blogging about frontend JavaScript frameworks.

Vue.js, React, Angular… we ❤ these.

I thought I’d shake things up and explore the server-side of JS.

Okay, it’s not THAT distressing of a ride.

This State of Node.js article from a few months ago was a good introduction, but today I’m going to focus on Node.js for e-commerce.

I’ll first expose what Node can bring to your online store and the ecosystem’s e-commerce tools.

Then I’ll craft my own demo shop using the neat Node.js framework that is Koa.js. Here are the steps we’ll follow:

  1. Initializing the Koa.js app directory.
  2. Creating the app’s entry point.
  3. Reading products data.
  4. Setting up Koa.js routes.
  5. Enabling e-commerce capabilities on your Node.js app

Ready for this?

Why use Node.js for e-commerce?

Node.js is a JavaScript runtime built on Chrome’s V8 JS engine. It uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.

A few of its features make it an excellent choice for your next e-commerce project:

It’s JavaScript, and JavaScript is everywhere.

If you ever want to use one of the many popular JS frameworks for your store’s frontend, a Node.js backend makes it easy to find code universality across your stack. Plus, it’s widely used for server-side rendering to solve JavaScript single page apps SEO issues.

Going with a JavaScript full stack, you can write an e-commerce web app that renders both on the browser and the server seamlessly.

It scales when your business needs it.

You’re totally in charge of your Node.js backend configuration. Whatever functionalities you need for a store’s backend, you select and add the necessary modules. On this matter, you shouldn’t be scared to miss any piece as npm is the widest software registry out there.

It’s more popular than ever.

If you’re a business owner, you’ll never have any problem filling your development team with resourceful Node.js developers.

If you’re a single developer working on a small e-commerce client project, you’ll find all the help you need from the vast Node.js community.

And then, there’s the wide choice of tools available.

Node.js e-commerce tools

There are quite a lot of noteworthy e-commerce solutions in the Node.js ecosystem.

  • Total.js’ Eshop Total.js is a full-featured Node.js framework with its built-in e-commerce solution. It can be a good option if you’re ready to adopt the framework as a whole.
  • Reaction Commerce An open-source, real-time e-commerce platform that plays nicely with React. It’s mostly based on Meteor though, so advanced knowledge of the framework is needed here if you want to customize it. (Gotta admit, that website’s design is dope!)
  • Prime Fusion An Express.js e-commerce platform built on the MEAN stack (Mongo, Express, Angular, Node). It resides behind an API layer which means you can attach it to any frontend framework for templating and theming. It’s open-source, but at the same time maintained by a team providing regular updates.
  • Cezerin Cezerin is a React & Node.js based e-commerce platform for progressive web apps.
  • Spurt Commerce This one offers a Node.js e-commerce backend as well as Angular storefronts. It’s still in its first version though and doesn’t have a whole lot of built-in features.

As you can see, most of the existing e-commerce solutions are dependent on Node.js frameworks.

In the following example, I’ll use Snipcart, which you can integrate within any Node.js e-commerce setup, and the Node framework Koa.js.

Koa.js + Snipcart e-commerce example

There are many great Node.js frameworks I could’ve tried here. We’ve already played with Express, but there’s Meteor, Sails.js, Nest, Hapi, Strapi & many others.

Koa.js is described as the future of Node.js, so you might understand why I got curious!

It was built by the same team behind Express in 2013, the difference being that it’s a smaller, more expressive, and more robust foundation for web applications and APIs.

The least I can say about it is that it’s minimalistic. I mean, for real.

To prove it, here’s my demo use case:

Your friend Lisa is launching a new podcast, and she needs external financing to help her get started. Among other things, she wants a fundraiser website where people can donate by either buying products or give the amount they want.

The specs for this project are:

  • It has to be live quick.
  • No need for a CMS to manage products.

Your goal for this project is to put the minimum online for your friend to get going, in record time.

Koa.js documentation is a one-pager; need I say more? It’s dead simple and embraces the “pick the tools you need” philosophy, which makes it a good fit for this project.

You’ll be selling stuff, so Snipcart’s zero friction setup will serve you well.

Technical tutorial: Node.js e-commerce with Koa.js

Pre-requisites

1. Initializing the Koa.js app directory

Let’s get started by creating your project’s directory:

Generate a package.json file with the following content:

1.2 Installing Koa.js dependencies

A quick overview of these packages:

  • koa : The core Koa.js framework used to run the web app.
  • koa-router : Maps URL patterns to handler functions.
  • koa-static : Serves static files (stylesheets, scripts).
  • koa-views : Enhances Koa's context object, allowing you to render views using the templating engine of your choice.
  • pug : The templating engine I'll use in this demo.
  • fs-extra : Provides promise support for methods of the native fs module (more on that later).
  • config : I like to use this package to centralize configuration keys.
  • nodemon : When in development, this package watches your files and restarts the app when changes are detected.

2. Creating the app’s entry point

Out of the box, Koa is nothing more than a middleware pipeline. You’ll have to build on top of that.

The app code will be placed in a file named index.js at root:

Some quick points not covered in the comments:

  • config.get() : Returns config values from app/config/default.json
  • DataLoader : Could've been simpler, but I decided to go down that path to showcase one of Koa's best features: support for async functions in middlewares. I'll get to the implementation details in the next section.

3. Reading product data

To demonstrate how Koa plays well with promises, I’ve built a simple DataLoader component that reads the content of JSON files in a directory and parses them into an array of objects.

The code below makes use of fs-extra to read the file’s content:

Note that in beefier scenarios, this could have been database or remote API calls.

This data loader class will then be used in our routes to fetch products.

4. Showing Koa.js home route

Let’s take a look at the home route now:

Simple, isn’t it? Loading all products, and passing them down to the view via Koa’s context object.

Now, I will focus on the middleware function signature. See that async keyword? It's precisely where Koa.js shines. Its support for promises allows you to write middlewares as async functions, thus getting rid of callback hell. This makes for much cleaner and readable code.

Now, here’s what to put in the home.pug template to render your products:

Notice how I am accessing the products array via model.products? That's because by default, koa-views pass the entire ctx.state object to your views. Nifty!

Each product has a “Learn More” link that takes us to /buy/some-product.

6. Enabling e-commerce on your Node.js app

What about selling these products? Before attacking the buy route, quickly add Snipcart to your layout, and you’ll be good to go:

6.1 The “buy” route

The code looks pretty similar to the home route, except I’m loading a single product:

In product.pug, add this button to hook your product definition to Snipcart:

Well done, you can now sell your products!

6.2 The “donate” route

When confirming an order, Snipcart crawls all the products URLs and validates items price to make sure nothing fishy happened to your cart. To do that, Snipcart looks at the data-item-price attribute of your buy buttons.

Now, since donation amounts are customer-driven, you’ll have to use a little trick to make it all work. You have to add the number as a query parameter in the data-item-url attribute of the buy button. Then, make sure that the value is rendered in the data-item-price attribute.

Your app must handle the amount parameter correctly, which brings us to the donate route code:

Just add an amount property to the model object and assign the query parameter to it.

Here I also used the settings.defaultDonation config value as a fallback when no query parameter is set.

Now, what about donate.pug? Define your elements as follows:

Two things to note here:

  • data-item-url is fully generated using urlWithoutQuery and model.amount
  • data-base-url will be used in the script below to recompute data-item-url dynamically at runtime

Finally, write some frontend code to hook up the donation amount input to your buy button:

With that in place, any change made to the #amount field value will update the product URL.

And you’re all set!

Live demo & GitHub repo

See the live demo here

See GitHub repo here

Closing thoughts

I enjoyed Koa very much. Its API is elegant and easy to learn. The architecture puts the developer 100% in control of what’s happening, which is nice when you want to build things the way you like. I definitely recommend this approach for any Node.js developer dealing with e-commerce.

I spent less than a day to build this demo including research around Koa.js and post-review tweaks.

To push it further, I could’ve made use of some cool community middlewares to make it more like a real production app (i.e., request caching, logging). Koa.js is a killer tool to build lean, performant and maintainable web APIs.

Liked the post? Take a second to 👏 and share it on Twitter! Hit the comments for thoughts and questions.

Originally published on the Snipcart blog and in our newsletter.

--

--