An internal DSL for generating HTML in JavaScript
Switch branches/tags
Nothing to show
Clone or download
Latest commit 6149549 May 15, 2013
Failed to load latest commit information.
lib Ensure that we have the correct toString reference May 15, 2013
test first commit Mar 27, 2013
.gitignore added .gitignore Mar 27, 2013
LICENSE added LICENSE and updated package.json Mar 27, 2013 fix typo in README Mar 30, 2013
package.json bump version May 15, 2013


An internal DSL for generating HTML in JavaScript.


Basic elements

html.div('#main', [
    html.h1(null, 'Hello, world!'),
    html.img({src: 'foo.jpg'})
<div id="main">
    <h1>Hello, world!</h1>
    <img src="foo.jpg"/>

Loops etc.

Using Underscore.js or similar:

function todoItem(item) {
    return{rel:}, [
        html.div('.title', item.title),
        html.button('.destroy', 'delete')

function todoList(list) {
    return html.ul('.todo-list',, todoItem));

    {id: 1, title: 'item one'},
    {id: 2, title: 'item two'},
    {id: 3, title: 'item three'}
<ul class="todo-list">
    <li rel="1">
        <div class="title">item one</div>
        <button class="destroy">delete</button>
    <li rel="2">
        <div class="title">item two</div>
        <button class="destroy">delete</button>
    <li rel="3">
        <div class="title">item three</div>
        <button class="destroy">delete</button>

Why use an internal DSL?

  • It's a more convenient and safer alternative to string contatenation
  • Very flexible, you can use all the power of JavaScript functions and control structures
  • For small bits of HTML you might not want to switch contexts from code to a template
  • Easier to debug than a templating engine
  • You get full tool-chain support:
    • editor support: syntax highlighting, code tools etc etc
    • code analyzers: jslint, jshint
    • testing/coverage tools

When to use?

  • Consider using where you might currently use string concatenation
  • Avoid using for large HTML documents or in places where speed is critical
  • Good for small snippets used for client-side page updates
  • Bad for generating huge amounts of HTML on the server


I like to alias the 'pithy' library as 'html':

var html = require('pithy');

You can then just use html.tagname as a function to create the appropriate element. Please note, you actually get a html.SafeString object back, not a native JavaScript String. This might mess up your isString() tests. If you have a workaround please send a pull-request.

There is also a html.escape() function for escaping HTML (returns a html.SafeString). It will not escape a value that is already a html.SafeString object.