Need help with wintersmith?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

3.5K Stars 346 Forks MIT License 470 Commits 15 Opened issues


A flexible static site generator

Services available


Need anything else?

Contributors list


Wintersmith is a simple yet flexible static site generator. It takes contents (markdown, less, scripts, etc), transforms them using plugins and outputs a static website (html, css, images, etc) that you can host anywhere.

It ships with plugins for markdown and pug templates, if you need something else check the plugin listing or write your own!



First install wintersmith using npm:

$ npm install wintersmith -g

This will install wintersmith globally on your system so that you can access the

command from anywhere. Once that is complete run:
$ wintersmith new 


 is the location you want the site to be generated. This creates a skeleton site with a basic set of templates and some articles, while not strictly needed it's a good starting point.

Now enter the directory and start the preview server:

$ cd 
$ wintersmith preview

At this point you are ready to start customizing your site. Point your browser to

and start editing templates and articles.

When done run:

$ wintersmith build

This generates your site and places it in the

directory - all ready to be copied to your web server!

And remember to give the old

a look :-)


A wintersmith site is built up of three main components: contents, views and templates.

Contents is a directory where all the sites raw material goes (markdown files, images, javascript etc). This directory is then scanned to produce what's internally called a ContentTree.

The ContentTree is a nested object built up of ContentPlugins and looks something like this:

  "": {MarkdownPlugin} // plugin instance, subclass of ContentPlugin
  "some-dir/": { // another ContentTree instance
    "image.jpg": {StaticPlugin}
    "random.file": {StaticPlugin}


This content tree is provided in full to the views when rendering. This gives you a lot of flexibility when writing plugins, you could for example write a plugin that generates a mosaic using images located in a specific directory.

Wintersmith comes with a default Page plugin that renders markdown content using templates. This plugin takes markdown (combined with some metadata, more on this later) compiles it and provides it to a template along with the content tree and some utility functions.

This brings us to the second component, the template directory. All templates found in this directory are loaded and are also passed to the content plugins when rendering.

By default only

templates are loaded, but you can easily add template plugins to use a template engine of your choosing.

Check the

directory for some inspiration on how you can use wintersmith or the showcase to see what others are doing.


Configuration can be done with command-line options, a config file or both. The config file will be looked for as

in the root of your site (you can set a custom path using



Default Description

contents directory location
templates directory location
views directory location, optional
global site variables, can also be a path to a json file
modules to load and add to locals. e.g. if you want underscore as
you would say
{"": "underscore"}
list of plugins to load
list of files or pattern to ignore
output directory, this is where the generated site is output when building
outputs filenames and paths according to a template. (documentation)
to get a permalink to that content

The Page plugin

Wintersmith ships with a page plugin. This plugin is what the markdown page and many other content plugins build upon.


The Page model (inherits from ContentPlugin)



metadata object containing the pages metadata


date | Date object created from
if set, unix epoch time if not rfc822date | a rfc-822 formatted string made from
body | markdown source html | parsed markdown as html

A MarkdownPage is either a markdown file with metadata on top or a json file located in the contents directory.

title: My first post
date: 2012-12-12 12:12
author: John Hjort 
template: article.pug

Hello friends!

Life is wonderful, isn't it?

or use json to simply pass metadata to a template:

  "template": "template.pug",
  "stuff": {
    "things": 123,
    "moar": [1, 2, 3]

Pages are by default rendered using the

view. This view passes the page to the template provided in the metadata. Omitting the template key or setting it to
will cause the page not to be rendered.


All relative links in the markdown will be resolved correctly when rendering. This means you can just place image.png in the same directory and simply include it in your markdown as

![my image](image.png)

This is especially convenient when using a markdown editor (read Mou if you're on a mac).


Metadata is parsed using js-yaml and will be accessible in the template as


There are two special metadata keys, The first one is

which specifies what template to render the page with. If the key is omitted or set to
the page will not be rendered (but still available in the content tree).

The second one is

which can be used to override the output filename of the page. See filename templating for advanced usage.


When a page is rendered to a template the page instance is available as

in the template context. The content tree is also available as
is the root object.


A plugin is a function that's called with the wintersmith environment and a callback.

Plugins are loaded by adding a "require id" to

. This can be a path, local- or global module. It works just like you would expect a
call to.

Plugin example:

fs = require 'fs'

module.exports = (env, callback) ->

class SimonSays extends env.ContentPlugin

constructor: (@filepath, text) ->
  @text = "Simon says: #{ text }"

getFilename: -> @filepath.relative # relative to content directory

getView: -> (env, locals, contents, templates, callback) ->
  callback null, new Buffer @text

SimonSays.fromFile = (filepath, callback) -> fs.readFile filepath.full, (error, buffer) -> if error callback error else callback null, new SimonSays filepath, buffer.toString()

env.registerContentPlugin 'text', '*/.txt', SimonSays callback() # tell the plugin manager we are done

See the plugin guide for more info.

Using wintersmith programmatically


var wintersmith = require('wintersmith');

// create the sites environment, can also be called with a config object. e.g. // {contents: '/some/contents', locals: {powerLevel: 10}}, ..} var env = wintersmith('/path/to/my/config.json');

// build site { if (error) throw error; console.log('Done!'); });

// preview env.preview(function(error, server) { if (error) throw error; console.log('Server running!'); });

// do something with the content tree env.load(function(error, result) { if (error) throw error; console.log('Contents loaded!'); });

Check the source or api docs for a full list of methods.


To run a development that compiles the coffee script files on the fly use the

command. The chdir
flag is handy for pointing it to a test project to experiment with.


Wintersmith is written by Johan Nordberg using CoffeeScript and licensed under the MIT-license.

The name is a nod to blacksmith which inspired this project.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.