Bundle splitting with HTTP2 push support for Choo with choo-ssr
Last updated 3 years ago by diffcunha .
MIT · Repository · Bugs · Original npm · Tarball · package.json
$ cnpm install choo-bundles 
SYNC missed versions from official npm registry.


Bundle splitting with HTTP2 push support for choo-ssr (server-side rendering with Choo).

Requires choo-async.

Lazy load the parts of your app that are not immediately used, to make the initial load faster.

This module works without a compile step on the server, and in the browser with the browserify plugin.

Usage - Install - Plugin CLI - Plugin API - License: MIT

stability standard


This plugin exposes a load function on a bundles object in the Choo instance:

// app.js
const choo = require('choo')
const ssr = require('choo-ssr')
const async = require('choo-async')
const bundles = require('choo-bundles')

const home = require('./views/home')
const notfound = require('./views/notfound')

function main () {
  const app = async(choo())

  const page = view => (


  app.route('/', page(home))
  app.route('/lazy', page(lazy))
  app.route('*', page(notfound))

  async function lazy (state, emit) {
    const view = await app.bundles.load('./views/lazy')
    return view(state, emit)

  return app

if (typeof window !== 'undefined') {

module.exports = main
// server.js
const path = require('path')
const fastify = require('fastify')()

fastify.register(require('fastify-static'), {
  root: path.join(__dirname, 'build'),
  prefix: '/build'

fastify.register(require('choo-ssr/fastify'), {
  app: require('./app'),
  plugins: [[
    require('choo-bundles/ssr'), {
      manifest: path.resolve(__dirname, 'build/manifest.json'),
      bundles: [{
        name: 'common',
        js: '/build/bundle.js'

fastify.listen(8080, function () {
  console.log('listening on 8080')
// build.js
const fs = require('fs')
const path = require('path')
const browserify = require('browserify')

  .plugin(require('choo-bundles/browserify'), {
    output: path.resolve(__dirname, 'build'),
    manifest: path.resolve(__dirname, 'build/manifest.json'),
    prefix: '/build'

This will split the loaded files into their own bundles so they can be dynamically loaded at runtime. In this case, a common bundle would be created including choo, choo/html, choo-bundles and the file above. A second bundle will be created for the lazyView.js file and its dependencies.

See examples for more


npm install choo-bundles

Browserify Plugin

Works with Browserify v16 and newer

CLI Usage

browserify ./app.js -p [ choo-bundles/browserify --output ./bundles/ --manifest ./bundles/manifest.json ]
  > ./bundles/common.js



Set the output directory for dynamic bundles. Use a folder path to place dynamic bundles in that folder.

The default is ., outputting in the current working directory.


Set the output path for manifest file.

The default is ./bundles.manifest.json, outputting in the current working directory.


Filename for the dynamic bundles. You must use %f in place of the bundle id

-p [ choo-bundles/browserify --filename bundle.%f.js ]

Defaults to bundle.%f.js, so the filename of dynamic bundle #1 is bundle.1.js.


URL prefix for the dynamic bundles.

Defaults to /, so the URL of dynamic bundle #1 is /bundle.1.js.

API Usage

var bundles = require('choo-bundles/browserify')

  .plugin(bundles, {
    output: '/output/bundles',
    manifest: '/output/manifest.json',



Set the output directory for dynamic bundles, if a string is passed.

Also accepts a function that returns a stream and takes filename as argument. The dynamic bundle will be written to the stream:

b.plugin(bundles, {
  output: filename => fs.createWriteStream(`/output/bundles/${filename}`)

Defaults to ..


Set the output path for manifest file, if a string is passed.

Also accepts a function that takes manifest object as argument:

b.plugin(bundles, {
  manifest: manifest => fs.writeFileSync('/output/manifest.json', JSON.stringify(manifest))

Defaults to ./bundles.manifest.json


Filename for the dynamic bundles. If string is passed you must use %f in place of the bundle id.

Also accepts a function that takes the entry point entry as argument:

b.plugin(bundles, {
  filename: entry => 'bundle.' + entry.index + '.js'

URL prefix for the dynamic bundles.

Defaults to /, so dynamic bundle #1 will have /bundle.1.js as URL.


b.on('choo-bunldes.pipeline', function (pipeline, entry, filename, manifest) {})

choo-bunlde emits an event on the browserify instance for each pipeline it creates.

pipeline is a labeled-stream-splicer with labels:

entry is the browserify row object for the entry point of the dynamic bundle. filename is the name of the dynamic bundle file. manifest is an object with an add function to add entries to the manifest

b.on('choo-bundles.pipeline', function (pipeline, entry, filename, manifest) {
  manifest.add('css', '/' + filename.replace('.js', '.css')) // URL of the CSS file
  pipeline.get('pack').unshift(extractcss(`/output/bundles/${filename.replace('.js', '.css')}`))


Browserify plugin heavily inspired on @goto-bus-stop's split-require



Current Tags

  • 0.2.4                                ...           latest (3 years ago)

7 Versions

  • 0.2.4                                ...           3 years ago
  • 0.2.3                                ...           3 years ago
  • 0.2.2                                ...           3 years ago
  • 0.2.1                                ...           3 years ago
  • 0.2.0                                ...           3 years ago
  • 0.1.1                                ...           3 years ago
  • 0.1.0                                ...           3 years ago
Maintainers (1)
Today 0
This Week 0
This Month 1
Last Day 0
Last Week 0
Last Month 0
Dependencies (26)
Dev Dependencies (1)
Dependents (0)

Copyright 2014 - 2016 © |