Get the rocks out of your socks! Assemble makes you fast at web development

  • By Assemble
  • Last update: Dec 30, 2022
  • Comments: 16


NPM version NPM monthly downloads Build Status Gitter

Looking for the grunt plugin? Please visit grunt-assemble.

(Note that the current website, is for grunt-assemble. Thanks for your patience while we work on updating the site with documentation for the latest assemble).


(Click the following sections to expand them)

Table of contents

(TOC generated by verb using markdown-toc)

What is Assemble?

Assemble is a command line tool and developer framework for rapid prototyping, static site generation, and much more.

Who uses assemble?

Assemble is used by thousands of developers and teams in more than 170 countries! Here are a few examples of sites built with assemble:

Is your website, blog or project built with assemble? Please let us know about it!

Why should I use assemble?
  • Expressive, functional API (the API is also stable)
  • You can use assemble with any web framework or CSS/HTML toolkit
  • Assemble can build static sites or hybrid static/dynamic sites
  • Streams support, you can run any gulp plugin
  • Powerful features for rapid web development, including a robust API for rendering templates with any node.js template engine.
  • Assemble can use any base plugin
  • Assemble can do anything Jekyll does, but with more flexibility and control
  • Like gulp, assemble can also run any other static site generator as a plugin, which means you can do anything and everything all other node.js static site generators can do, and much more.
What can I do with Assemble?
Rapid development toolkit

Assemble can be used standalone, but it's even more powerful when used alongside the following libraries:

  • generate: scaffold out new projects from the command line
  • assemble: <= you are here
  • verb: generate documention for your projects
  • update: keep your projects up-to-date

Here are just a few of the features assemble offers:


Installing assemble

Add assemble your project's devDependencies using npm:

$ npm install -D assemble

You should now be able to run assemble directly (using node assemblefile.js etc) or using npm scripts. For example, add the following to package.json:

  "scripts": {
    "build": "assemble"

Then run

$ npm run build

Installing assemble's CLI

You can also assemble's CLI globally, which adds the assemble command to your system path, allowing it to be run from any directory.

$ npm install --global assemble

Note that even if assemble is installed globally, it's good practice to install it locally in every project to ensure that your projects are protected against any potentially breaking changes that might occur in assemble between development cycles.


To use assemble's CLI, you'll need to add an assemblefile.js to your project. The fastest way to do this is to run the following command:

$ assemble

If no assemblefile.js exists in the current project, assemble will ask if you want to add one. If you answer yes, assemble will then generate a basic assembfile.js for you.


Run assemble from the command line.

$ assemble <tasks> [options]

Running tasks

Specify one or more space-separated tasks to run.


Run task foo

$ assemble foo

Run tasks foo and bar

$ assemble foo bar

Specifying options

Non-task options are prefixed with --.


Set the --cwd to run an assemblefile.js in a different directory:

$ assemble --cwd=docs

Emit views as they're loaded and log them to stderr:

$ assemble --emit=view

See more [command line options](#command line options)

Object expansion

Object-paths may be specified using dot-notation for either the key or value in a command line argument.

Additionally, assemble uses expand-object (and some custom parsing) to make it easier to pass non-trivial options and commands via command line. So all of the following formats are possible.


Boolean values:

$ assemble --foo 
# { foo: true }

Key-value pairs:

$ assemble --foo=bar
# { foo: 'bar' }

Nested booleans:

$ assemble --option=foo 
# {options: { foo: true }}

Nested key-value pairs:

$ assemble --option=foo:bar
# {options: { foo: 'bar' }}

Deeply nested key-value pairs:

$ assemble
# {options: foo: { bar: { baz: 'qux' }}}}

Or on the left-side of the =:

$ assemble
# {options: foo: { bar: { baz: 'qux' }}}}

Command line options


Change the cwd for the assemblefile.js to run, optionally specifying any tasks to run:

$ assemble <tasks> --cwd [directory]


To run the scaffolds example in the examples/ directory, you would enter:

$ assemble --cwd examples/scaffolds

If successful, in the command line, you should see something like this:

screen shot 2016-01-09 at 1 35 52 pm


Specify the name of the config file for assemble's CLI to run, the default is assemblefile.js.


$ assemble --file



Create an assemble app. This is the main function exported by the assemble module.


  • options {Object}: Optionally pass default options to use.


var assemble = require('assemble');
var app = assemble();

Templates API

Assemble exposes the entire API from the templates library for working with templates and template collections. The API is much more extensive than what is documented here, see templates for more documentation.

Templates and Views

In the following documentation, the terms "template" and "view" both refer to aspects of the same thing. Here's what they mean:

  • template: an actual template string
  • view: a object with a content property that contains the template string. Since views are instances of vinyl, you can think of a view as a "vinyl file for templates".


Create a template collection for caching views:

app.create('includes', {viewType: 'partial'});


  • cwd {String}: the base directory to use when loading templates onto the collection from a glob

  • viewType: {String|Array}: One or more view types to associate with the collection

Add views

Add a view to the collection:

app.include('', {contents: new Buffer('this is contents')});

Add multiple views:

  path: '', contents: new Buffer('this is contents'),
  path: '', contents: new Buffer('this is contents'),
  path: '', contents: new Buffer('this is contents')

// or pass a glob (optionally override `cwd` defined on `.create`)
app.includes('*.{md,hbs}', {cwd: 'templates/includes'});

View types

View types are defined on a collection to determine how a templates in the collection will be handled throughout the [render cycle][].

Available types

Assemble supports three view types:

  • partial: Views with this type are can be used as "partials" (or "partial views"), which can be injected into other views. Useful for components, document fragments, or other snippets of reusable code or content. These views are passed to rendering engines to be used as partials, or variables on the context if partials are not directly supported.
  • layout: allows views to "wrap" other views (of any type, including other layouts or partials) with common code or content.
  • renderable: Views that have a one-to-one relationship with rendered files that will eventually be visible to a user or visitor to a website. For example: pages or blog posts. The renderable view type is automatically set if no other view types are set.

Defining view types

You can define view types when a collection is created:

app.create('snippet', {viewType: 'partial'});

Or directly on the collection options:

app.snippets.option('viewType', ['partial']); // string or array


Register template engine for rendering views with the given ext:

app.engine(ext, fn);


  • ext {String}: The file extension of files to render with the engine
  • fn {Function}: Async function that follows consolidate engine conventions, and takes three arguments: str, locals and callback.


// this engine is already registered in assemble
app.engine('hbs', require('engine-handlebars'));

// create a custom engine
app.engine('txt', function(str, locals, cb) {
  // render `str` with `locals`
  cb(null, str);

You can tell assemble to use the same engine for all file extensions by setting a value on options.engine.


// use engine `hbs` for rendering all files
app.option('engine', 'hbs');

Or, if you're using .renderFile, you can force a specific engine to be used by passing the engine name.


Use the hbs engine to render all templates:



Render a view with the given locals and callback.

app.render(view, {title: 'Foo'}, function(err, view) {
  // `view` is an object with a rendered `content` property


  • view {Object|String}: The view to render
  • locals {Object}: Locals to pass to template engine for rendering templates in view
  • callback {Function}

File System API

Assemble offers the following low-level methods for working with the file system:

Assemble has first-class support for vinyl-fs, so any gulp plugin can be used in your assemble pipeline.


Create a vinyl stream. Takes glob patterns or filepaths to the source files to read.


  • glob {String|Array}: Glob patterns or file paths to source files.
  • options {Object}: Options or locals to merge into the context and/or pass to src plugins



// define `src` options
app.src('src/*.hbs', { layout: 'default' });


Specify a destination for processed files.


  • dest {String|Function}: File path or rename function.
  • options {Object}: Options and locals to pass to dest plugins




Copy files with the given glob patterns to the specified dest.


  • patterns {String|Array}: Glob patterns of files to copy.
  • dest {String|Function}: Desination directory.
  • returns {Stream}: Stream, to continue processing if necessary.


app.task('assets', function() {
  // return, to let assemble know when the task has completed
  return app.copy('assets/**', 'dist/');


Renders files as they are pushed through the stream.


Force a specific engine to be used for rendering files:

app.engine('txt', function(str, locals, cb) {
  cb(null, str);

  .pipe(app.renderfile('txt')) //<= use engine `txt`

Task API

Assemble has the following methods for running tasks and controlling workflows:


Define a task to be run when the task is called.


  • name {String}: Task name
  • fn {Function}: function that is called when the task is run.


app.task('default', function() {


Run one or more tasks.


  • tasks {Array|String}: Task name or array of task names.
  • cb {Function}: callback function that exposes err

Example['foo', 'bar'], function(err) {
  if (err) throw err;


Watch files, run one or more tasks when a watched file changes.


  • glob {String|Array}: Filepaths or glob patterns.
  • tasks {Array}: Task(s) to watch.


app.task('watch', function() {'docs/*.md', ['docs']);


Discovering plugins

Plugins from any applications built on base should work with Assemble and can be used in your assemblefile.js:

  • base: find base plugins on npm using the baseplugin keyword
  • assemble: find assemble plugins on npm using the assembleplugin keyword
  • generate: find generate plugins on npm using the generateplugin keyword
  • templates: find templates plugins on npm using the templatesplugin keyword
  • update: find update plugins on npm using the updateplugin keyword
  • verb: find verb plugins on npm using the verbplugin keyword

Authoring plugins

Visit the plugin documentation guide to learn how to use, author and publish plugins.



Get in touch!

Have questions, suggestions, or want to discuss assemble? Join the conversation on gitter or give us a shout on twitter. The assemble team and community are always happy to help!

More information


Website is outdated and being refactored!

Assemble's website,, only has information related to gulp-assemble. We're working hard to update the site with information about the latest release.

In the meantime, you might find the WIP docs useful. The unit tests are also great examples!

Is the assemble website up-to-date?

No, as mentioned above, it's completely out-of-date. If you're using grunt-assemble, some of the documentation at might still be useful. If you're using assemble v0.6.0 and higher, the documentation is probably wrong in almost every way.

We're actively (daily) working on a refactor and it's a very high priority.

What's the difference between assemble-core and assemble?

Assemble adds a CLI, a few built-in view collections: pages, layouts, and partials, middleware for parsing front-matter, and a few other basic defaults that we've found many users expect. If you'd prefer different defaults, assemble-core is a great starting point.

If you want something that handles templates, rendering, engines, helpers, collections, etc. but you don't need to run tasks or work with the file system, then consider using templates instead of assemble-core.

I use gulp, why is it recommended to use assemble directly, instead of running assemble with gulp?

You can run gulp plugins with assemble, but it won't always work the other way around. This is because, as a build system, assemble does things that gulp doesn't do, like handle middleware.

For example, assemble's .src and .dest methods have built-in .onStream, .preWrite, and .postWrite middleware handlers. If you still wish to use gulp and your build cycle includes middleware that requires these handlers, you can use the assemble-handle plugin with gulp to ensure that the handlers are still called as needed.

This is a long way of saying, you can find ways to make gulp work, but you would just be adding an extra dependency to your project to do things that assemble already does.

What is the relationship between gulp and assemble?

Please read our gulp FAQ for more information.



Get updates on Assemble's development and chat with the project maintainers and community members.


Please read our contributing guide if you'd like to learn more about contributing to this project.

Related projects

You might also be interested in these projects from @doowb and @jonschlinkert:

  • boilerplate: Tools and conventions for authoring and using declarative configurations for project "boilerplates" that can be… more | [homepage]( "Tools and conventions for authoring and using declarative configurations for project "boilerplates" that can be consumed by any build system or project scaffolding tool.")
  • generate: Command line tool and developer framework for scaffolding out new GitHub projects. Generate offers the… more | homepage
  • scaffold: Conventions and API for creating declarative configuration objects for project scaffolds - similar in format… more | homepage
  • update: Be scalable! Update is a new, open source developer framework and CLI for automating updates… more | homepage
  • verb: Documentation generator for GitHub projects. Verb is extremely powerful, easy to use, and is used… more | homepage

Similar projects

If assemble doesn't do what you need, there are some other great open source projects you might be interested in, created by our friends on GitHub (in alphabetical order):

Static site generators

Blog frameworks

Release history

Changelog entries are classified using the following labels (from keep-a-changelog):

  • added: for new features
  • changed: for changes in existing functionality
  • deprecated: for once-stable features removed in upcoming releases
  • removed: for deprecated features removed in this release
  • fixed: for any bug fixes

Custom labels used in this changelog:

  • dependencies: bumps dependencies
  • housekeeping: code re-organization, minor edits, or other changes that don't fit in one of the other categories.

0.24.0 - 2017-05-19


  • By popular request, assemble now automatically expands config templates in yaml front-matter, via expand-front-matter! This is a feature that we had in grunt-assemble, and users let us know that they wanted it back.


  • Updated dependencies to use is-binary-buffer, which fixes a bug where isbinaryfile was trying to read from a file that didn't exist.

0.23.0 - 2017-02-11


  • Bumps assemble-core to get an update to assemble-streams that ensures that view is decorated with .toStream() when created by app (versus a collection).

0.21.0 - 2017-02-03


  • Bumps assemble-loader to v1.0.0 to take advantage of optimizations, improvements and bug fixes related to loading views


  • Regression in 0.20.0 that was causing view.stat to be null in some cases after view.path changed
  • view.base was not always correct on views that were not created from the file system

0.20.0 - 2017-02-02


  • Bumps assemble-core to v0.29.0 to take advantage of improvements to dest handling

0.19.0 - 2017-02-01


  • Bumps assemble-core to v0.28.0 to take advantage of new methods available on lists




  • bump dependencies. In particular, there was a bug in parser-front-matter where leading whitespace was removed after extracting front-matter, which caused the first line of indentation to be removed. This has been fixed.
  • Added: .log() method, which also exposes additional methods, like, .log.success(), etc.
  • docs were moved to support/docs, so that markdown docs can be built to the docs directory
  • docs were updated, new docs added
  • Moves some private prototype methods to static methods, to allow them to be used without creating an instance
  • Bumps assemble-core to v0.25.0
  • Bumps assemble-core to v0.24.0 to get the latest versions of templates and base-data which removes the renameKey option from the .data method. Use the namespace option instead.

Bumps assemble-core to v0.22.0 to take advantage of fixes and improvements to lookup methods: .find and getView. No API changes were made. Please let us know if regressions occur.

  • fixes List bug that was caused collection helpers to explode
  • Improvements to lookup functions: app.getView() and app.find()
  • Bumps base to take advantages of code optimizations.
  • Bumps assemble-core to v0.21.0. Support for the queue property was removed on collections. See assemble-core for additional details.
  • Fixes bug where glob parent was not being used for file.base, causing dest directory to be relative to cwd instead of glob parent in some cases.
  • Some changes were made to context handling that effected one unit test out of ~1,000. although it's unlikely you'll be effected by the change, it warrants a minor bump
  • Externalizes common templates tests to base-test-runner, so that assemble plugins and other base applications can use the tests
  • Includes a fix from assemble-loader, where a bug caused renameKey to not always be used when defined on collection loader options.
  • Includes fixes from templates for resolving layouts
  • Bumps assemble-core to v0.18.0, which includes a bump in templates. See the changelog on the templates library for more details.
  • debug methods and related code have been removed
  • Bumps assemble-core to v0.17.0
  • Adds support for using es6 generators with tasks
  • Bumps assemble-core to v0.15.0
  • Bumps several dependencies. No API changes, this is mostly an optimization release. Be sure to completely remove node_modules and reinstall all dependencies to avoid errors such as isRegistered is not a function
  • Stability improvements and optimizations of the API introduced in v0.6.0.
  • Major refactor. Assemble was completely re-written from the ground-up as a standalone node.js library and is no longer a grunt plugin. Grunt plugin support has been moved to grunt-assemble. Please see that repo for additional details.

(Changelog generated by helper-changelog)


Pull requests and stars are always welcome. For bugs and feature requests, please create an issue.

Please read the contributing guide for advice on opening issues, pull requests, and coding standards.

If Assemble doesn't do what you need, please let us know


Commits Contributor
1497 jonschlinkert
842 doowb
11 AndersDJohnson
7 Arkkimaagi
7 stefanwalther
4 avr
4 bendrucker
2 thegreatsunra
2 rauberdaniel
2 onokumus
2 RobLoach
2 StevenBlack
2 xzyfer
2 ain
1 asans
1 bauerca
1 caseyg1204
1 hyzhak
1 mootari
1 criticalmash
1 joonasy
1 jordanthomas
1 frayer
1 efender
1 pburtchaell
1 scmorrison
1 oncletom
1 tylerhowarth
1 klokie


Jon Schlinkert

Brian Woodward


Copyright © 2017, Jon Schlinkert. MIT

This file was generated by verb-generate-readme, v0.6.0, on December 27, 2017.



  • 1

    i18n support

    Currently looking to generate out demos in multiple languages using some string replacements and templates.

    • Strings are currently in a CSV, but can be converted to JSON
    • File names should based on the base page name + 3 letter ISO code

    Is this the right project to use or am I better off writing custom code? Also looked at, but I'm not sure how finished it is.

  • 2

    Assemble v0.6.0 Example Repos

    Hey @doowb @jonschlinkert this is David at Optimizely. I started playing around with your v0.6.0 for a personal project, with hopes of contributing and potentially porting v6 over to our marketing site. I'm having a little bit of trouble reconciling common tasks in Grunt for v4 such as registering multiple layouts, pages, partials, etc with your v6 docs. Do you have any example repos and task config using v6 that I could have a look through as I think this would be helpful in getting started?

  • 3

    Ordering blog posts, Assemble 0.4.x vs 0.5.x, etc.

    I've finally worked out how to configure Assemble, in it's most basic fashion, but one part eludes me: collections. The site I'm porting to Assemble currently has one section (/notebook) where posts appear in a list, ordered with the most recently published first. (Currently, the link above is published with Kirby CMS, which I'm hoping to move away from. I share it here as an example of what I'm looking to achieve.)

    I see that Assemble has a few basic constructs for this (e.g. Collections), but I don't know how to use 'em. The documentation isn't quite clear to me. How should I go about creating ordered blog lists with permalinks, pagination, etc.?

    Are Collections the right methodology for this, or am I looking in the wrong place? Because I would rather not have to create file/directory structures that dictate ordering (as I'm currently doing in Kirby), and let the system decide which posts should be displayed first, based on the published date.

    I've looked at the assemble-blog package, but it's under heavy development (as I understand, anyway), and not suitable for reference. I'm also a bit confused about the new "middleware" packages, and what significance they carry, if any, in the world of Assemble 0.4.x.

    Should I continue learning 0.4.x, with all it's ins-and-outs, or jump to the 0.5.x branch, and set myself up for the future? As a newcomer, I need a little guidance.

  • 4

    asset -path should have a trailing slash (when it's not "")

    The current asset path helper seems to be quite handy. I'm actually really happy that it's there. Previously I was handling this manually and it was a pain.

    Sadly there's one problem. It's missing a trailing slash. Let me explain.

    I have a file structure like this:


    The build folder contents will be published like this:

    During development however some developers may have to have the site like this:


    This is why the relative paths are so important, I should not use absolute paths, as it will break the thing on developers machines.

    I'd like the asset path to point to my build-directory so that I can reference either scripts or css (or any of the other things I have there, like other pages). I'd like to be able to reference myscript.js file from layout files, partials, etc. Currently it returns values like this for myscript.js:

    localhost/~Developer/ {{assets}}+{{myscript}} = ""+"script/myscript.js"
    localhost/~Developer/about/ {{assets}}+{{myscript}} = ".."+"script/myscript.js"
    localhost/~Developer/news/ {{assets}}+{{myscript}} = ".."+"script/myscript.js"
    localhost/~Developer/news/2013/ {{assets}}+{{myscript}} = "../.."+"script/myscript.js"
    localhost/~Developer/ {{assets}}+{{myscript}} = ""+"/script/myscript.js"
    localhost/~Developer/about/ {{assets}}+{{myscript}} = ".."+"/script/myscript.js"
    localhost/~Developer/news/ {{assets}}+{{myscript}} = ".."+"/script/myscript.js"
    localhost/~Developer/news/2013/ {{assets}}+{{myscript}} = "../.."+"/script/myscript.js"

    The latter is how the assemble documentation suggests that we'd use the asset variable.

    What I'd like it do do is this:

    localhost/~Developer/ {{assets}}+{{myscript}} = ""+"script/myscript.js"
    localhost/~Developer/about/ {{assets}}+{{myscript}} = "../"+"script/myscript.js"
    localhost/~Developer/news/ {{assets}}+{{myscript}} = "../"+"script/myscript.js"
    localhost/~Developer/news/2013/ {{assets}}+{{myscript}} = "../../"+"script/myscript.js"

    This could be done either by changing how assets works or by adding a new variable that works the way I described.

    Currently I have written a helper that checks if the assets variable is not empty and then adds the trailing slash to it. It's just a bit inelegant to use helper everywhere for such a simple task.

    Or am I missing something?

  • 5

    v0.6.0 what?!

    That's right! we decided to go straight to v0.6.0. Why? Well, here are a few of the highlights.

    v0.6.0 features

    In the upcoming release, here are just a few of the new features being introduced to Assemble:

    • CLI v0.6.0 uses the same config-style and CLI patterns as gulp. just run assemble at the command line.
    • Streams (gulp-style): Assemble v0.6.0 uses vinyl
    • Plugins/Tasks (gulp-style): Since Assemble v0.6.0 also uses orchestrator, not only does Assemble v0.6.0 have support for gulp-style streaming plugins, but any gulp plugin can be run by Assemble v0.6.0.
    • Parsers (kerouac-style): Parsers are like express engines and they're registered the same way as well. Being parsers, they're used for parsing instead of rendering. As an example, the pre-loaded (default) parser will extend the context with data from yaml front matter.
    • Engines express-style engine support! Engines support has changed so dramatically in this version that we're considering this a new feature. Assemble v0.6.0 allows any engine from Consolidate or Transformers to be registered using assemble.engine(), just like express. To author a custom engine, follow the instructions on the consolidate docs or the transformers docs, depending on what you need.
    • Routes/Middleware (express/kerouac-style): Express-style routes, but for static pages! In a nutshell, routes allow you to run a stack of middlewares against any pages that match any number of given regex or string patterns. Endless possibilities here (need revving/cache busting anyone?).

    This is truly just for starters. There are many "smaller" features, and some of them are more exciting to me than any of the above (like support for partial layouts! yep, meaning that partials are able to use layouts - even nested layouts!). Stay tuned for updates!

    What about support for previous versions?

    We'll be moving the code for previous versions to branches or repos where it makes sense, and of course we'll continue to answer questions and help out where we can, but we won't be actively supporting previous versions beyond crucial bug fixes.


    This new version will be decoupled from grunt? It will have a gulp plugin?

    Yes, Assemble v0.6.0 will be completely independent, but we will also offer both grunt and gulp plugins for anyone who prefers those tool chains. Once v0.6.0 is released, the main difference for Grunt users will be the need to begin installing grunt-assemble instead of just assemble - which is how it should have been all along.

    The Assemble core team will continue using Grunt, Gulp and whatever other tool works best on each particular project.


    Please feel free to ask questions, give feedback and help out with this release. If you're interested in helping out with anything, as always please let us know! We will definitely need help and feedback from the community to make this happen!

    What else do you want to know about this release?

  • 6

    v0.6.0 Timings

    I created some more timing statistics with our fairly large set of product pages to generate. We have source "group" JSON files with several products in each JSON. 10.json has all the products in group 10. The groups differ in sizes, there are large and small groups.

    While assemble is reasonably fast there still seem to be a non-linearity during runtime. E.g. for large data sets the runtime will increase non-linearly.


    Note that generating all groups after another in several gulp/assemble runs takes about 9 minutes. Generating all products on the other hand, takes about 29 minutes.

    Do you have pointers what causes the additional 20 minutes when you generate the whole data set?

    (For my tests I didn't change any code, all I did was limit the input data by supplying command line arguments and extracting only relevant data from JSON in my loader.)

  • 7

    @index in #each is now empty

    I've spent several hours trying to debug why my code has stopped outputting the @index. Thought it was a bug of mine at first - but then I realized I had recently pulled code that was working to a new machine, and downloaded the latest node, as well as the latest version of Assemble.

    I then tried pulling another project that prints the @index, and using the same node version and assemble version found that it too is not outputting @index.

    Lastly, i created a net new project, and am using this code in my partial:

    {{#each items}} Index: {{@index}} {{/each}}

    Thats it. The output outputs the word "Index:" with no trailing numeric value as you would expect for a data file containing an array of five objects

    Am I missing something? Can anyone repro this?

    I rolled node back to 0.10.34 and am using assemble v 0.4.42. I have tried any combination of node 0.10.34->current as well as assemble 0.4.0 -> current. Could this be something else?

  • 8

    options.pages bug

    I can't pin down what's causing it, but there is definitely a bug. I noticed it in the past but couldn't reproduce it so I didn't create an issue.

    Basically, assemble seems to randomly skip any target that has a pages option defined. Sometimes all of the pages show as being built successfully, but no file is actually written to the disk. And sometimes the console shows a success message for each page, but each page has the same name and dest path.

    I just wanted to get this issue created in case someone else has the problem so we can try to figure this out.

  • 9

    RangeError: Maximum call stack size exceeded when trying to create an assemblefile.js


    • [x] Have you searched for existing issues (open and close) to see if the bug or feature request has already been reported?
    • [x] If this is a bug report, are you running the latest version of Assemble? If not, please update to the latest version and verify that the issue still occurs before proceding.
    • [x] Have you read the Contributing Guide?
    • [x] Have you reviewed the project readme (you might find advice about creating new issues)?
    • [x] Are you creating an issue in the correct repository? (For example, if your issue is related to [grunt-assemble][] or [handlebars-helpers][], you will want to create the issue in that project).

    Ready? Great! Please provide the following details:




    Please decribe the bug or feature, along with:

    • [x] Expected behavior and actual behavior. I can't use assemble to create an assemblefile.js in 0.18.1 or newer (tested every version up to the latest one). 0.17.1 is the last working version. Running assemble always results in a RangeError.

    • [x] Steps to reproduce the problem.

    Using cygwin on Windows, node v6.9.0. Did nothing but npm i -g assemble && assemble. Et voila, error.

    error message

    Manuel@Manuel-406 /cygdrive/w/_git/assemble
    $ assemble --version
    [00:14:54] using cwd ~/W:\_git\assemble
    assemble v0.18.1
    Manuel@Manuel-406 /cygdrive/w/_git/assemble
    $ assemble
    [00:14:59] using cwd ~/W:\_git\assemble
    [00:15:00] starting assemble
    [00:15:00] starting assemble:default task
    [00:15:00] starting assemble:prompt-new task
    ? No assemblefile.js found, want to add one? Yes
    RangeError: Maximum call stack size exceeded
  • 10

    Is it possible to define and pass data to an Assemble partial inline?

    In ERB, I can do it like this:

    <%= partial("inputtext", :locals => {
        :id => "fistname",
        :label => "First name"
    }) %>

    I know I can pass data to an Assemble partial if it is already defined, e.g:

    {{> inputtext predefinedData }} 

    But can I define the data inline?

  • 11

    Possibility of developing Assemble forum?

    I noticed that a lot of the issues on this repository are either question or discussion based (like this one... how ironic). Would you be open to developing a forum for Assemble? I think something like the Foundation support area and forum might be successful.

  • 12

    Assemble logo as an SVG?

    From what I was able to find, the logos available for the Assemble project are available only in the PNG format. I was wondering if there is an SVG version of the logo that could be made available. Thanks!

  • 13

    Markdown Helper

    I am using version 0.6.3 of grunt-assemble.

    The markdown helper seems to insert breaks even when it shouldn't.

    The following code:

    Paragraph 1: The quick brown 
    fox  jumps over the lazy dog.
    Paragraph 2: The quick brown 
    fox  jumps over the lazy dog.

    compiles to:

    <p>Paragraph 1: The quick brown 
    <br>fox  jumps over the lazy dog.
    <p>Paragraph 2: The quick brown 
    <br>fox  jumps over the lazy dog.

    ... when I believe it should compile to:

    <p>Paragraph 1: The quick brown fox jumps over the lazy dog.</p>
    <p>Paragraph 2: The quick brown fox jumps over the lazy dog.</p>

    I think line breaks should be inserted only when there are two spaces a the end of the line.

  • 14

    How to add pagination in grunt-assemble

    [email protected] (grunt-assemble)

    Please share ideas how to make pagination with assemble + handlebars. I can't think of anything. Static sites are a mystery. I just need a basic idea, please. Thank you!

  • 15

    Nested if statements causing custom parameters in partials to become repeated/global scope

    Version: 0.24.3

    Error: Nested if statements cause custom parameters in partials to become global in scope, which causes subsequent uses of that partial to hold onto those parameter values unless they are declared as empty strings or new values. Using gulp.


    var gulp = require('gulp');
    var extname = require('gulp-extname');
    var assemble = require('assemble');
    var app = assemble();
    gulp.task('load', function(cb) {
    gulp.task('assemble', ['load'], function() {
      return app.toStream('pages')
    gulp.task('default', ['assemble']);

    p.hbs partial

    {{#if copy}}{{#if test}}{{test}}{{/if}}<p>{{{copy}}}</p>{{/if}}

    index.hbs page file

    layout: default.hbs
    subject: Branded transaction email example
    {{> p copy="copy1" test="abc" }}
    {{> p copy="copy2" }}
    {{> p copy="copy3" }}
    {{> p copy="copy4" }}

    layout.hbs layout file

    <!doctype html>
    <meta name="viewport" content="width=device-width" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link href="../src/css/main.css" media="all" rel="stylesheet" type="text/css" />
    {% body %}

    expected output


    output produced

  • 16

    Passing to yaml front matter.


    [email protected]


    I want to generate YAML from matter from JSON data passed directly

            options: {
              layout: 'single-blog-post.hbs',
              pages: createPages('data/blog/blog.json','app/layouts/single-blog-post.hbs')
          files: {'<%= dirs.output %>/blog/' : ['!*'] } //We need to trick assemble here using !* as the src


    title : {{}}

    It returns [object Object] rather than the title name. When I add {{name}} in the hbs file it outputs it directly but it doesn't want to output it as YAML Front Matter.