Metalsmith – static site generator


Past weekend I spent playing with Metalsmith, which is an extremely simple, pluggable static site generator, written in JavaScript. This means package’s only responsibility is copying files from source to destination folder and in a process applying pluggable transformations to those files via external plugins (if you’ve ever used Gulp, this will look familiar to you).

Here is minimal, but useless example, because only thing it does is transferring files from src folder in current directory to build folder (which are default names).

var metalsmith = require('metalsmith');

metalsmith(__dirname)
    .build();

Things start to get interesting if we are writing in markdown and would like files to be transformed to proper HTML. Simple, we just install and require metalsmith-markdown and plug it into our app via .use() method.

var metalsmith = require('metalsmith'),
    markdown = require('metalsmith-markdown');

metalsmith(__dirname)
    .use(markdown())
    .build();

In my 2-days experiences of building static website with metalsmith, I found those plugins essential ((I also found out that the order of used plugins is very important.)):

  • metalsmith-markdown
    As mentioned, it transforms files from markdown format to HTML format.
  • metalsmith-templates
    Use templates/layouts for a file. You specify which template/layout to use by adding template key in file’s YAML front-matter
  • metalsmith-collections
    Group files by a pattern or specifying a collection key in file’s YAML front-matter.
  • metalsmith-permalinks
    Changes filename hierarchy so that conforms to desired urls. For example, it can change about.html to about/index.html.

Most plugins are built in a way that they accept configuration object and return a callback with 3 arguments – collection of files, metalsmith object and a done callback. The most interesting one is files, which is an object with filename as a keys and filename’s (YAML front-matter, content,…) data as a value and where plugins’ transformations are applied.

I used collections plugin in conjunction with permalinks plugin and immediately wasn’t satisfied with former one, since I wanted to have different permalinks per collection. So I forked this plugin on GitHub and applied desired logic. It can be found here. In a process I also learned you can use as a dependency a npm package hosted in public git repo. Instructions can be found here.