Have ideas to improve npm?Join in the discussion! »


    1.4.2 • Public • Published


    Kiss Static Site Generator, is an open-source MVC html website builder (for node), that leverages handlebar templates to make quick, simple and blisteringly fast websites.

    Kiss-ssg uses handlebar partials and handlebar-layouts to help you make DRY static websites.

    Install with npm install kiss-ssg --save-dev, or just drop kiss-ssg.js somewhere.


    kiss-ssg has 3 methods

    • .page()
    • .pages()
    • .scan()

    The simplest usage is to use .scan() to scan your 'pages directory' for *.hbs files and outputs them to the 'build folder'.

    const Kiss = require('kiss-ssg')
    const kiss = new Kiss()

    Note: kiss will generate the default folders for you when you first run the script. You can overwrite the folder locations bay passing a config to the kiss constructor.

    The default config options are:

      dev: false,
      verbose: false,
      cleanBuild: true,
      folders: {
        src: './src',
        build: './public',
        assets: './src/assets',
        layouts: './src/layouts',
        pages: './src/pages',
        partials: './src/partials',
        models: './src/models',
        controllers: './src/controllers'

    Partials: Cam be a .hbs, a .html file or a .md file, Note: .md files are automatically parsed

    Option Default Purpose
    dev false Dev mode will start a local live-reload server and rebuild on file change.
    verbose false Enables additional output on the terminal, when set to true
    cleanBuild true Removed all files from the build dir before generating.
    folders see above A JSON object of alternative folder locations

    Note: All config settings are available in the view under "this.config"


    Any static files you have in the assets directory will be copied to the build directory


    Instead (in in conjunction) of using the .scan() method you can pass a model to the view using the .page() method. This allows you to name the view and pass a model to that view. The model is then available in the handlebar template under the model property, e.g. {{model.name}}

    const Kiss = require('kiss-ssg')
    const kiss = new Kiss({ dev: true })
        view: 'index.hbs',
        model: 'index.json',
        controller: 'index.js',
        title: 'My Page Title',

    Note: The file locations of the models, views, and controllers are relative to the folder locations defined in the kiss configuration. Alternatively, instead of passing a file location you can pass a native object for that setting.

    Views: can se a .hbs file or a string Models: can be a .json file, a http api endpoint, or a JSON object Controllers: can be a .js file or a function that returns a page option JSON to be merged into the page options

    The options that you can pass to .page() & pages() are:

        view: 'index.hbs',
        model: {}
        controller: ({model})=>{return {model: model}},
        title: 'Page Title',
        description: 'A description of the page (useful for meta data)'
        path: '/',
        slug: 'index',

    These options are both used internally by kiss and are available in view.

    • view = A handlebars view.
    • model = A json object, the name of the json file relative to the models folder or a URL for an API endpoint.
    • controller = A function that returns a page options object - used for manipulating data in the model.
    • title = The page title
    • path = the folder path to the page
    • slug = the name of the file without the extension

    page and path create the url, i.e. /{path}/{slug}.html

    Note: If you don't pass a path or a slug they will be inferred from the view


    In addition to passing page options you can also pass a option mapper to act as a controllers to the .page() and .pages() methods:

    const Kiss = require('kiss-ssg')
    const kiss = new Kiss()
        title: 'My Team Page',
        view: 'about/index.hbs',
        model: 'departments.json',
        controller: ({ model }) => {
          return {
            model: model.sort(
              (a, b) => parseInt(a.sort_order) - parseInt(b.sort_order)


    The option mapper is really useful for mapping a slug from the model. This is great for dynamic slugs and a necessity when passing an array of models to the .pages() method to generate a series of pages.

    const Kiss = require('kiss-ssg')
    const kiss = new Kiss({ test: '123' })
        title: 'Page Title',
        view: 'index.hbs',
        view: 'course.hbs',
        model: 'https://{my-cool-api}/courses',
        controller: ({ model }) => {
          return {
            slug: model.slug,
        path: 'courses',


    Kiss-ssg registers a few useful helpers by default including:

    You can parse markdown like this:

    # Heading
    > this is markdown
    foo bar baz
    {{markdown model.introduction}}

    If you want to take a peek at whats properties you have available to to in a handlebars file you can use this helper:

    {{{stringify this}}}

    Kiss exposes the handlebars object so you can register your own helpers, e.g.

    kiss.handlebars.registerHelper('stringify', function (obj) {
      return JSON.stringify(obj, null, 3)


    npm i kiss-ssg

    DownloadsWeekly Downloads





    Apache 2.0

    Unpacked Size

    95.5 kB

    Total Files


    Last publish


    • avatar