Skip to content
A super simple flat file generator.
Branch: develop
Clone or download
Latest commit 71f3144 Oct 15, 2018
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github Add issue template and pull request template Aug 25, 2017
bin Add a pass on a CLI for panini Nov 2, 2016
helpers Update markdown.js Jan 24, 2018
test Don't add newline after partial when loading it, fixes #125 Jul 13, 2017
.babelrc Upgrade Mocha to ES6 and scaffold out new test structure with basic test Jan 7, 2016
.gitignore Fixed Handlebars helpers feature Nov 4, 2015
.travis.yml Test Node.js 4-7 in Travis Mar 8, 2017
LICENSE updates for 2017 Jan 3, 2017
index.js Add a pass on a CLI for panini Nov 2, 2016
package-lock.json Release v1.6.2 Feb 19, 2018
package.json Bump to version 1.6.3 Oct 15, 2018 updated copy on cli and readme Jul 11, 2017


Build Status npm version Coverage Status Dependency Status

A super simple flat file generator for use with Gulp. It compiles a series of HTML pages using a common layout. These pages can also include HTML partials, external Handlebars helpers, or external data as JSON or YAML.

Panini isn't a full-fledged static site generator—rather, it solves the very specific problem of assembling flat files from common elements, using a templating language.


npm install panini --save-dev


Feed Panini a stream of HTML files, and get a delicious flattened site out the other end.

var gulp = require('gulp');
var panini = require('panini');

gulp.task('default', function() {
      root: 'pages/',
      layouts: 'layouts/',
      partials: 'partials/',
      helpers: 'helpers/',
      data: 'data/'

Note that Panini loads layouts, partials, helpers, and data files once on first run. Whenever these files change, call panini.refresh() to get it up to date. You can easily do this inside a call to['./src/{layouts,partials,helpers,data}/**/*'], [panini.refresh]);



Type: String

Path to the root folder all pages live in. This option does not pull in the files themselves for processing—that's what gulp.src() is for. This setting tells Panini what the common root of your site's pages is.


Type: String

Path to a folder containing layouts. Layout files can have the extension .html, .hbs, or .handlebars. One layout must be named default. To use a layout other than the default on a specific page, override it in the Front Matter on that page.

layout: post

<!-- Uses layouts/post.html as the template -->

All layouts have a special Handlebars partial called body which contains the contents of the page.

<!-- Header up here -->
{{> body}}
<!-- Footer down here -->


Type: Object

A list of presets for page layouts, grouped by folder. This allows you to automatically set all pages within a certain folder to have the same layout.

  root: 'src/pages/',
  layouts: 'src/layouts/',
  pageLayouts: {
    // All pages inside src/pages/blog will use the blog.html layout
    'blog': 'blog'


Type: String

Path to a folder containing HTML partials. Partial files can have the extension .html, .hbs, or .handlebars. Each will be registered as a Handlebars partial which can be accessed using the name of the file. (The path to the file doesn't matter—only the name of the file itself is used.)

<!-- Renders partials/header.html -->
{{> header}}


Type: String

Path to a folder containing Handlebars helpers. Handlebars helpers are .js files which export a function via module.exports. The name used to register the helper is the same as the name of the file.

For example, a file named markdown.js that exports this function would add a Handlebars helper called {{markdown}}.

var marked = require('marked');

module.exports = function(text) {
  return marked(text);


Type: String

Path to a folder containing external data, which will be passed in to every page. Data can be formatted as JSON (.json) or YAML (.yml). Within a template, the data is stored within a variable with the same name as the file it came from.

For example, a file named contact.json with key/value pairs such as the following:

    "name": "John Doe",
    "email": "",
    "phone": "555-1212"

Could be used to output the value of John Doe within a template using the Handlebars syntax of {{}}.

Data can also be a .js file with a module.exports. The data returned by the export function will be used.

Data can also be inserted into the page itself with a Front Matter template at the top of the file.

Lastly, the reserved page variable is added to every page template as it renders. It contains the name of the page being rendered, without the extension.


You can also use panini via the CLI.

Usage: panini --layouts=[layoutdir] --root=[rootdir] --output=[destdir] [other options] 'pagesglob'

  --layouts  (required) path to a folder containing layouts
  --root     (required) path to the root folder all pages live in
  --output     (required) path to the folder compiled pages should get sent to
  --partials            path to root folder for partials
  --helpers             path to folder for additional helpers
  --data                path to folder for additional data

the argument pagesglob should be a glob describing what pages you want to apply panini to.

Example: panini --root=src/pages --layouts=src/layouts --partials=src/partials --data=src/data --output=dist 'src/pages/**/*.html'

Local Development

git clone
cd panini
npm install

Use npm test to run tests.

You can’t perform that action at this time.