Skip to content
This repository has been archived by the owner. It is now read-only.
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

portent: perfect websites

Build Status Dependency Status Codacy Badge Code Climate bitHound Score

Simple best-practices static website generator.

Quick start

Run npm install --save portent, then add two scripts to your package.json:

"scripts": {
	"start": "portent run .",
	"build": "portent build .",
	"deploy": "portent deploy . my-ssh-server:path/to/destination"

Then create a pages directory, maybe a few more files as described below, run npm start and start editing and using your website.

File hierarchy convention

The website project directory should look as follows:


Anywhere in the tree files and directories prefixed with an _ are ignored.

The structure above will produce a website that responds to URLs / and /about.

Page structure

pages directory contains actual routes for pages in the website. Every html file inside is a single URL route. Pages with Unicode names do not work perfectly, but if they work for you, great.

It is recommended to include a tag in every template and refer to files and URLs relative to the root of the project, without using a leading slash. For example, to link from projects/foo to about, use a string about, not ../about. A workflow different from this has undefined behavior.

If pages contains a file transform.js, it will be used to modify HTML programatically:

module.exports = function(path, $){
  $.root().append('Hello, world');


errors directory contains templates for HTTP errors.


All CSS are combined and included in your HTML.

To refer to images, use url('foo.png') syntax, where the images are located in the same directory as your CSS file, or deeper with url('foo/bar.png').

If a file ends in .less, it will be processed with LESS. Take care to ensure your submodules are hidden behind an _ name, or else they will be included twice.

If a file ends in .ie9.css or ie9.less (or ie 8), the files will be conditionally connected only in Internet Explorer.


Portent includes a base stylesheet that promotes some best practices. Import it using @import 'portent/base.less'.


All JavaScript files are combined and included in your HTML.

If a file ends in .min.js, it will not be processed, but included as is in a separate bundle and will run before your regular scripts.

If a file ends in .cjs.js, it will be Browserified. Take care to ensure your submodules are hidden behind an _ name, or else they will be included twice.


HTML files are processed using nunjucks templating syntax (version 2) that is primarily useful for its extends tag.


Portent includes a base template for HTML websites that promotes best practices in HTML authoring. Use it by extending in your templates with {% extends "portent/base.html" %}, and then defining blocks and variables as follows:

{% extends "portent/base.html" %}

{% block title %}
	Document title
{% endblock %}

{% block head %}
	<meta name=description content="">
	<link rel=stylesheet href="">
{% endblock %}

{% block body %}
	<header>Website-generic content</header>
	    Include new custom blocks for further extending:
	    {% block content %}{% endblock %}
{% endblock %}

If your website is non-English, make sure to set the language with a {% set lang='XX' %} anywhere in the template.

Set a theme color for your website to use whenever it is possible to customize browser chrome with {% set themeColor='blue' %}. Any CSS color or syntax works.


Images in img will become part of your website.

If a file favicon.png is present in the root of your images directory, it will be added to your website as a proper favicon, resized and included in HTML. It is recommended to have the base favicon in at least the 196x196 size.


Everything in static will become part of your website. Use this to host fonts, videos, other resources of the sort.


Development server

To develop your website, run a development server in the terminal: portent run . or in Node: portent(directory).server.listen(port).

Building for production

To build the website for production, use portent build ., or in Node portent(directory).build(destination, { onWarning: console.log.bind(console) }).


To deploy the website, portent exposes a nicer way to use rsync on your machine. Run portent deploy . ssh-server:path/on/remote/.


Simple best-practices static website generator



No packages published