node package manager


Template rendering middleware for koa


Template rendering middleware for koa.

Note: This master branch is for koa's upcoming version koa@2. Take a look at the v1.x branch for koa@1.

$ npm install koa-views@next

koa-views is using consolidate under the hood.

List of supported engines

var views = require('koa-views');
// Must be used before any router is used 
app.use(views(__dirname + '/views', {
  map: {
    html: 'underscore'
app.use(async function (ctx, next) {
  ctx.state = {
    session: this.session,
    title: 'app'
  await ctx.render('user', {
    user: 'John'

For more examples you can take a look at the tests.

  • root: Where your views are located. Must be an absolute path. All rendered views are relative to this path
  • opts (optional)
  • opts.extension: Default extension for your views

Instead of providing the full file extension you can omit it.

app.use(async function (ctx) {
  await ctx.render('user.jade')


app.use(views(__dirname, { extension: 'jade' }))
app.use(async function (ctx) {
  await ctx.render('user')
  • Map a file extension to an engine

In this example, each file ending with .html will get rendered using the nunjucks templating engine.

app.use(views(__dirname, { map: {html: 'nunjucks' }}))
// render `user.html` with nunjucks 
app.use(async function (ctx) {
  await ctx.render('user.html')
  • opts.options: These options will get passed to the view engine. This is the time to add partials and helpers etc.
const app = new Koa()
  .use(views(__dirname, {
    map: { hbs: 'handlebars' },
    options: {
      helpers: {
        uppercase: (str) => str.toUpperCase()
      partials: {
        subTitle: './my-partial' // requires ./my-partial.hbs 
  .use(function (ctx) {
    ctx.state = { title: 'my title', author: 'queckezz' }
    return ctx.render('./my-view.hbs')

Set the DEBUG environment variable to koa-views when starting your server.

$ DEBUG=koa-views