diff --git a/spec/stdlib/template/builder-spec.coffee b/spec/stdlib/template/builder-spec.coffee
new file mode 100644
index 000000000..4d552cd2c
--- /dev/null
+++ b/spec/stdlib/template/builder-spec.coffee
@@ -0,0 +1,16 @@
+Builder = require 'template/builder'
+
+fdescribe "Builder", ->
+ builder = null
+
+ beforeEach -> builder = new Builder
+
+ describe ".tag(name, args...)", ->
+ it "can generate simple tags", ->
+ builder.tag 'div'
+ expect(builder.toHtml()).toBe("
")
+
+ builder.reset()
+ builder.tag 'ol'
+ expect(builder.toHtml()).toBe("
")
+
diff --git a/src/stdlib/template/builder.coffee b/src/stdlib/template/builder.coffee
new file mode 100644
index 000000000..ce3b7964c
--- /dev/null
+++ b/src/stdlib/template/builder.coffee
@@ -0,0 +1,25 @@
+_ = require 'underscore'
+OpenTag = require 'template/open-tag'
+CloseTag = require 'template/close-tag'
+
+module.exports =
+class Builder
+ constructor: ->
+ @reset()
+
+ toHtml: ->
+ _.map(@document, (x) -> x.toHtml()).join('')
+
+ tag: (name) ->
+ @openTag(name)
+ @closeTag(name)
+
+ openTag: (name) ->
+ @document.push(new OpenTag(name))
+
+ closeTag: (name) ->
+ @document.push(new CloseTag(name))
+
+ reset: ->
+ @document = []
+
diff --git a/src/stdlib/template/close-tag.coffee b/src/stdlib/template/close-tag.coffee
new file mode 100644
index 000000000..3e4874dfc
--- /dev/null
+++ b/src/stdlib/template/close-tag.coffee
@@ -0,0 +1,7 @@
+module.exports =
+class CloseTag
+ constructor: (@name) ->
+
+ toHtml: ->
+ "#{@name}>"
+
diff --git a/src/stdlib/template/open-tag.coffee b/src/stdlib/template/open-tag.coffee
new file mode 100644
index 000000000..c913728b9
--- /dev/null
+++ b/src/stdlib/template/open-tag.coffee
@@ -0,0 +1,7 @@
+module.exports =
+class OpenTag
+ constructor: (@name) ->
+
+ toHtml: ->
+ "<#{@name}>"
+