A Bite-Size SPA Website Generator

About Kibble.js


Welcome to Kibble.js — a JavaScript SPA (Single Page App) website generator, ver 0.2.0, available at

In concept, Kibble is similar to static website generators such as Jekyll, except that it operates as a SPA. Meaning, Kibble does not fetch static HTML pages from the server*. Instead, all text content is embedded within Kibble's JavaScript "bundle" (in the Markdown format) and fetched just once, on initial page load. The articles are subsequently rendered and served "bite-size" within a single page, as needed.

As with most other static website generators, you can upload and host a Kibble on the simplest of web servers — no backend code or database are required. So, a Kibble site is cheap to host and should be pretty hack-proof (unless someone breaks into your hosting account). However, one major benefit over a truly "static" site is the ability to easily add text search, templating logic, or any other client-side functionality.

The dev stack comprises NPM, Gulp, Browserify, Backbone, CoffeeScript, jQuery, Sass. For the first real-world Kibble site, see, running a custom theme.


  • 100% client-side Javascript
  • Spiffy-fast UI interaction
  • Small and focused — best for short articles, quick tutorials, recipes, etc.
  • Write posts and pages in Markdown
  • Text search (in progress)
  • Syntax highlighting for code snippets
  • Responsive CSS with theme support — utilizes Minithematiq.css
  • Built-in image viewer
  • Disqus-ready
  • SEO-capable* (in progress)
  • Build and serve with Gulp, via LiveReload


  • Not suitable for prolific bloggers — initial load times are directly tied to content size (potentially solvable by splitting up bundles, using Webpack instead of Browserify..)
  • Limited initial feature set


The aim was to knock out — a simple website for my teenage techie son where he could post instructional articles about his DIY maker projects.

I wrangled with Jekyll for a bit but I enjoy coding client-side apps. I also wanted a few bits of custom functionality, primarily support for numbered, collapsible sections to allow step-by-step presentation of his project flows, text search, etc.

The project turned out to be a fun learning exercise so I'm making it available as my first "official" open-source repo. Feel free to clone and modify Kibble as you see fit!

Getting Started

To get going, NPM must be installed on your system:

With npm installed, cd into your projects root folder, then:

# clone the repo
git clone

cd kibble.js        # enter the project folder
npm install         # install all dependencies

gulp build          # compile starter site
gulp serve          # start local server

If all went well, Kibble should now be running on http://localhost:8080. While developing, you can just run gulp which will launch the server and rebuild the site whenever changes are made.

NOTE: If you get "EACCESS" errors during npm install (OSX), try sudo npm install. If you can't run gulp, you probably need to do npm install -g gulp to add it to your system PATH.

Kibble Basics

Once you pull down the starter repo, you can rename the folder and start making your modifications. Kill the existing .git subfolder and start your own repo:

rm -rf .git
git init

All development files (which are used to compile your final site) reside in the _dev/ folder. For adding content and modding your Kibble site, this is the place:

    content/        # Your Articles (Pages & Posts)
        content.js  # Site info and content registry file
        pages/      # Markdown files for your pages
        posts/      # Markdown files for your posts
    coffee/         # CoffeeScript files
    js/             # Compiled CoffeeScript files (do not modify directly)
    sass/           # SASS styling files
    templates/      # HTML templates

In terms of adding new Pages and Posts, the _dev/content/ subfolder is your friend. The basic steps are:

  1. Save some new .md articles (text files written using the Markdown syntax) into pages/ or posts/
  2. Be sure to add the required "YAML Info" at the top of each article file (see below)
  3. Edit content.js to update your site info and to register your newly added files
  4. Run gulp build to recompile your site!

Adding Your Content

The _dev\content\content.js "registry" file is where your content gets included:

var fs = require( 'fs' );
module.exports = {

    // Edit your site details here
    site:  {
        title:           "My Blog",                 // The main title of your website, for header, footer, <title>
        tagline:         "Thoughts & Musings",      // A cool subtitle to go with your title
        description:     "A blogging journey..",    // Description used for the <meta> tag (search engines)
        disqusShortname: "myblog",                  // Your Disqus id (set it up on
        hostURL:         "",   // Your official website location, when you deploy (for Disqus)
        hostName:        "",              // Your official host name, when you deploy (for Disqus)

    // Register your new Page files here
    pages: [
        { markdown: fs.readFileSync( "./\_dev/content/pages/",   "utf8" ) },  // note the comma
        { markdown: fs.readFileSync( "./\_dev/content/pages/",   "utf8" ) },  // note the comma
        { markdown: fs.readFileSync( "./\_dev/content/pages/", "utf8" ) }   // last item = no comma!

    // Register your new Post files here
    posts: [
        { markdown: fs.readFileSync( "./\_dev/content/posts/", "utf8" ) }  // first & last item = no comma!

NOTE: The above data structure is a JavaScript object, so be sure to observe the correct placement of commas.

NOTE: Whenever you add any new files or edit content.js you must re-run/restart Gulp.

Writing Articles for Kibble

You can add two types of "articles" to Kibble — Pages and Posts. You save your articles as Markdown .md files. However, for your articles to show up, you need to add a small bit of "YAML Info" at the top of each file. When saving your files, though not required, it's good practice to include a date in the article's filename, e.g.


Your typical blog entries, for example, the provided sample Intro to Markdown post.

Each post must be assigned a category. For each unique category a Nav Menu item is automatically created (to allow filtering by category). Category nav links are ordered within the menu by the number of posts per category. Each post also receives a Disqus comment block (if set up).

At the very top of each Post, include the following "YAML Info". Looking at our Markdown article as an example:

id:         markdown                     # Unique id (used in URL route)
date:       Mar 1 2015                   # Used to date your Post
title:      Intro to Markdown            # Title of your Post
tagline:    Markdown all the things!     # Subtitle of your Post
category:   Misc                         # Specific category (will become a Menu item)
titleImage: ../../media/thumbs/markdown/title.jpg     # Hero image
publish:    true                         # Set to 'false' to exclude from site
syntax:                                  # Optional: Languages for code highlighting
    - css
    - html
    - markdown

NOTE: This is "inspired" by Jekyll's "YAML Matter" — be sure maintain alignment and retain the surrounding "---" delimiters.


These are your non-blog web pages, say, your landing page or other prominent content. For instance, this About article is a "Page". Pages do not appear in the blog roll and do not get Disqus attached.

Published pages can appear in the Nav Menu as well, either before category links or after. One such page can be tagged as the landing "home" page, otherwise Kibble defaults to the All blog roll (sorted by date).

"YAML Info" for Pages follows this structure:

id:       about              # Unique id (used in URL route)
title:    About Kibble.js    # Title of your Page
navTitle: Home               # Menu name for this Page
navOrder: -1                 # Controls menu position (see below)
isHome:   true               # Set to 'true' is landing page
publish:  true               # Set to 'false' to exclude from site
syntax:                      # Optional: Languages for code highlighting
    - markdown
    - html
    - bash
    - javascript

For navOrder, negative values will place your Page nav before any Post Category links, and positive values after.

NOTE: If you just want a page without any Menu presence, you only need id, title, and publish in your YAML block. The starter legal pages provided here are an example of that.


Images reside in the ../../media/thumbs/ folder, organized into subfolders, one per article (recommended practice). To include an image in your article, the syntax is:

![Cool Caption](../../media/thumbs/markdown/title.jpg)

Cool Caption

Kibble automatically adds a fancy frame around your images and applies the alt attribute text as the caption. Clicking on any image within an article will launch Kibble's integrated image viewer (desktop resolutions only).

To speed up page loads, Kibble supports image substitution -- the subfolder ../../media/thumbs/thumbs/ is reserved for thumbnail versions of your pics. So, you should specify your image paths pointing to the thumbs URL and Kibble will fetch the original HD versions for its Image Viewer, and the article hero image only.

The folder structure within the thumbs/ directory should mimic the folders within ../../media/thumbs/. You can save your thumbnails manually, or better, run the gulp thumbs task which will automatically generate your thumbnails at a width of 300px (you can change it in gulpfile.js).

NOTE: The 'thumbs' task requires the GraphicsMagick library. On A Mac, you can install it via brew install graphicsmagick, on Ubuntu sudo apt-get install graphicsmagick.

NOTE: Always delete all contents in thumbs/ before running the task, otherwise you will end up with thumbs within thumbs ad infinitum, due to the recursive nature of Gulp.

Styling Your Kibble Site


Generating SEO Pages

As I've discovered, a SPA blog is pretty worthless in terms of SEO -- there is nothing for search engines to crawl! While there are ways to make it work using backend solutions (rendering "escaped fragments"), to stay within the "static" paradigm I'm trying something much simpler:

  1. Pre-render all articles into a special folder (articles/) as actual HMTL pages.
  2. Render hard links to those HTML pages into the home page nav (Kibble will override them with its own nav).
  3. Embed a JS snippet into each page to redirect back into that same article within the SPA.

So, Google will find and index your page as articles\post\myarticle.html but when you hit that page, it instantly redirects to #\post\myarticle and fires up Kibble, serving the correct article.

It seems to be working, but the jury is still out. Currently, we see a bit of FOUC when we access a Kibble site via search results but I think that can be fixed with some CSS...

In any case, before deploying, run node seo.js which will render all of your articles and index.html using the seo templates.

NOTE: If you want to make any modifications to your index.html , do so in the seo-index.html template, otherwise your changes will be wiped out when you run this script!

Publishing Your Blog


•To Dos

  • Improve SEO (in progress)
  • Add Search (in progress)
  • Add Contact functionality
  • Handle long lists
  • Concat nav if many unique categories (combine under 'other' )
  • Add mobile nav
  • ImageViewer improvements, info overlays
  • Add social media hooks
  • Support multiple categories per post (?)