
Product
Socket for Jira Is Now Available
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.
@bark/koa-handlebars
Advanced tools
Render HBS files in your Koa apps with autoloaded helpers and partials
npm i @bark/koa-handlebars handlebars fs-jetpack
koa-handlebars is BYOFS (Bring-your-own-file-system). If you have a different fs implementation that is api-compatible with fs-jetpack, you can use that instead and provide it to the jetpack option when creating your renderer
The primary use case for this module is to act as a Koa middleware. This means that you will need to app.use it somewhere in your middleware stack. This will add a ctx.render function that can be used to render templates in one
of your app's controllers.
const Koa = require('koa')
const hbs = require('@bark/koa-handlebars')
const path = require('path')
const app = new Koa()
// ... Other Middleware ...
app.use(hbs(path.join(__dirname, 'views'))) // <-- Mount the middleware
// ... More Middleware ...
router.get('web.projects.list', '/projects', async ctx => {
const currentUser = await getCurrentUser()
const projects = await getProjectsSomehow(currentUser)
await ctx.render('projects/list-projects', { // <-- Call 'ctx.render' with your template name and data
user: currentUser,
projects,
})
})
You might sometimes need to access the fully configured renderer outside of your request/response flow (e.g. async job queue handlers). Koa-handlebars exposes a method for creating a ctx-independent renderer with the same set of options as the middleware version.
const path = require('path')
const { cwd } = require('process')
const { createRenderer } = require('@bark/koa-handlebars')
const renderer = createRenderer(path.join(cwd(), 'views')))
const output = await renderer.render('mailers/users/password-reset', {
name: 'Schmoopy',
token: '123',
action_url: 'https://example.com/reset-password?token=123'
})
This module exposes two functions, both of which have the same parameters. One function creates a koa middleware that attaches a render method to ctx (see above usage). The other creates a Renderer object with a render method. Both render methods take the same parameters
The base path that the render method will append template names to in order to find a template file. Unless the helper and partial paths are customised, koa-handlebars will expect the folder found at this path to also contain folders named helpers and partials
An object that can be used to customise the behaviour of the koa-handlebars renderer
Default: process.env.NODE_ENV === 'production'
When set to true, the renderer will store the parsed template file in an internal cache. This does not store the result
of using a template; rather, the file is loaded from disk, parsed by Handlebars and then stored in the cache before being used. Subsequent calls to render the same template will use the cached template instead of having to hit the filesystem and re-parse the template file.
This behaviour may be undesirable if you are iterating on your templates, or if you have a large number of templates that might take up a lot of memory when cached.
Default: ".hbs"
The extension that koa-handlebars will append to the name of a template in order to find the template file. Using the default settings, a call to renderer.render('users/profile') would render <root>/users/profile.hbs.
Default: "partials"
The name of the folder holding your partials, relative to the root path. Using the default settings, the following handlebars expression will render the template found at <root>/partials/user-footer.hbs
<!-- Some content -->
{{> user-footer }}
<!-- Some other content -->
Default: "helpers"
The name of the folder holding your helper functions, relative to the root path. koa-handlebars will require every file in this folder to look for helpers. See below for more information about how to write a helper file in a way that is compatible with koa-handlebars
Default: (inst) => inst
A simple hook that allows you to directly access and modify the underlying Handlebars instance. This function is called at the end of the configuration process after partials and helpers have been registered. The extend function must return a handlebars instance (or another api-compatible object), but this does not imply that it has to be the handlebars instance passed to the extend function.
Default: require('fs-jetpack')
The filesystem instance that koa-handlebars will use for all filesystem operations. This should either be an instance of fs-jetpack, or some other api-compatible object. If you are providing your own implementation, you do not need to install the fs-jetpack dependency.
This is the path to the template file, relative to the root option provided to the constructor, and without the file extension. If the template does not exist, ctx.render will set the response status to 404 with no response body; renderer.render will simply return null
This object holds data that will be made available to the Handlebars template. This is passed directly to the Handlebars instance without modification.
This object holds options for the underlying Handlebars instance. This is passed directly to the Handlebars instance without modification; check the Handlebars documentation for more information.
Helpers are javascript functions that can perform some sync processing and return data to be interpolated into a template. By default, koa-handlebars will look at every file in the <root>/helpers directory for functions to load. Helpers can be exported in one of two ways: one helper per file, or helper bundles.
If you have one helper per file, the name of the file will be registered as the name of your helper function, and your file should look something like this:
// <root>/helpers/current_year.js
const Handlebars = require('handlebars')
module.exports = function showCurrentYear() {
const date = new Date()
return new Handlebars.SafeString(String(date.getFullYear()))
}
If you have multiple helpers per file, every exported name will be registered as a helper function, where the helper function name matches the exported name. You file should look something like this:
// <root>/helpers/utilities.js
const Handlebars = require('handlebars')
exports.current_year = function showCurrentYear() {
const date = new Date()
return new Handlebars.SafeString(String(date.getFullYear()))
}
exports.ifenv = function(name, compare, options) {
if (options == null) {
options = compare
compare = null
}
const value = process.env[name.toUpperCase()]
if (value === compare) {
return options.fn(this)
} else {
return options.inverse(this)
}
}
Both of the above ways of registering helpers will allow the following code to work:
<div class="footer">
Copyright 1970 - {{# current_year }}
</div>
The second example will also allow the following to work:
{{#ifenv "node_env" "production"}}
<script type="application/javascript" src="https://example.com/cdn/my-crm-widget.js"></script>
{{else}}
<script type="application/javascript" src="https://example.com/cdn/my-debug-tools.js"></script>
{{/ifenv}}
FAQs
Render hbs files in your koa apps with autoloaded helpers and partials
We found that @bark/koa-handlebars demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.