Static HTML sites with Markdown and Metalsmith


The language in which all websites and web apps are being presented on the web browsers is HTML.

This markup language is what web browsers read, understand and render. In addition to HTML, web applications usually have dedicated JavaScript code and style files.

Many web sites are dynamic with HTML and corresponding assets generated dynamically, by the web server backend application.

Recently, static web sites started to gain popularity.

Static web site means that all HTML and Javascript required by web browser to render are statically generated and will not change.

Which brings many benefits for web site performance – most of the content can be cached and is loaded by browser very fast.

Such pages do not change, you dont need the backed server. Hence the name – static websites.

Because of this nature, static web sites can be served from multiple platforms which allow content sharing. Examples would be GitHub pages or even DropBox.

Generating static HTML websites

What are most common ways of generating static HTML websites?

You can, of course, create and maintain your static website pages in HTML language itself.

However, being a markup language, HTML is hard to read for humans.

The most popular solution is to maintain your static pages in the language like Markdown. Markdown is easy to read for humans and multiple static site generators exist, who convert it to HTML pages automatically.

In this tutorial, we are going to show you one of such static site generators – Metalsmith. You will learn how to setup and configure  simple static web site.

MobileGap – the list of open source mobile applications

MobileGap is a simple web application we have created to maintain the list of open source mobile app projects. The first version of was quickly put together by using existing WordPress template we had lying around.

But, as the number of developers asking to add their open source applications to the list grew, we decided to open source the content creation of this website. The good option for such setup was to maintain website content in Markdown language, generate HTML markup from it and move generated HTML files to be served by the web server. Markdown pages should be hosted on a publically accessible repository like GitHub.

Now, everyone wishing to add their application to the list only has to issue a GitHub pull request to MobileGap GitHub project in order to update the pages.

How did we set it up?

Maintain static HTML websites with Markdown and Metalsmith

We are using simple static site generator to convert Markdown pages to HTML markup.

Now let’s reference the current project structure of source code for generating static HTML websites

Metalsmith is NodeJS module and requires NodeJS to be installed on the system. Let’s go through the files in the project.

package.json is a packaging file for Node applications. It has a list of dependencies which application relies on in the dependencies section. The contents of the file are the following:

 "name": "",
 "version": "0.1.0",
 "description": "MobileGap - open source mobile application directory",
 "main": "index.js",
 "repository": { 
 "type" : "git",
 "url" : ""
 "dependencies": {
 "handlebars": "^4.0.5",
 "metalsmith": "^2.1.0",
 "metalsmith-markdown": "^0.2.1",
 "metalsmith-templates": "^0.7.0"
 "author": "",
 "license": "MIT"

Dependencies section lists few npm packages our project relies on. Metalsmith core is simplistic and minimal, and in order to use Markdown or templating functionality, we have to list these specific Metalsmith modules. There is also a handlebars module, which helps to setup templates.

Other sections of the file provide information about the project. If you want to understand the structure of a packaging file for NodeJS projects, check the official documentation.

Run npm install on your system and npm package manager (it comes together with NodeJS installation) will download all the project dependencies.

Now let’s look at index.js

var Metalsmith = require('metalsmith'),
 markdown = require('metalsmith-markdown'),
 templates = require('metalsmith-templates'),
 Handlebars = require('handlebars'),
 fs = require('fs');

 Handlebars.registerPartial('header', fs.readFileSync(__dirname + '/templates/partials/header.hbt').toString());
 Handlebars.registerPartial('footer', fs.readFileSync(__dirname + '/templates/partials/footer.hbt').toString());

 .build(function (err) { if(err) console.log(err) })

In you are familiar with NodeJS applications, this file doesn’t look very complex. First, we retrieve all the required modules. Then we are registering partials for Handlebars templates. This allows us to keep shared header and footer for all pages.

Next, we setup Metalsmith static site generator, with Metalsmith(..) providing it the location to a current directory and instructing to use Handlebars templates, use markdown directory as a source and directory as a destination for generated HTML files.

Last step is build(). We are catching and logging any errors which might happen during the build process.

As you might have already guessed, Markdown files are located in markdown directory, template files are located in templates. We like simplicity.

Now, if you run node index.js all Markdown files from markdown directory will be converted to HTML using the template and partials from templates directory. The resulting HTML files are created in directory. Metalsmith will delete the old HTML files before creating new ones by default. By default Metalsmith will copy all other files (styles, JavaScript) from a source directory to destination directory as they are.

What’s left is to move generated HTML files to your web server. In the next part of this post, I’ll describe the process we use to employ continuous integration to automate the generation of static HTML websites after new code changes are merged to GitHub repository.

6 Responses

  • Rakhi Sharma

    Thanks for sharing, very helpful!

  • np, glad you found this useful!

  • Brian Califano

    Very helpful. Markdown is indeed very easy to edit in a normal text editor. Metalsmith is also easy to get started and does support a wide range of templates and data format options. The plug-in architecture is also simple and lightweight.

  • Satya Prakash

    Thanks for sharing

  • Jonathan Doherty

    Thanks for sharing with us this useful information.

  • TCrowd

    Thanks for helpful article.