diff --git a/0.21.0/docs/index.html b/0.21.0/docs/index.html
index 4b8fbf37..3f3b0371 100644
--- a/0.21.0/docs/index.html
+++ b/0.21.0/docs/index.html
@@ -21,6 +21,11 @@
                 <li><a href="..">Home</a></li>
                 <li class="active"><a href="#">Documentation</a></li>
                 <li><a href="/repl?v=0.21.0">Try Ramda</a></li>
+                <li><a href="/examples">Cookbook</a></li>
+            </ul>
+        </div>
+        <div class='navbar-right'>
+            <ul class="nav navbar-nav">
                 <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
             </ul>
         </div>
diff --git a/0.21.0/examples/code/apply.function.n.times.json b/0.21.0/examples/code/apply.function.n.times.json
new file mode 100644
index 00000000..edc8f868
--- /dev/null
+++ b/0.21.0/examples/code/apply.function.n.times.json
@@ -0,0 +1 @@
+{"title":"Apply a given function N times","name":"Apply function N times","description":null,"source":"let R = require('ramda');\n\n// applyN :: (a -> a) -> Number -> (a -> a)\nconst applyN = R.compose(R.reduceRight(R.compose, R.identity), R.repeat);\n\napplyN(x => x * x, 4)(2); //=> 65536 (2 -> 4 -> 16 -> 256 -> 65536)\n\nconst isOdd = n => n % 2 == 1;\nconst collatz = n => isOdd(n) ? (3 * n + 1) : (n / 2);\n\napplyN(collatz, 5)(27);\n"}
diff --git a/0.21.0/examples/code/convert.list.to.object.json b/0.21.0/examples/code/convert.list.to.object.json
new file mode 100644
index 00000000..ae36b6cb
--- /dev/null
+++ b/0.21.0/examples/code/convert.list.to.object.json
@@ -0,0 +1 @@
+{"title":"Convert a list of property-lists (with header) into a list of objects","name":"Convert List to Object","description":null,"source":"let R = require('ramda');\n\nconst tsv = [\n  ['name',  'age', 'drink'], \n  ['john',   23,   'wine'], \n  ['maggie', 45,   'water']\n];\nR.compose(R.apply(R.lift(R.zipObj)), R.splitAt(1))(tsv);\n"}
diff --git a/0.21.0/examples/code/convert.object.to.array.json b/0.21.0/examples/code/convert.object.to.array.json
new file mode 100644
index 00000000..aa643dec
--- /dev/null
+++ b/0.21.0/examples/code/convert.object.to.array.json
@@ -0,0 +1 @@
+{"title":"Convert object to array","name":"Convert object to array","description":null,"source":"let R = require('ramda');\n\n// convert :: {a} -> [{ word :: String, count :: a }]\nconst convert = R.compose(R.map(R.zipObj(['word', 'count'])), R.toPairs);\n\nconvert({I: 2, it: 4, that: 1});\n"}
diff --git a/0.21.0/examples/code/create.list.json b/0.21.0/examples/code/create.list.json
new file mode 100644
index 00000000..54bcb949
--- /dev/null
+++ b/0.21.0/examples/code/create.list.json
@@ -0,0 +1 @@
+{"title":"Create a list","name":"Create a list","description":"This snippet will create a new list with the specified values. Check out https://clojuredocs.org/clojure.core/list.","source":"let R = require('ramda');\n\n//  list :: a... -> [a...]\nvar list = R.unapply(R.identity);\nlist(1, 2, 3);\n"}
diff --git a/0.21.0/examples/code/diff.objects.json b/0.21.0/examples/code/diff.objects.json
new file mode 100644
index 00000000..89e823b4
--- /dev/null
+++ b/0.21.0/examples/code/diff.objects.json
@@ -0,0 +1 @@
+{"title":"diffing objects","name":"Diff Objects","description":"similar to <a href=\"http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Maps.html#difference%28java.util.Map,%20java.util.Map%29\">Guava's Maps Difference</a>","source":"let R = require('ramda');\n\nvar groupObjBy = R.curry(R.pipe(\n  // Call groupBy with the object as pairs, passing only the value to the key function\n  R.useWith(R.groupBy, [R.useWith(__, [R.last]), R.toPairs]),\n  R.map(R.fromPairs)\n))\n\nvar diffObjs = R.pipe(\n  R.useWith(R.mergeWith(R.merge), [R.map(R.objOf(\"leftValue\")), R.map(R.objOf(\"rightValue\"))]),\n  R.groupObjBy(R.cond([\n    [\n      R.both(R.has(\"leftValue\"), R.has(\"rightValue\")),\n      R.pipe(R.values, R.ifElse(R.apply(equals), R.always(\"common\"), R.always(\"difference\")))\n    ],\n    [R.has(\"leftValue\"), R.always(\"onlyOnLeft\")],\n    [R.has(\"rightValue\"), R.always(\"onlyOnRight\")],\n  ])),\n  R.evolve({\n    common: R.map(R.prop(\"leftValue\")),\n    onlyOnLeft: R.map(R.prop(\"leftValue\")),\n    onlyOnRight: R.map(R.prop(\"rightValue\"))\n  })\n);\n\ndiffObjs({a: 1, c: 5, d: 4 }, {a: 1, b: 2, d: 7});\n"}
diff --git a/0.21.0/examples/code/do.any.strings.appear.json b/0.21.0/examples/code/do.any.strings.appear.json
new file mode 100644
index 00000000..49fa9571
--- /dev/null
+++ b/0.21.0/examples/code/do.any.strings.appear.json
@@ -0,0 +1 @@
+{"title":"Do any of these strings appear in another list?","name":"Any Duplicate Strings","description":null,"source":"let R = require('ramda');\n//    overlaps :: [a] -> [a] -> Boolean\nconst overlaps = R.pipe(R.intersection, R.complement(R.isEmpty));\nprocess.argv // ['node', 'script.js', '-v']\noverlaps(['-v', '--verbose'], process.argv)\n"}
diff --git a/0.21.0/examples/code/filter.using.keys.and.values.json b/0.21.0/examples/code/filter.using.keys.and.values.json
new file mode 100644
index 00000000..6657d85c
--- /dev/null
+++ b/0.21.0/examples/code/filter.using.keys.and.values.json
@@ -0,0 +1 @@
+{"title":"Filter an object using keys as well as values","name":"Filter w/ Keys & Vals","description":null,"source":"let R = require('ramda');\n\nconst filterWithKeys = (pred, obj) => R.pipe(\n  R.toPairs, \n  R.filter(R.apply(pred)), \n  R.fromPairs\n)(obj);\n\nfilterWithKeys(\n  (key, val) => key.length === val, \n  {red: 3, blue: 5, green: 5, yellow: 2}\n);\n"}
diff --git a/0.21.0/examples/code/get.object.by.id.json b/0.21.0/examples/code/get.object.by.id.json
new file mode 100644
index 00000000..b6a326b3
--- /dev/null
+++ b/0.21.0/examples/code/get.object.by.id.json
@@ -0,0 +1 @@
+{"title":"Get object by id","name":"Get object by id","description":null,"source":"let R = require('ramda');\n\n//    findById :: String -> Array -> Object\nconst findById = R.converge(\n  R.find,\n  [R.pipe(R.nthArg(0), R.propEq(\"id\")), R.nthArg(1)]\n);\n"}
diff --git a/0.21.0/examples/code/get.objects.methods.json b/0.21.0/examples/code/get.objects.methods.json
new file mode 100644
index 00000000..cc88e298
--- /dev/null
+++ b/0.21.0/examples/code/get.objects.methods.json
@@ -0,0 +1 @@
+{"title":"Get an object's method names","name":"Get method names","description":null,"source":"let R = require('ramda');\n\n//  methodNames :: Object -> [String]\nvar methodNames = R.compose(R.keys, R.pickBy(R.is(Function)));\n\nvar obj = {\n  foo: true,\n  bar: function() {},\n  baz: function() {},\n};\n\nmethodNames(obj);\n"}
diff --git a/0.21.0/examples/code/increment.with.step.json b/0.21.0/examples/code/increment.with.step.json
new file mode 100644
index 00000000..de519692
--- /dev/null
+++ b/0.21.0/examples/code/increment.with.step.json
@@ -0,0 +1 @@
+{"title":"Create an incrementing or decrementing range of numbers with a step","name":"Increment with step","description":null,"source":"let R = require('ramda');\n\nconst rangeStep = (start, step, stop) => R.map(\n  n => start + step * n,\n  R.range(0, (1 + (stop - start) / step) >>> 0)\n);\n\nconsole.log(rangeStep(1, 1, 4));   // [1, 2, 3, 4]\nconsole.log(rangeStep(2, 2, 8));   // [2, 4, 6, 8]\nconsole.log(rangeStep(0, 3, 10));  // [0, 3, 6, 9]\nconsole.log(rangeStep(3, -2, -3)); // [3, 1, -1, -3]\n"}
diff --git a/0.21.0/examples/code/make.objects.out.of.keys.json b/0.21.0/examples/code/make.objects.out.of.keys.json
new file mode 100644
index 00000000..331475a2
--- /dev/null
+++ b/0.21.0/examples/code/make.objects.out.of.keys.json
@@ -0,0 +1 @@
+{"title":"Make an object out of keys, with values derived from them","name":"Make object from keys","description":null,"source":"let R = require('ramda');\nlet fs = require('fs');\n\n//    objFromKeys :: (String -> a) -> [String] -> {String: a}\nconst objFromKeys = R.curry((fn, keys) =>\n  R.zipObj(keys, R.map(fn, keys)));\nconst files = ['diary.txt', 'shopping.txt'];\nobjFromKeys(fs.readFileSync, files);\n"}
diff --git a/0.21.0/examples/code/map.keys.of.object.json b/0.21.0/examples/code/map.keys.of.object.json
new file mode 100644
index 00000000..528cb1a6
--- /dev/null
+++ b/0.21.0/examples/code/map.keys.of.object.json
@@ -0,0 +1 @@
+{"title":"Map keys of an object","description":null,"source":"let R = require('ramda');\n\n//    mapKeys :: (String -> String) -> Object -> Object\nconst mapKeys = R.curry((fn, obj) =>\n  R.fromPairs(R.map(R.adjust(fn, 0), R.toPairs(obj))));\nmapKeys(R.toUpper, { a: 1, b: 2, c: 3 });\n"}
diff --git a/0.21.0/examples/code/map.keys.to.objects.json b/0.21.0/examples/code/map.keys.to.objects.json
new file mode 100644
index 00000000..cb55a10b
--- /dev/null
+++ b/0.21.0/examples/code/map.keys.to.objects.json
@@ -0,0 +1 @@
+{"title":"Map Keys To Objects","name":"Map keys to objects","description":null,"source":"let R = require('ramda');\n\nconst mapKeys = R.curry((fn, obj) =>\n    R.fromPairs(R.map(R.adjust(fn, 0), R.toPairs(obj))));\n    mapKeys(R.toUpper, { a: 1, b: 2, c: 3 });\n"}
diff --git a/0.21.0/examples/code/map.value.at.end.of.path.json b/0.21.0/examples/code/map.value.at.end.of.path.json
new file mode 100644
index 00000000..d84b42b1
--- /dev/null
+++ b/0.21.0/examples/code/map.value.at.end.of.path.json
@@ -0,0 +1 @@
+{"title":"Map over the value at the end of a path","name":"Map val at end of path","description":null,"source":"let R = require('ramda');\n\n// :: [String] -> (a -> b) -> {k: a} -> {k: b}\nconst mapPath = R.curry((path, f, obj) =>\n  R.assocPath(path, f(R.path(path, obj)), obj)\n);\n\nmapPath(['a', 'b', 'c'], R.inc, {a: {b: {c: 3}}});\n"}
diff --git a/0.21.0/examples/code/mess.with.dom.json b/0.21.0/examples/code/mess.with.dom.json
new file mode 100644
index 00000000..0b6e7c9c
--- /dev/null
+++ b/0.21.0/examples/code/mess.with.dom.json
@@ -0,0 +1 @@
+{"title":"Mess with the DOM","name":"Mess with DOM","description":"This example shows how to set styles so that all paragraphs are red.","source":"let R = require('ramda');\n\n// Get all descendants that match selector\n// Note: NodeList is array-like so you can run ramda list functions on it.\n//  cssQuery :: String -> Node -> NodeList\nvar cssQuery = R.invoker(1, 'querySelectorAll');\n\n// Mutate style properties on an element\n//  setStyle :: String -> String -> Element -> Element\nvar setStyle = R.assoc('style');\n\n// Make all paragraphs and anchors red\nR.pipe(\n    cssQuery('a, p'),\n    R.map(setStyle('color', 'red'))\n)(document)\n"}
diff --git a/0.21.0/examples/code/n.function.calls.json b/0.21.0/examples/code/n.function.calls.json
new file mode 100644
index 00000000..300e769a
--- /dev/null
+++ b/0.21.0/examples/code/n.function.calls.json
@@ -0,0 +1 @@
+{"title":"Get n function calls as a list","name":"Get n function calls","description":null,"source":"let R = require('ramda');\n\nR.map(R.call, R.repeat(Math.random, 5));\n"}
diff --git a/0.21.0/examples/code/object.size.json b/0.21.0/examples/code/object.size.json
new file mode 100644
index 00000000..8f659aa1
--- /dev/null
+++ b/0.21.0/examples/code/object.size.json
@@ -0,0 +1 @@
+{"title":"Get Object Size","name":"Object Size","description":null,"source":"let R = require('ramda');\n\n//    objSize :: Object -> Number\nconst objSize = R.nAry(1, R.pipe(\n  R.when(R.is(Object), R.keys),\n  R.when(R.is(Boolean), R.cond([[R.equals(false), R.always(null)], [R.T, R.always(1)]])),\n  R.when(R.is(Number), R.toString),\n  R.ifElse(R.isNil, R.always(0), R.length)\n));\nconsole.log(objSize()); // 0\nconsole.log(objSize(undefined)); // 0\nconsole.log(objSize(null)); // 0\nconsole.log(objSize(false)); // 0\nconsole.log(objSize(true)); // 1\nconsole.log(objSize('')); // 0\nconsole.log(objSize('foo')); // 3\nconsole.log(objSize(0)); // 1\nconsole.log(objSize(13)); // 2\nconsole.log(objSize(101)); // 3\nconsole.log(objSize(0.01)); // 4\nconsole.log(objSize({})); // 0\nconsole.log(objSize({foo:undefined, bar:undefined})); // 2\nconsole.log(objSize([])); // 0\nconsole.log(objSize([undefined, undefined])); // 2\n"}
diff --git a/0.21.0/examples/code/pick-list.json b/0.21.0/examples/code/pick-list.json
new file mode 100644
index 00000000..217f93b4
--- /dev/null
+++ b/0.21.0/examples/code/pick-list.json
@@ -0,0 +1 @@
+{"title":"Pick List Values by Index","name":"Pick List by Index","description":"This example shows you how to specify multiple indexes of an array to retrieve multiple values from the array.","source":"let R = require('ramda');\n\n// :: [Number] -> [a] -> [a]\nvar pickIndexes = R.compose(R.values, R.pickAll);\npickIndexes([0, 2], ['a', 'b', 'c']);\n"}
diff --git a/0.21.0/examples/code/r.props.deep.fields.json b/0.21.0/examples/code/r.props.deep.fields.json
new file mode 100644
index 00000000..d605c27a
--- /dev/null
+++ b/0.21.0/examples/code/r.props.deep.fields.json
@@ -0,0 +1 @@
+{"title":"Derivative of R.props for deep fields","name":"R.props for deep fields","description":null,"source":"let R = require('ramda');\n\nvar dotPath = R.useWith(R.path, R.split('.'));\nvar propsDotPath = R.useWith(R.ap, R.map(dotPath), R.of);\nvar obj = {\n    a: { b: { c: 1 } },\n    x: 2\n};\n\npropsDotPath(['a.b.c', 'x'], obj);\n"}
diff --git a/0.21.0/examples/code/ramda.fantasy.ajax.json b/0.21.0/examples/code/ramda.fantasy.ajax.json
new file mode 100644
index 00000000..37068fc1
--- /dev/null
+++ b/0.21.0/examples/code/ramda.fantasy.ajax.json
@@ -0,0 +1 @@
+{"title":"Use ramda-fantasy Future to wrap AJAX","name":"ramda-fantasy wrap AJAX","description":null,"source":"var Future = require('ramda-fantasy').Future;\n// Wrap ajax in a future\n//  fetch :: String -> Future String\nvar fetch = function(url) {\n  return new Future(function(rej, res) {\n    var oReq = new XMLHttpRequest();\n    oReq.addEventListener('load', res, false);\n    oReq.addEventListener('error', rej, false);\n    oReq.addEventListener('abort', rej, false);\n    oReq.open('get', url, true);\n    oReq.send();\n  });\n};\n\n// Could use Either instead of Future but they work about the same.\n//  parseJSON :: String -> Future Object\nvar parseJSON = function(str) {\n  return new Future(function(rej, res) {\n    try {\n      res(JSON.parse(str));\n    } catch (err) {\n      rej({ error: 'json parse error' });\n    }\n  });\n};\n\n// We have\n// String -> Future String\n// And\n// String -> Future Object\n// So we can .chain() them together\nvar fetchJSON = fetch.chain(parseJSON);\n\n// Get the items out of it?\n//  fetchItems :: Future Object -> Future []\nvar fetchItems = fetchJSON.map(R.prop('items'));\n\n// BTW at this point in the code the request still hasn't been sent\n\n// Filter the response?\n// Have to map first to get at the contents of the future then filter\n//  fetchNewItems :: Future [Object] -> Future [Object]\nvar fetchNewItems = fetchItems.map(R.filter(R.prop('new')));\n\n// Just get the titles of the items\n//  getNewTitles :: Future [Object] -> Future [String]\nvar getNewTitles = fetchNewItems.map(R.map('title'));\n\n// Finally do something\ngetNewTitles('/products.json').fork(console.error, console.log);\n// Now the AJAX req is sent and will log success or failure to console.\n\n// Bonus: Make one ajax request dependent on another\nfetchDependent = fetchJSON.map(R.prop('url')).chain(fetch);\nfetchDependent('urls.json').fork(console.error, console.log);\n"}
diff --git a/0.21.0/examples/code/rename.keys.of.object.json b/0.21.0/examples/code/rename.keys.of.object.json
new file mode 100644
index 00000000..7a986132
--- /dev/null
+++ b/0.21.0/examples/code/rename.keys.of.object.json
@@ -0,0 +1 @@
+{"title":"Rename keys of an object","name":"Rename keys","description":null,"source":"let R = require('ramda');\n\n/**\n* Creates a new object with the own properties of the provided object, but the\n* keys renamed according to the keysMap object as `{oldKey: newKey}`.\n* When some key is not found in the keysMap, then it's passed as-is.\n*\n* Keep in mind that in the case of keys conflict is behaviour undefined and\n* the result may vary between various JS engines!\n*\n* @sig {a: b} -> {a: *} -> {b: *}\n*/\nconst renameKeys = R.curry((keysMap, obj) => {\n  return R.reduce((acc, key) => {\n    acc[keysMap[key] || key] = obj[key];\n    return acc;\n  }, {}, R.keys(obj));\n});\n\nconst input = { firstName: 'Elisia', age: 22, type: 'human' }\n\nrenameKeys({ firstName: 'name', type: 'kind', foo: 'bar' })(input)\n"}
diff --git a/0.21.0/examples/code/set.properties.if.dont.exist.json b/0.21.0/examples/code/set.properties.if.dont.exist.json
new file mode 100644
index 00000000..217d0d2f
--- /dev/null
+++ b/0.21.0/examples/code/set.properties.if.dont.exist.json
@@ -0,0 +1 @@
+{"title":"Set properties only if they don't exist","name":"Set non-existent properties","description":"Useful for passing defaults, similar to lodash's _.defaults.","source":"let R = require('ramda');\n\n//  defaults :: Object -> Object -> Object\nvar defaults = R.flip(R.merge);\n\n// process.env.SECRET overwrites deadbeef if it exists\ndefaults(process.env, {\n  SECRET: 'deadbeef'\n});\n"}
diff --git a/0.21.0/examples/code/specific.order.json b/0.21.0/examples/code/specific.order.json
new file mode 100644
index 00000000..c38fb0cd
--- /dev/null
+++ b/0.21.0/examples/code/specific.order.json
@@ -0,0 +1 @@
+{"title":"Apply a list of functions in a specific order into a list of values","name":"Functions in order","description":null,"source":"let R = require('ramda');\n\nconst {red, green, blue} = require('chalk');\nconst disco = R.pipe(R.zipWith(R.call, [ red, green, blue ]), R.join(' '));\nconsole.log(disco([ 'foo', 'bar', 'xyz' ]));\n"}
diff --git a/0.21.0/examples/index.html b/0.21.0/examples/index.html
new file mode 100644
index 00000000..970f16f1
--- /dev/null
+++ b/0.21.0/examples/index.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html class="docs-page">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Ramda Cookbook</title>
+  <link rel="stylesheet" type="text/css" href="../style.css">
+  <script src="https://embed.tonicdev.com"></script>
+</head>
+
+<body>
+  <input type="checkbox" id="open-nav" />
+  <header class="navbar navbar-fixed-top navbar-inverse container-fluid">
+    <div class="navbar-header">
+      <label class="open-nav" for="open-nav"></label>
+      <a class="navbar-brand" href="#">
+        <strong>Ramda</strong>
+        <span class="version">v0.21.0</span>      
+      </a>
+    </div>
+    <div class="navbar-left">
+      <ul class="nav navbar-nav">
+        <li><a href="/">Home</a></li>
+        <li><a href="/docs">Documentation</a></li>
+        <li><a href="/repl?v=0.21.0">Try Ramda</a></li>
+        <li class='active'><a href="#">Cookbook</a></li>
+      </ul>
+    </div>
+    <div class='navbar-right'>
+        <ul class="nav navbar-nav">
+            <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
+        </ul>
+    </div>
+  </header>
+  <aside class="sidebar no-filter container-fluid">
+        <ul class="nav nav-pills nav-stacked toc">
+            <li class='text-capitalize padded' data-file="../examples/code/apply.function.n.times.json">Apply function N times</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/convert.list.to.object.json">Convert List to Object</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/convert.object.to.array.json">Convert object to array</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/create.list.json">Create a list</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/diff.objects.json">Diff Objects</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/do.any.strings.appear.json">Any Duplicate Strings</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/filter.using.keys.and.values.json">Filter w/ Keys &amp; Vals</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/get.object.by.id.json">Get object by id</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/get.objects.methods.json">Get method names</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/increment.with.step.json">Increment with step</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/make.objects.out.of.keys.json">Make object from keys</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/map.keys.of.object.json"></li> 
+            <li class='text-capitalize padded' data-file="../examples/code/map.keys.to.objects.json">Map keys to objects</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/map.value.at.end.of.path.json">Map val at end of path</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/mess.with.dom.json">Mess with DOM</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/n.function.calls.json">Get n function calls</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/object.size.json">Object Size</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/pick-list.json">Pick List by Index</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/r.props.deep.fields.json">R.props for deep fields</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/ramda.fantasy.ajax.json">ramda-fantasy wrap AJAX</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/rename.keys.of.object.json">Rename keys</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/set.properties.if.dont.exist.json">Set non-existent properties</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/specific.order.json">Functions in order</li> 
+        </ul>
+    </aside>
+  <main class="container-fluid">
+    <h1 class='title text-capitalize'>Cookbook</h1>
+    <div class='snippet'></div>    
+    <div id='tonic'></div>
+  </main>
+</body>
+<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
+<script>
+  (function(){
+            var notebook = Tonic.createNotebook({
+                element: document.getElementById("tonic"), 
+                source: '//Select an example to continue'
+            });             
+            
+            $('li').on('click', function(e){
+                let filename = $(e.currentTarget).data('file');
+                $('li').removeClass('active');
+                $(e.currentTarget).addClass('active');
+                
+                $.ajax({
+                    url: filename,
+                    dataType: 'text'
+                }).done(function(file){
+                    var example = JSON.parse(file);                  
+                    $('h1.title').text(example.title);
+                    if(example.description){
+                      $('div.snippet').html(example.description);  
+                    }
+                    
+                    notebook.setSource(example.source);
+                });         
+            });
+        })();
+</script>
+
+</html>
\ No newline at end of file
diff --git a/0.21.0/index.html b/0.21.0/index.html
index a63744dc..ae7ef6ed 100644
--- a/0.21.0/index.html
+++ b/0.21.0/index.html
@@ -21,6 +21,11 @@
                 <li class="active"><a href="#">Home</a></li>
                 <li><a href="docs">Documentation</a></li>
                 <li><a href="/repl?v=0.21.0">Try Ramda</a></li>
+                <li><a href="examples">Cookbook</a></li>
+            </ul>
+        </div>
+        <div class='navbar-right'>
+            <ul class="nav navbar-nav">
                 <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
             </ul>
         </div>
diff --git a/0.21.0/style.css b/0.21.0/style.css
index 0fb6eabc..e95a343f 100644
--- a/0.21.0/style.css
+++ b/0.21.0/style.css
@@ -6741,6 +6741,9 @@ header {
     display: none;
   }
 }
+.padded {
+  padding: 5px;
+}
 /**
  * Home
  */
@@ -6876,6 +6879,9 @@ html.docs-page #open-nav:checked ~ main {
   border-right: 1px solid #ccc;
   font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
 }
+.sidebar.no-filter {
+  padding-top: 20px;
+}
 .sidebar .filter {
   width: 100%;
   margin: 15px 0;
@@ -6895,6 +6901,10 @@ html.docs-page #open-nav:checked ~ main {
 .sidebar .toc li {
   margin: 0;
 }
+.sidebar .toc li.active {
+  background-color: #849;
+  color: white;
+}
 .sidebar .toc a {
   padding: 5px 15px;
   border-radius: 0;
diff --git a/Makefile b/Makefile
index ca363f95..3323d938 100644
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,19 @@
 GITBOOK = node_modules/.bin/gitbook
 JSDOC = node_modules/.bin/jsdoc
 LESS = node_modules/.bin/lessc
+YAML = node_modules/.bin/yaml2json
 
 JSDOC_FILES := $(shell find jsdoc -type f | sort)
 LESS_FILES := $(shell find less -name '*.less' | sort)
-
+EXAMPLE_FILES := $(shell find examples -name '*.json' | sort)
+YAML_FILES := $(shell find examples -name '*.yaml' | sort)
 
 .PHONY: all
 all: \
 	check-version \
 	$(VERSION)/tmp/README.md \
 	$(VERSION)/tmp/package.json \
+	yaml \
 	$(VERSION)/docs/dist/ramda.js \
 	$(VERSION)/docs/index.html \
 	$(VERSION)/docs/main.js \
@@ -21,12 +24,20 @@ all: \
 	$(VERSION)/fonts/glyphicons-halflings-regular.woff \
 	$(VERSION)/fonts/glyphicons-halflings-regular.woff2 \
 	$(VERSION)/style.css \
+	$(VERSION)/examples/index.html \
 	gitbook \
 	docs/dist/ramda.js \
 	docs/index.html \
 	docs/main.js \
 	index.html \
 	style.css \
+	examples/index.html \
+	
+.PHONY: clean
+clean: $(VERSION)/clean
+	
+$(VERSION)/clean:
+	rm -r $(VERSION)/*
 
 $(VERSION)/tmp/%:
 	mkdir -p '$(@D)'
@@ -36,7 +47,7 @@ $(VERSION)/docs/dist/ramda.js:
 	mkdir -p '$(@D)'
 	curl --silent 'https://raw.githubusercontent.com/ramda/ramda/v$(VERSION)/dist/ramda.js' >'$@'
 
-$(VERSION)/docs/index.html $(VERSION)/index.html: $(JSDOC_FILES)
+$(VERSION)/docs/index.html $(VERSION)/index.html $(VERSION)/examples/index.html: $(JSDOC_FILES)
 	VERSION='$(VERSION)' $(JSDOC) \
 	  --destination '$(VERSION)' \
 	  --template '$(<D)' \
@@ -58,6 +69,16 @@ docs/%: $(VERSION)/docs/%
 	mkdir -p '$(@D)'
 	cp '$<' '$@'
 
+examples/%: $(VERSION)/examples/%
+	mkdir -p '$(<D)'
+	cp -R '$@' '$<'	
+
+yaml: $(YAML_FILES)
+	mkdir -p $(VERSION)/examples/code
+	-@for file in $(YAML_FILES); do \
+			$(YAML) $$file > $(VERSION)/$${file%yaml}json; \
+    done
+
 .PHONY: index.html
 index.html: check-version
 	echo '<!DOCTYPE html><html><head><link rel="canonical" href="http://ramdajs.com/$(VERSION)/index.html" /><script>window.location = "$(VERSION)/index.html" + window.location.hash;</script></head><body></body></html>' >'$@'
diff --git a/README.md b/README.md
index 2a14ffbf..4676d31f 100644
--- a/README.md
+++ b/README.md
@@ -13,3 +13,30 @@ $ VERSION=X.Y.Z make
 	npm run server
 
 Then visit [localhost:8080](http://localhost:8080/) to view the docs.
+
+
+## Cookbook
+
+To add an example to the cookbook, simply add a `yaml` file in the `examples/code` folder, run `make` and issue a PR.
+
+Here's an example yaml file:
+
+```yaml
+title: Pick List Values by Index
+name: Pick List by Index
+description: "This example shows you how to specify multiple indexes of an array to retrieve multiple values from the array." 
+source: |
+      let R = require('ramda');
+
+      // :: [Number] -> [a] -> [a]
+      var pickIndexes = R.compose(R.values, R.pickAll);
+      pickIndexes([0, 2], ['a', 'b', 'c']);
+```
+
+**title** will be displayed on the page when the example is selected.
+
+**name** will be the text displayed in the left-hand menu.
+
+**description** is optional and will be displayed below the title if it is supplied.
+
+**source** is the code for the cookbook. In order for it to run in `Tonic`, please require all libraries used, including Ramda.
\ No newline at end of file
diff --git a/docs/index.html b/docs/index.html
index 4b8fbf37..3f3b0371 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -21,6 +21,11 @@
                 <li><a href="..">Home</a></li>
                 <li class="active"><a href="#">Documentation</a></li>
                 <li><a href="/repl?v=0.21.0">Try Ramda</a></li>
+                <li><a href="/examples">Cookbook</a></li>
+            </ul>
+        </div>
+        <div class='navbar-right'>
+            <ul class="nav navbar-nav">
                 <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
             </ul>
         </div>
diff --git a/docs/index.html.handlebars b/docs/index.html.handlebars
index 949a0f62..ea219265 100644
--- a/docs/index.html.handlebars
+++ b/docs/index.html.handlebars
@@ -21,6 +21,11 @@
                 <li><a href="..">Home</a></li>
                 <li class="active"><a href="#">Documentation</a></li>
                 <li><a href="/repl?v={{version}}">Try Ramda</a></li>
+                <li><a href="/examples">Cookbook</a></li>
+            </ul>
+        </div>
+        <div class='navbar-right'>
+            <ul class="nav navbar-nav">
                 <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
             </ul>
         </div>
diff --git a/examples/Index.html b/examples/Index.html
new file mode 100644
index 00000000..970f16f1
--- /dev/null
+++ b/examples/Index.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html class="docs-page">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Ramda Cookbook</title>
+  <link rel="stylesheet" type="text/css" href="../style.css">
+  <script src="https://embed.tonicdev.com"></script>
+</head>
+
+<body>
+  <input type="checkbox" id="open-nav" />
+  <header class="navbar navbar-fixed-top navbar-inverse container-fluid">
+    <div class="navbar-header">
+      <label class="open-nav" for="open-nav"></label>
+      <a class="navbar-brand" href="#">
+        <strong>Ramda</strong>
+        <span class="version">v0.21.0</span>      
+      </a>
+    </div>
+    <div class="navbar-left">
+      <ul class="nav navbar-nav">
+        <li><a href="/">Home</a></li>
+        <li><a href="/docs">Documentation</a></li>
+        <li><a href="/repl?v=0.21.0">Try Ramda</a></li>
+        <li class='active'><a href="#">Cookbook</a></li>
+      </ul>
+    </div>
+    <div class='navbar-right'>
+        <ul class="nav navbar-nav">
+            <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
+        </ul>
+    </div>
+  </header>
+  <aside class="sidebar no-filter container-fluid">
+        <ul class="nav nav-pills nav-stacked toc">
+            <li class='text-capitalize padded' data-file="../examples/code/apply.function.n.times.json">Apply function N times</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/convert.list.to.object.json">Convert List to Object</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/convert.object.to.array.json">Convert object to array</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/create.list.json">Create a list</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/diff.objects.json">Diff Objects</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/do.any.strings.appear.json">Any Duplicate Strings</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/filter.using.keys.and.values.json">Filter w/ Keys &amp; Vals</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/get.object.by.id.json">Get object by id</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/get.objects.methods.json">Get method names</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/increment.with.step.json">Increment with step</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/make.objects.out.of.keys.json">Make object from keys</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/map.keys.of.object.json"></li> 
+            <li class='text-capitalize padded' data-file="../examples/code/map.keys.to.objects.json">Map keys to objects</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/map.value.at.end.of.path.json">Map val at end of path</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/mess.with.dom.json">Mess with DOM</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/n.function.calls.json">Get n function calls</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/object.size.json">Object Size</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/pick-list.json">Pick List by Index</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/r.props.deep.fields.json">R.props for deep fields</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/ramda.fantasy.ajax.json">ramda-fantasy wrap AJAX</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/rename.keys.of.object.json">Rename keys</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/set.properties.if.dont.exist.json">Set non-existent properties</li> 
+            <li class='text-capitalize padded' data-file="../examples/code/specific.order.json">Functions in order</li> 
+        </ul>
+    </aside>
+  <main class="container-fluid">
+    <h1 class='title text-capitalize'>Cookbook</h1>
+    <div class='snippet'></div>    
+    <div id='tonic'></div>
+  </main>
+</body>
+<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
+<script>
+  (function(){
+            var notebook = Tonic.createNotebook({
+                element: document.getElementById("tonic"), 
+                source: '//Select an example to continue'
+            });             
+            
+            $('li').on('click', function(e){
+                let filename = $(e.currentTarget).data('file');
+                $('li').removeClass('active');
+                $(e.currentTarget).addClass('active');
+                
+                $.ajax({
+                    url: filename,
+                    dataType: 'text'
+                }).done(function(file){
+                    var example = JSON.parse(file);                  
+                    $('h1.title').text(example.title);
+                    if(example.description){
+                      $('div.snippet').html(example.description);  
+                    }
+                    
+                    notebook.setSource(example.source);
+                });         
+            });
+        })();
+</script>
+
+</html>
\ No newline at end of file
diff --git a/examples/Index.html.handlebars b/examples/Index.html.handlebars
new file mode 100644
index 00000000..9933db2a
--- /dev/null
+++ b/examples/Index.html.handlebars
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html class="docs-page">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Ramda Cookbook</title>
+  <link rel="stylesheet" type="text/css" href="../style.css">
+  <script src="https://embed.tonicdev.com"></script>
+</head>
+
+<body>
+  <input type="checkbox" id="open-nav" />
+  <header class="navbar navbar-fixed-top navbar-inverse container-fluid">
+    <div class="navbar-header">
+      <label class="open-nav" for="open-nav"></label>
+      <a class="navbar-brand" href="#">
+        <strong>Ramda</strong>
+        <span class="version">v{{version}}</span>      
+      </a>
+    </div>
+    <div class="navbar-left">
+      <ul class="nav navbar-nav">
+        <li><a href="/">Home</a></li>
+        <li><a href="/docs">Documentation</a></li>
+        <li><a href="/repl?v={{version}}">Try Ramda</a></li>
+        <li class='active'><a href="#">Cookbook</a></li>
+      </ul>
+    </div>
+    <div class='navbar-right'>
+        <ul class="nav navbar-nav">
+            <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
+        </ul>
+    </div>
+  </header>
+  <aside class="sidebar no-filter container-fluid">
+        <ul class="nav nav-pills nav-stacked toc">
+            {{#each files}}
+            <li class='text-capitalize padded' data-file="../examples/code/{{@key}}.json">{{name}}</li> 
+            {{/each}}
+        </ul>
+    </aside>
+  <main class="container-fluid">
+    <h1 class='title text-capitalize'>Cookbook</h1>
+    <div class='snippet'></div>    
+    <div id='tonic'></div>
+  </main>
+</body>
+<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
+<script>
+  (function(){
+            var notebook = Tonic.createNotebook({
+                element: document.getElementById("tonic"), 
+                source: '//Select an example to continue'
+            });             
+            
+            $('li').on('click', function(e){
+                let filename = $(e.currentTarget).data('file');
+                $('li').removeClass('active');
+                $(e.currentTarget).addClass('active');
+                
+                $.ajax({
+                    url: filename,
+                    dataType: 'text'
+                }).done(function(file){
+                    var example = JSON.parse(file);                  
+                    $('h1.title').text(example.title);
+                    if(example.description){
+                      $('div.snippet').html(example.description);  
+                    }
+                    
+                    notebook.setSource(example.source);
+                });         
+            });
+        })();
+</script>
+
+</html>
\ No newline at end of file
diff --git a/examples/code/apply.function.n.times.yaml b/examples/code/apply.function.n.times.yaml
new file mode 100644
index 00000000..88754420
--- /dev/null
+++ b/examples/code/apply.function.n.times.yaml
@@ -0,0 +1,15 @@
+title: Apply a given function N times
+name: Apply function N times
+description: 
+source: |
+      let R = require('ramda');
+
+      // applyN :: (a -> a) -> Number -> (a -> a)
+      const applyN = R.compose(R.reduceRight(R.compose, R.identity), R.repeat);
+      
+      applyN(x => x * x, 4)(2); //=> 65536 (2 -> 4 -> 16 -> 256 -> 65536)
+      
+      const isOdd = n => n % 2 == 1;
+      const collatz = n => isOdd(n) ? (3 * n + 1) : (n / 2);
+      
+      applyN(collatz, 5)(27);
\ No newline at end of file
diff --git a/examples/code/convert.list.to.object.yaml b/examples/code/convert.list.to.object.yaml
new file mode 100644
index 00000000..9a162034
--- /dev/null
+++ b/examples/code/convert.list.to.object.yaml
@@ -0,0 +1,12 @@
+title: Convert a list of property-lists (with header) into a list of objects
+name: Convert List to Object
+description:               
+source: |
+      let R = require('ramda');
+
+      const tsv = [
+        ['name',  'age', 'drink'], 
+        ['john',   23,   'wine'], 
+        ['maggie', 45,   'water']
+      ];
+      R.compose(R.apply(R.lift(R.zipObj)), R.splitAt(1))(tsv);
\ No newline at end of file
diff --git a/examples/code/convert.object.to.array.yaml b/examples/code/convert.object.to.array.yaml
new file mode 100644
index 00000000..eb560af6
--- /dev/null
+++ b/examples/code/convert.object.to.array.yaml
@@ -0,0 +1,11 @@
+title: Convert object to array
+name: Convert object to array
+description: 
+source: |
+      let R = require('ramda');
+
+      // convert :: {a} -> [{ word :: String, count :: a }]
+      const convert = R.compose(R.map(R.zipObj(['word', 'count'])), R.toPairs);
+      
+      convert({I: 2, it: 4, that: 1});
+      
\ No newline at end of file
diff --git a/examples/code/create.list.yaml b/examples/code/create.list.yaml
new file mode 100644
index 00000000..2e9fd25f
--- /dev/null
+++ b/examples/code/create.list.yaml
@@ -0,0 +1,9 @@
+title: Create a list
+name: Create a list
+description: This snippet will create a new list with the specified values. Check out https://clojuredocs.org/clojure.core/list.
+source: |
+      let R = require('ramda');
+      
+      //  list :: a... -> [a...]
+      var list = R.unapply(R.identity);
+      list(1, 2, 3);
diff --git a/examples/code/diff.objects.yaml b/examples/code/diff.objects.yaml
new file mode 100644
index 00000000..88f98293
--- /dev/null
+++ b/examples/code/diff.objects.yaml
@@ -0,0 +1,30 @@
+title: diffing objects
+name: Diff Objects
+description: similar to <a href="http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Maps.html#difference%28java.util.Map,%20java.util.Map%29">Guava's Maps Difference</a>              
+source: |
+      let R = require('ramda');
+
+      var groupObjBy = R.curry(R.pipe(
+        // Call groupBy with the object as pairs, passing only the value to the key function
+        R.useWith(R.groupBy, [R.useWith(__, [R.last]), R.toPairs]),
+        R.map(R.fromPairs)
+      ))
+      
+      var diffObjs = R.pipe(
+        R.useWith(R.mergeWith(R.merge), [R.map(R.objOf("leftValue")), R.map(R.objOf("rightValue"))]),
+        R.groupObjBy(R.cond([
+          [
+            R.both(R.has("leftValue"), R.has("rightValue")),
+            R.pipe(R.values, R.ifElse(R.apply(equals), R.always("common"), R.always("difference")))
+          ],
+          [R.has("leftValue"), R.always("onlyOnLeft")],
+          [R.has("rightValue"), R.always("onlyOnRight")],
+        ])),
+        R.evolve({
+          common: R.map(R.prop("leftValue")),
+          onlyOnLeft: R.map(R.prop("leftValue")),
+          onlyOnRight: R.map(R.prop("rightValue"))
+        })
+      );
+      
+      diffObjs({a: 1, c: 5, d: 4 }, {a: 1, b: 2, d: 7});
diff --git a/examples/code/do.any.strings.appear.yaml b/examples/code/do.any.strings.appear.yaml
new file mode 100644
index 00000000..89fa0a03
--- /dev/null
+++ b/examples/code/do.any.strings.appear.yaml
@@ -0,0 +1,10 @@
+title: Do any of these strings appear in another list?
+name: Any Duplicate Strings
+description: 
+source: |
+      let R = require('ramda');
+      //    overlaps :: [a] -> [a] -> Boolean
+      const overlaps = R.pipe(R.intersection, R.complement(R.isEmpty));
+      process.argv // ['node', 'script.js', '-v']
+      overlaps(['-v', '--verbose'], process.argv)
+        
\ No newline at end of file
diff --git a/examples/code/filter.using.keys.and.values.yaml b/examples/code/filter.using.keys.and.values.yaml
new file mode 100644
index 00000000..194f61b3
--- /dev/null
+++ b/examples/code/filter.using.keys.and.values.yaml
@@ -0,0 +1,16 @@
+title: Filter an object using keys as well as values
+name: "Filter w/ Keys & Vals"
+description: 
+source: |
+      let R = require('ramda');
+
+      const filterWithKeys = (pred, obj) => R.pipe(
+        R.toPairs, 
+        R.filter(R.apply(pred)), 
+        R.fromPairs
+      )(obj);
+      
+      filterWithKeys(
+        (key, val) => key.length === val, 
+        {red: 3, blue: 5, green: 5, yellow: 2}
+      );
\ No newline at end of file
diff --git a/examples/code/get.object.by.id.yaml b/examples/code/get.object.by.id.yaml
new file mode 100644
index 00000000..c9a8e272
--- /dev/null
+++ b/examples/code/get.object.by.id.yaml
@@ -0,0 +1,12 @@
+title: Get object by id
+name: Get object by id
+description: 
+source: |
+      let R = require('ramda');
+
+      //    findById :: String -> Array -> Object
+      const findById = R.converge(
+        R.find,
+        [R.pipe(R.nthArg(0), R.propEq("id")), R.nthArg(1)]
+      );
+      
\ No newline at end of file
diff --git a/examples/code/get.objects.methods.yaml b/examples/code/get.objects.methods.yaml
new file mode 100644
index 00000000..ae1b9d33
--- /dev/null
+++ b/examples/code/get.objects.methods.yaml
@@ -0,0 +1,16 @@
+title: Get an object's method names
+name: Get method names
+description: 
+source: |
+      let R = require('ramda');
+
+      //  methodNames :: Object -> [String]
+      var methodNames = R.compose(R.keys, R.pickBy(R.is(Function)));
+      
+      var obj = {
+        foo: true,
+        bar: function() {},
+        baz: function() {},
+      };
+      
+      methodNames(obj);
\ No newline at end of file
diff --git a/examples/code/increment.with.step.yaml b/examples/code/increment.with.step.yaml
new file mode 100644
index 00000000..aace7699
--- /dev/null
+++ b/examples/code/increment.with.step.yaml
@@ -0,0 +1,16 @@
+title: Create an incrementing or decrementing range of numbers with a step
+name: Increment with step
+description: 
+source: |
+      let R = require('ramda');
+
+      const rangeStep = (start, step, stop) => R.map(
+        n => start + step * n,
+        R.range(0, (1 + (stop - start) / step) >>> 0)
+      );
+      
+      console.log(rangeStep(1, 1, 4));   // [1, 2, 3, 4]
+      console.log(rangeStep(2, 2, 8));   // [2, 4, 6, 8]
+      console.log(rangeStep(0, 3, 10));  // [0, 3, 6, 9]
+      console.log(rangeStep(3, -2, -3)); // [3, 1, -1, -3]
+      
\ No newline at end of file
diff --git a/examples/code/make.objects.out.of.keys.yaml b/examples/code/make.objects.out.of.keys.yaml
new file mode 100644
index 00000000..e9a50ba0
--- /dev/null
+++ b/examples/code/make.objects.out.of.keys.yaml
@@ -0,0 +1,13 @@
+title: "Make an object out of keys, with values derived from them"
+name: Make object from keys
+description: 
+source: |
+      let R = require('ramda');
+      let fs = require('fs');
+
+      //    objFromKeys :: (String -> a) -> [String] -> {String: a}
+      const objFromKeys = R.curry((fn, keys) =>
+        R.zipObj(keys, R.map(fn, keys)));
+      const files = ['diary.txt', 'shopping.txt'];
+      objFromKeys(fs.readFileSync, files);
+      
\ No newline at end of file
diff --git a/examples/code/map.keys.of.object.yaml b/examples/code/map.keys.of.object.yaml
new file mode 100644
index 00000000..07457707
--- /dev/null
+++ b/examples/code/map.keys.of.object.yaml
@@ -0,0 +1,10 @@
+title: "Map keys of an object"
+description: 
+source: |
+      let R = require('ramda');
+
+      //    mapKeys :: (String -> String) -> Object -> Object
+      const mapKeys = R.curry((fn, obj) =>
+        R.fromPairs(R.map(R.adjust(fn, 0), R.toPairs(obj))));
+      mapKeys(R.toUpper, { a: 1, b: 2, c: 3 });
+        
\ No newline at end of file
diff --git a/examples/code/map.keys.to.objects.yaml b/examples/code/map.keys.to.objects.yaml
new file mode 100644
index 00000000..7759116f
--- /dev/null
+++ b/examples/code/map.keys.to.objects.yaml
@@ -0,0 +1,9 @@
+title: Map Keys To Objects
+name: Map keys to objects
+description:
+source: |
+      let R = require('ramda');
+      
+      const mapKeys = R.curry((fn, obj) =>
+          R.fromPairs(R.map(R.adjust(fn, 0), R.toPairs(obj))));
+          mapKeys(R.toUpper, { a: 1, b: 2, c: 3 });
\ No newline at end of file
diff --git a/examples/code/map.value.at.end.of.path.yaml b/examples/code/map.value.at.end.of.path.yaml
new file mode 100644
index 00000000..270527f5
--- /dev/null
+++ b/examples/code/map.value.at.end.of.path.yaml
@@ -0,0 +1,13 @@
+title: Map over the value at the end of a path
+name: Map val at end of path
+description: 
+source: |
+      let R = require('ramda');
+
+      // :: [String] -> (a -> b) -> {k: a} -> {k: b}
+      const mapPath = R.curry((path, f, obj) =>
+        R.assocPath(path, f(R.path(path, obj)), obj)
+      );
+      
+      mapPath(['a', 'b', 'c'], R.inc, {a: {b: {c: 3}}});
+      
\ No newline at end of file
diff --git a/examples/code/mess.with.dom.yaml b/examples/code/mess.with.dom.yaml
new file mode 100644
index 00000000..d1ba56f9
--- /dev/null
+++ b/examples/code/mess.with.dom.yaml
@@ -0,0 +1,20 @@
+title: Mess with the DOM
+name: Mess with DOM
+description: This example shows how to set styles so that all paragraphs are red.
+source: |
+      let R = require('ramda');
+      
+      // Get all descendants that match selector
+      // Note: NodeList is array-like so you can run ramda list functions on it.
+      //  cssQuery :: String -> Node -> NodeList
+      var cssQuery = R.invoker(1, 'querySelectorAll');
+
+      // Mutate style properties on an element
+      //  setStyle :: String -> String -> Element -> Element
+      var setStyle = R.assoc('style');
+
+      // Make all paragraphs and anchors red
+      R.pipe(
+          cssQuery('a, p'),
+          R.map(setStyle('color', 'red'))
+      )(document)
diff --git a/examples/code/n.function.calls.yaml b/examples/code/n.function.calls.yaml
new file mode 100644
index 00000000..33184c3f
--- /dev/null
+++ b/examples/code/n.function.calls.yaml
@@ -0,0 +1,7 @@
+title: Get n function calls as a list
+name: Get n function calls
+description: 
+source: |
+      let R = require('ramda');
+
+      R.map(R.call, R.repeat(Math.random, 5));
\ No newline at end of file
diff --git a/examples/code/object.size.yaml b/examples/code/object.size.yaml
new file mode 100644
index 00000000..e575172f
--- /dev/null
+++ b/examples/code/object.size.yaml
@@ -0,0 +1,29 @@
+title: Get Object Size
+name: Object Size
+description: 
+source: |
+      let R = require('ramda');
+
+      //    objSize :: Object -> Number
+      const objSize = R.nAry(1, R.pipe(
+        R.when(R.is(Object), R.keys),
+        R.when(R.is(Boolean), R.cond([[R.equals(false), R.always(null)], [R.T, R.always(1)]])),
+        R.when(R.is(Number), R.toString),
+        R.ifElse(R.isNil, R.always(0), R.length)
+      ));
+      console.log(objSize()); // 0
+      console.log(objSize(undefined)); // 0
+      console.log(objSize(null)); // 0
+      console.log(objSize(false)); // 0
+      console.log(objSize(true)); // 1
+      console.log(objSize('')); // 0
+      console.log(objSize('foo')); // 3
+      console.log(objSize(0)); // 1
+      console.log(objSize(13)); // 2
+      console.log(objSize(101)); // 3
+      console.log(objSize(0.01)); // 4
+      console.log(objSize({})); // 0
+      console.log(objSize({foo:undefined, bar:undefined})); // 2
+      console.log(objSize([])); // 0
+      console.log(objSize([undefined, undefined])); // 2
+      
\ No newline at end of file
diff --git a/examples/code/pick-list.yaml b/examples/code/pick-list.yaml
new file mode 100644
index 00000000..683280e0
--- /dev/null
+++ b/examples/code/pick-list.yaml
@@ -0,0 +1,9 @@
+title: Pick List Values by Index
+name: Pick List by Index
+description: "This example shows you how to specify multiple indexes of an array to retrieve multiple values from the array." 
+source: |
+      let R = require('ramda');
+
+      // :: [Number] -> [a] -> [a]
+      var pickIndexes = R.compose(R.values, R.pickAll);
+      pickIndexes([0, 2], ['a', 'b', 'c']);
\ No newline at end of file
diff --git a/examples/code/r.props.deep.fields.yaml b/examples/code/r.props.deep.fields.yaml
new file mode 100644
index 00000000..fcbaf75c
--- /dev/null
+++ b/examples/code/r.props.deep.fields.yaml
@@ -0,0 +1,14 @@
+title: Derivative of R.props for deep fields
+name: R.props for deep fields
+description:  
+source: |
+      let R = require('ramda');
+
+      var dotPath = R.useWith(R.path, R.split('.'));
+      var propsDotPath = R.useWith(R.ap, R.map(dotPath), R.of);
+      var obj = {
+          a: { b: { c: 1 } },
+          x: 2
+      };
+
+      propsDotPath(['a.b.c', 'x'], obj);
\ No newline at end of file
diff --git a/examples/code/ramda.fantasy.ajax.yaml b/examples/code/ramda.fantasy.ajax.yaml
new file mode 100644
index 00000000..5dae3d5d
--- /dev/null
+++ b/examples/code/ramda.fantasy.ajax.yaml
@@ -0,0 +1,59 @@
+title: Use ramda-fantasy Future to wrap AJAX
+name: ramda-fantasy wrap AJAX
+description:  
+source: |
+      var Future = require('ramda-fantasy').Future;
+      // Wrap ajax in a future
+      //  fetch :: String -> Future String
+      var fetch = function(url) {
+        return new Future(function(rej, res) {
+          var oReq = new XMLHttpRequest();
+          oReq.addEventListener('load', res, false);
+          oReq.addEventListener('error', rej, false);
+          oReq.addEventListener('abort', rej, false);
+          oReq.open('get', url, true);
+          oReq.send();
+        });
+      };
+      
+      // Could use Either instead of Future but they work about the same.
+      //  parseJSON :: String -> Future Object
+      var parseJSON = function(str) {
+        return new Future(function(rej, res) {
+          try {
+            res(JSON.parse(str));
+          } catch (err) {
+            rej({ error: 'json parse error' });
+          }
+        });
+      };
+      
+      // We have
+      // String -> Future String
+      // And
+      // String -> Future Object
+      // So we can .chain() them together
+      var fetchJSON = fetch.chain(parseJSON);
+      
+      // Get the items out of it?
+      //  fetchItems :: Future Object -> Future []
+      var fetchItems = fetchJSON.map(R.prop('items'));
+      
+      // BTW at this point in the code the request still hasn't been sent
+      
+      // Filter the response?
+      // Have to map first to get at the contents of the future then filter
+      //  fetchNewItems :: Future [Object] -> Future [Object]
+      var fetchNewItems = fetchItems.map(R.filter(R.prop('new')));
+      
+      // Just get the titles of the items
+      //  getNewTitles :: Future [Object] -> Future [String]
+      var getNewTitles = fetchNewItems.map(R.map('title'));
+      
+      // Finally do something
+      getNewTitles('/products.json').fork(console.error, console.log);
+      // Now the AJAX req is sent and will log success or failure to console.
+      
+      // Bonus: Make one ajax request dependent on another
+      fetchDependent = fetchJSON.map(R.prop('url')).chain(fetch);
+      fetchDependent('urls.json').fork(console.error, console.log);
\ No newline at end of file
diff --git a/examples/code/rename.keys.of.object.yaml b/examples/code/rename.keys.of.object.yaml
new file mode 100644
index 00000000..f68f72dc
--- /dev/null
+++ b/examples/code/rename.keys.of.object.yaml
@@ -0,0 +1,26 @@
+title: Rename keys of an object
+name: Rename keys
+description: 
+source: |
+      let R = require('ramda');
+
+      /**
+      * Creates a new object with the own properties of the provided object, but the
+      * keys renamed according to the keysMap object as `{oldKey: newKey}`.
+      * When some key is not found in the keysMap, then it's passed as-is.
+      *
+      * Keep in mind that in the case of keys conflict is behaviour undefined and
+      * the result may vary between various JS engines!
+      *
+      * @sig {a: b} -> {a: *} -> {b: *}
+      */
+      const renameKeys = R.curry((keysMap, obj) => {
+        return R.reduce((acc, key) => {
+          acc[keysMap[key] || key] = obj[key];
+          return acc;
+        }, {}, R.keys(obj));
+      });
+      
+      const input = { firstName: 'Elisia', age: 22, type: 'human' }
+
+      renameKeys({ firstName: 'name', type: 'kind', foo: 'bar' })(input)  
\ No newline at end of file
diff --git a/examples/code/set.properties.if.dont.exist.yaml b/examples/code/set.properties.if.dont.exist.yaml
new file mode 100644
index 00000000..db9e8bc9
--- /dev/null
+++ b/examples/code/set.properties.if.dont.exist.yaml
@@ -0,0 +1,13 @@
+title: Set properties only if they don't exist
+name: Set non-existent properties
+description: "Useful for passing defaults, similar to lodash's _.defaults."
+source: |
+      let R = require('ramda');
+
+      //  defaults :: Object -> Object -> Object
+      var defaults = R.flip(R.merge);
+      
+      // process.env.SECRET overwrites deadbeef if it exists
+      defaults(process.env, {
+        SECRET: 'deadbeef'
+      });
\ No newline at end of file
diff --git a/examples/code/specific.order.yaml b/examples/code/specific.order.yaml
new file mode 100644
index 00000000..9b6e18b9
--- /dev/null
+++ b/examples/code/specific.order.yaml
@@ -0,0 +1,9 @@
+title: Apply a list of functions in a specific order into a list of values
+name: Functions in order
+description:  
+source: |
+      let R = require('ramda');
+
+      const {red, green, blue} = require('chalk');
+      const disco = R.pipe(R.zipWith(R.call, [ red, green, blue ]), R.join(' '));
+      console.log(disco([ 'foo', 'bar', 'xyz' ]));
\ No newline at end of file
diff --git a/jsdoc/publish.js b/jsdoc/publish.js
index f649d391..a65967de 100644
--- a/jsdoc/publish.js
+++ b/jsdoc/publish.js
@@ -6,6 +6,7 @@ var hljs = require('highlight.js');
 var helper = require('jsdoc/util/templateHelper');
 var marked = require('marked');
 
+var requireDir = require('require-dir-all');
 
 if (!Object.prototype.hasOwnProperty.call(process.env, 'VERSION')) {
   throw new Error('No environment variable named "VERSION"');
@@ -13,11 +14,11 @@ if (!Object.prototype.hasOwnProperty.call(process.env, 'VERSION')) {
 var VERSION = process.env.VERSION;
 
 
-var headOr = function(x, xs) {
+var headOr = function (x, xs) {
   return xs.length === 0 ? x : xs[0];
 };
 
-var chain = function(f, xs) {
+var chain = function (f, xs) {
   var result = [];
   for (var idx = 0; idx < xs.length; idx += 1) {
     result = result.concat(f(xs[idx]));
@@ -25,7 +26,7 @@ var chain = function(f, xs) {
   return result;
 };
 
-var valuesForTitle = function(title, xs) {
+var valuesForTitle = function (title, xs) {
   var result = [];
   for (var idx = 0; idx < xs.length; idx += 1) {
     if (xs[idx].title === title) {
@@ -35,36 +36,36 @@ var valuesForTitle = function(title, xs) {
   return result;
 };
 
-var prettifySig = function(s) {
+var prettifySig = function (s) {
   return s.replace(/[.][.][.]/g, '\u2026').replace(/->/g, '\u2192');
 };
 
-var prettifyCode = function(s) {
+var prettifyCode = function (s) {
   return hljs.highlight('javascript', s.join('\n').replace(/^[ ]{5}/gm, '')).value;
 };
 
 //  simplifySee :: [String] -> [String]
 //
 //  Handles any combination of comma-separated and multi-line @see annotations.
-var simplifySee = function(xs) {
+var simplifySee = function (xs) {
   var result = [];
-  xs.forEach(function(x) {
-    x.split(/\s*,\s*/).forEach(function(s) {
+  xs.forEach(function (x) {
+    x.split(/\s*,\s*/).forEach(function (s) {
       result.push(s.replace(/^R[.]/, ''));
     });
   });
   return result;
 };
 
-var simplifyData = function(d) {
+var simplifyData = function (d) {
   return {
-    aka: chain(function(s) { return s.split(/,\s*/); }, valuesForTitle('aka', d.tags)),
+    aka: chain(function (s) { return s.split(/,\s*/); }, valuesForTitle('aka', d.tags)),
     category: headOr('', valuesForTitle('category', d.tags)),
     deprecated: d.deprecated == null ? '' : d.deprecated,
     description: d.description == null ? '' : marked(d.description),
     example: d.examples == null ? [] : prettifyCode(d.examples),
     name: d.name == null ? '' : d.name,
-    params: d.params == null ? [] : d.params.map(function(p) {
+    params: d.params == null ? [] : d.params.map(function (p) {
       return {
         type: p.type.names[0] || '',
         description: marked(p.description || ''),
@@ -73,19 +74,19 @@ var simplifyData = function(d) {
     }),
     returns: {
       type:
-        d.returns != null &&
+      d.returns != null &&
         d.returns[0] != null &&
         d.returns[0].type != null &&
         d.returns[0].type.names != null &&
         d.returns[0].type.names[0] != null ?
-          d.returns[0].type.names[0] :
-          '',
+        d.returns[0].type.names[0] :
+        '',
       description:
-        d.returns != null &&
+      d.returns != null &&
         d.returns[0] != null &&
         d.returns[0].description != null ?
-          marked(d.returns[0].description) :
-          '',
+        marked(d.returns[0].description) :
+        '',
     },
     see: d.see == null ? [] : simplifySee(d.see),
     sigs: valuesForTitle('sig', d.tags).map(prettifySig),
@@ -94,37 +95,43 @@ var simplifyData = function(d) {
   };
 };
 
-var readFile = function(filename) {
-  return fs.readFileSync(filename, {encoding: 'utf8'});
+var readFile = function (filename) {
+  return fs.readFileSync(filename, { encoding: 'utf8' });
 };
 
-var render = function(templateFile, outputFile, context) {
+var render = function (templateFile, outputFile, context) {
   fs.writeFileSync(outputFile,
-                   handlebars.compile(readFile(templateFile))(context),
-                   {encoding: 'utf8'});
+    handlebars.compile(readFile(templateFile))(context),
+    { encoding: 'utf8' });
 };
 
-exports.publish = function(data, opts) {
+exports.publish = function (data, opts) {
   var context = {
     docs: helper.prune(data)()
-          .order('name, version, since')
-          .filter({kind: ['function', 'constant']})
-          .get()
-          .filter(function(x) { return x.access !== 'private'; })
-          .map(simplifyData),
+      .order('name, version, since')
+      .filter({ kind: ['function', 'constant'] })
+      .get()
+      .filter(function (x) { return x.access !== 'private'; })
+      .map(simplifyData),
     readme: new handlebars.SafeString(marked(readFile(VERSION + '/tmp/README.md'))),
     version: require('../' + VERSION + '/tmp/package.json').version,
+    files: requireDir('../' + VERSION + '/examples/code', {includeFiles: /^.*\.json$/})
   };
 
   render('jsdoc/templates/index.html.handlebars',
-         path.resolve(opts.destination, 'index.html'),
-         context);
+    path.resolve(opts.destination, 'index.html'),
+    context);
 
   render('docs/index.html.handlebars',
-         path.resolve(opts.destination, 'docs/index.html'),
-         context);
+    path.resolve(opts.destination, 'docs/index.html'),
+    context);
 
   render('repl/index.html.handlebars',
-         path.resolve('./repl/index.html'),
-         context); 
+    path.resolve('./repl/index.html'),
+    context);
+
+  render('examples/index.html.handlebars',
+    path.resolve('./examples/index.html'),
+    context);
+
 };
diff --git a/jsdoc/templates/index.html.handlebars b/jsdoc/templates/index.html.handlebars
index cf1484e7..845af7d0 100644
--- a/jsdoc/templates/index.html.handlebars
+++ b/jsdoc/templates/index.html.handlebars
@@ -21,6 +21,11 @@
                 <li class="active"><a href="#">Home</a></li>
                 <li><a href="docs">Documentation</a></li>
                 <li><a href="/repl?v={{version}}">Try Ramda</a></li>
+                <li><a href="examples">Cookbook</a></li>
+            </ul>
+        </div>
+        <div class='navbar-right'>
+            <ul class="nav navbar-nav">
                 <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
             </ul>
         </div>
diff --git a/less/layout.less b/less/layout.less
index 35813c5e..dcee6817 100644
--- a/less/layout.less
+++ b/less/layout.less
@@ -29,6 +29,10 @@ header {
     }
 }
 
+.padded {
+    padding: 5px;
+}
+
 /**
  * Home
  */
diff --git a/less/sidebar.less b/less/sidebar.less
index ae97cbc9..5cf7b270 100644
--- a/less/sidebar.less
+++ b/less/sidebar.less
@@ -5,6 +5,10 @@
     border-right: @border;
     font-family: @font-family-monospace;
 
+    &.no-filter {
+        padding-top: 20px;
+    }
+    
     .filter {
         width: 100%;
         margin: 15px 0;
@@ -29,6 +33,11 @@
 
         li {
             margin: 0;
+            
+            &.active {
+                background-color: #849;
+                color: white;
+            }
         }
 
         a {
diff --git a/package.json b/package.json
index c880c537..7fa42ddf 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
     "handlebars": "2.x.x",
     "highlight.js": "8.x.x",
     "http-server": "0.8.x",
+    "js-yaml": "^3.6.0",
     "jsdoc": "3.3.x",
     "less": "2.5.x",
     "marked": "0.3.x"
@@ -21,5 +22,8 @@
   "scripts": {
     "jsdoc": "jsdoc --destination ./docs --template . ./docs/dist/ramda.js",
     "server": "http-server"
+  },
+  "dependencies": {
+    "require-dir-all": "^0.4.9"
   }
 }
diff --git a/repl/index.html b/repl/index.html
index 76270615..0e58e7e7 100644
--- a/repl/index.html
+++ b/repl/index.html
@@ -53,10 +53,16 @@
                 <ul class="nav navbar-nav">
                     <li><a href="/">Home</a></li>
                     <li><a href="/docs">Documentation</a></li>
-		    <li class="active"><a href="/repl?v=0.21.0">Try Ramda</a></li>
-                    <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
+		            <li class="active"><a href="/repl?v=0.21.0">Try Ramda</a></li>
+                    <li><a href="/examples">Cookbook</a></li>
                 </ul>
+                <div class='navbar-right'>
+                    <ul class="nav navbar-nav">
+                        <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
+                    </ul>
+                </div>
             </div>
+            
             <!--/.nav-collapse -->
         </div>
     </div>
diff --git a/repl/index.html.handlebars b/repl/index.html.handlebars
index 9b1eac85..f7d6ddd2 100644
--- a/repl/index.html.handlebars
+++ b/repl/index.html.handlebars
@@ -53,10 +53,16 @@
                 <ul class="nav navbar-nav">
                     <li><a href="/">Home</a></li>
                     <li><a href="/docs">Documentation</a></li>
-		    <li class="active"><a href="/repl?v={{version}}">Try Ramda</a></li>
-                    <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
+		            <li class="active"><a href="/repl?v={{version}}">Try Ramda</a></li>
+                    <li><a href="/examples">Cookbook</a></li>
                 </ul>
+                <div class='navbar-right'>
+                    <ul class="nav navbar-nav">
+                        <li><a href="https://github.com/ramda/ramda">GitHub</a></li>
+                    </ul>
+                </div>
             </div>
+            
             <!--/.nav-collapse -->
         </div>
     </div>
diff --git a/style.css b/style.css
index 0fb6eabc..e95a343f 100644
--- a/style.css
+++ b/style.css
@@ -6741,6 +6741,9 @@ header {
     display: none;
   }
 }
+.padded {
+  padding: 5px;
+}
 /**
  * Home
  */
@@ -6876,6 +6879,9 @@ html.docs-page #open-nav:checked ~ main {
   border-right: 1px solid #ccc;
   font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
 }
+.sidebar.no-filter {
+  padding-top: 20px;
+}
 .sidebar .filter {
   width: 100%;
   margin: 15px 0;
@@ -6895,6 +6901,10 @@ html.docs-page #open-nav:checked ~ main {
 .sidebar .toc li {
   margin: 0;
 }
+.sidebar .toc li.active {
+  background-color: #849;
+  color: white;
+}
 .sidebar .toc a {
   padding: 5px 15px;
   border-radius: 0;