Small Stories
The code for a growing collection of very short stories on the web.


Small Stories is built using a custom static site generator written in Haskell. It is modeled in many ways after Yesod.


If you are just looking for the text of the stories, they can be found in the stories directory. The stories are written in Markdown and parsed with Pandoc.


Why build yet another static site generator? I had a few motivations:

  • Most of the other static site generators out there are basically nicer versions of Make. I didn't feel like an input → transform → output approach made much sense for the design I had in mind.1
  • I wanted to play around with Yesod but found it unsuitable for static sites (believe me, I tried).
  • I'm an intermediate Haskeller and I wanted a project to hack on.


Small Stories uses the Shakespearean templates, just like Yesod. All of the templates are in submodules of SmallStories.Component.


Components are Small Stories's take on Yesod's Widgets. They present a composable, simple abstraction around a small bit of HTML and CSS. Like Yesod's Widgets, components compose cleanly within caret brackets in Hamlet and we offer a toComponent function and accompanying typeclass that behaves much like Yesod's toWidget.

The biggest differences from Widgets:

  • While Components themselves are monadic in nature, they do not need to be run in any special monad to produce a value. Widgets are tied to Yesod's Handler monad.
  • Components are not as featureful as Widgets (yet). The two biggest omissions currently are a lack of support for Julius/JavaScript (should be extremely straightforward to add) and no way for components to set the contents of the <title> tag.

Also there is the fact that Small Stories is a static site generator and Yesod is designed to handle individual requests, so Components have a slightly different feel in that respect.

See the SmallStories.Component module for the implementation.

Static Pages

Much like Yesod, Small Stories compiles all templates and static assests directly into the binary, making it totally relocatable. In the SmallStories.Static module there is an implementation similar to Yesod's Data.FileEmbed and Yesod.Static.

We provide Template Haskell to embed all files in a particular directory. Note that the files are read at compile time, so the smallstories binary depends on only the text of the stories as input.

More Architecture Details

Small Stories is as a UNIX executable with a fairly simple set of command line flags. Command line parsing is driven by CmdArgs. The SmallStories.Main module handles this as well as assembling the pages to output.


For the moment there is a Page data type which (now) serves little purpose but to hold arguments to be passed to the fooComponent functions. It will be going away soon, hopefully. The corresponding module is SmallStories.Page.


The other main data type not already discussed above are the routing data type. Like Yesod, Small Stories leverages the Shakespearean templates to provide type safe URLs. This means that there's no way to write a link in a template that's a 404!

The SmallStories.Route module itself is not particularly interesting, but do note how the Component type is parameterized over the route type, which should make it highly reusable.

  1. The design came first before I started implementing; I prototyped it in HTML.