To run an execution time test on this page, run the profiler from your browser's developer tools and measure the running time of a page refresh. (Lower is better)
+
+
+
diff --git a/archive/v0.1/comparisons/backbone.parsing.html b/archive/v0.1/comparisons/backbone.parsing.html
new file mode 100644
index 00000000..e30e1eaf
--- /dev/null
+++ b/archive/v0.1/comparisons/backbone.parsing.html
@@ -0,0 +1,4 @@
+
+
+
+To run an execution time test on this page, run the profiler from your browser's developer tools and measure the running time of a page refresh. (Lower is better)
\ No newline at end of file
diff --git a/archive/v0.1/comparisons/backbone.rendering.html b/archive/v0.1/comparisons/backbone.rendering.html
new file mode 100644
index 00000000..07f38489
--- /dev/null
+++ b/archive/v0.1/comparisons/backbone.rendering.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
To run an execution time test on this page, run the profiler from your browser's developer tools and measure the running time of a page refresh. (Lower is better)
+
+
+
+
+
+
diff --git a/archive/v0.1/comparisons/backbone.safety.html b/archive/v0.1/comparisons/backbone.safety.html
new file mode 100644
index 00000000..e5a71e08
--- /dev/null
+++ b/archive/v0.1/comparisons/backbone.safety.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/archive/v0.1/comparisons/jquery.parsing.html b/archive/v0.1/comparisons/jquery.parsing.html
new file mode 100644
index 00000000..1fa16592
--- /dev/null
+++ b/archive/v0.1/comparisons/jquery.parsing.html
@@ -0,0 +1,2 @@
+
+To run an execution time test on this page, run the profiler from your browser's developer tools and measure the running time of a page refresh. (Lower is better)
\ No newline at end of file
diff --git a/archive/v0.1/comparisons/jquery.rendering.html b/archive/v0.1/comparisons/jquery.rendering.html
new file mode 100644
index 00000000..dde611ec
--- /dev/null
+++ b/archive/v0.1/comparisons/jquery.rendering.html
@@ -0,0 +1,17 @@
+
+
+
+
To run an execution time test on this page, run the profiler from your browser's developer tools and measure the running time of a page refresh. (Lower is better)
+
+
+
+
diff --git a/archive/v0.1/comparisons/jquery.safety.html b/archive/v0.1/comparisons/jquery.safety.html
new file mode 100644
index 00000000..e9667269
--- /dev/null
+++ b/archive/v0.1/comparisons/jquery.safety.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/archive/v0.1/comparisons/mithril.parsing.html b/archive/v0.1/comparisons/mithril.parsing.html
new file mode 100644
index 00000000..c2957a15
--- /dev/null
+++ b/archive/v0.1/comparisons/mithril.parsing.html
@@ -0,0 +1,2 @@
+
+To run an execution time test on this page, run the profiler from your browser's developer tools and measure the running time of a page refresh. (Lower is better)
\ No newline at end of file
diff --git a/archive/v0.1/comparisons/mithril.rendering.html b/archive/v0.1/comparisons/mithril.rendering.html
new file mode 100644
index 00000000..717f5d5e
--- /dev/null
+++ b/archive/v0.1/comparisons/mithril.rendering.html
@@ -0,0 +1,20 @@
+
+
+
+
To run an execution time test on this page, run the profiler from your browser's developer tools and measure the running time of a page refresh. (Lower is better)
To run the execution time tests below, click on their respective links, run the profiler from your desired browser's developer tools and measure the running time of a page refresh. (Lower is better)
Mithril templates are safe by default, i.e. you can't unintentionally create security holes.
+
To run the tests for each framework, click on the respective links. If you see an alert box, ensuring security with that framework is more work for you.
If you already have your HTML written and want to convert it into a Mithril template, paste the HTML below and press the "Convert" button.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/archive/v0.1/tools/template-converter.js b/archive/v0.1/tools/template-converter.js
new file mode 100644
index 00000000..5501df8e
--- /dev/null
+++ b/archive/v0.1/tools/template-converter.js
@@ -0,0 +1,89 @@
+var templateConverter = {};
+
+templateConverter.DOMFragment = function(markup) {
+ if (markup.indexOf(" -1) return [new DOMParser().parseFromString(markup, "text/html").childNodes[1]]
+ var container = document.createElement("div");
+ container.insertAdjacentHTML("beforeend", markup);
+ return container.childNodes;
+}
+templateConverter.VirtualFragment = function recurse(domFragment) {
+ var virtualFragment = [];
+ for (var i = 0, el; el = domFragment[i]; i++) {
+ if (el.nodeType == 3) {
+ virtualFragment.push(el.nodeValue);
+ }
+ else {
+ var attrs = {};
+ for (var j = 0, attr; attr = el.attributes[j]; j++) {
+ attrs[attr.name] = attr.value;
+ }
+
+ virtualFragment.push({tag: el.tagName.toLowerCase(), attrs: attrs, children: recurse(el.childNodes)});
+ }
+ }
+ return virtualFragment;
+}
+templateConverter.Template = function recurse() {
+ if (Object.prototype.toString.call(arguments[0]) == "[object String]") {
+ return new recurse(new templateConverter.VirtualFragment(new templateConverter.DOMFragment(arguments[0])));
+ }
+
+ var virtualFragment = arguments[0], level = arguments[1]
+ if (!level) level = 1;
+
+ var tab = "\n" + new Array(level + 1).join("\t");
+ var virtuals = [];
+ for (var i = 0, el; el = virtualFragment[i]; i++) {
+ if (typeof el == "string") {
+ if (el.match(/\t| {2,}/g) && el.trim().length == 0) virtuals.indented = true;
+ else virtuals.push('"' + el.replace(/"/g, '\\"').replace(/\r/g, "\\r").replace(/\n/g, "\\n") + '"');
+ }
+ else {
+ var virtual = "";
+ if (el.tag != "div") virtual += el.tag;
+ if (el.attrs["class"]) {
+ virtual += "." + el.attrs["class"].replace(/\t+/g, " ").split(" ").join(".");
+ delete el.attrs["class"];
+ }
+ var attrNames = Object.keys(el.attrs).sort()
+ for (var j = 0, attrName; attrName = attrNames[j]; j++) {
+ if (attrName != "style") virtual += "[" + attrName + "='" + el.attrs[attrName].replace(/'/g, "\\'") + "']";
+ }
+ virtual = '"' + virtual + '"';
+
+ var style = ""
+ if (el.attrs.style) {
+ virtual += ", {style: " + ("{\"" + el.attrs.style.replace(/:/g, "\": \"").replace(/;/g, "\", \"") + "}").replace(/, "}|"}/, "}") + "}"
+ }
+
+ if (el.children.length > 0) {
+ virtual += ", " + recurse(el.children, level + 1);
+ }
+ virtual = "m(" + virtual + ")";
+ virtuals.push(virtual);
+ }
+ }
+ if (!virtuals.indented) tab = "";
+
+ var isInline = virtuals.length == 1 && virtuals[0].charAt(0) == '"';
+ var template = isInline ? virtuals.join(", ") : "[" + tab + virtuals.join("," + tab) + tab.slice(0, -1) + "]";
+ return new String(template);
+}
+
+templateConverter.controller = function() {
+ this.source = m.prop("");
+ this.output = m.prop("");
+
+ this.convert = function() {
+ return this.output(new templateConverter.Template(this.source()));
+ };
+
+};
+
+templateConverter.view = function(ctrl) {
+ return [
+ m("textarea", {autofocus: true, style: {width:"100%", height: "40%"}, onchange: m.withAttr("value", ctrl.source)}, ctrl.source()),
+ m("button", {onclick: ctrl.convert.bind(ctrl)}, "Convert"),
+ m("textarea", {style: {width:"100%", height: "40%"}}, ctrl.output())
+ ];
+};
\ No newline at end of file
diff --git a/docs/auto-redrawing.md b/docs/auto-redrawing.md
new file mode 100644
index 00000000..fac7299f
--- /dev/null
+++ b/docs/auto-redrawing.md
@@ -0,0 +1,109 @@
+## Integrating with The Auto-Redrawing System
+
+If you need to do custom asynchronous calls without using Mithril's API, and find that your views are not redrawing, or that you're being forced to call [`m.redraw`](mithril.redraw.md) manually, you should consider using `m.startComputation` / `m.endComputation` so that Mithril can intelligently auto-redraw once your custom code finishes running.
+
+In order to integrate asynchronous code to Mithril's autoredrawing system, you should call `m.startComputation` BEFORE making an asynchronous call, and `m.endComputation` after the asynchronous callback completes.
+
+```javascript
+//this service waits 1 second, logs "hello" and then notifies the view that
+//it may start redrawing (if no other asynchronous operations are pending)
+var doStuff = function() {
+ m.startComputation(); //call `startComputation` before the asynchronous `setTimeout`
+
+ setTimeout(function() {
+ console.log("hello");
+
+ m.endComputation(); //call `endComputation` at the end of the callback
+ }, 1000);
+};
+```
+
+To integrate synchronous code, call `m.startComputation` at the beginning of the method, and `m.endComputation` at the end.
+
+```javascript
+window.onfocus = function() {
+ m.startComputation(); //call before everything else in the event handler
+
+ doStuff();
+
+ m.endComputation(); //call after everything else in the event handler
+}
+```
+
+For each `m.startComputation` call a library makes, it MUST also make one and ONLY one corresponding `m.endComputation` call.
+
+You should not use these methods if your code is intended to run repeatedly (e.g. by using `setInterval`). If you want to repeatedly redraw the view without necessarily waiting for user input, you should manually call [`m.redraw`](mithril.redraw.md) within the repeatable context.
+
+
+---
+
+### Integrating multiple execution threads
+
+When [integrating with third party libraries](integration.md), you might find that you need to call asynchronous methods from outside of Mithril's API.
+
+In order to integrate non-trivial asynchronous code to Mithril's auto-redrawing system, you need to ensure all execution threads call `m.startComputation` / `m.endComputation`.
+
+An execution thread is basically any amount of code that runs before other asynchronous threads start to run.
+
+Integrating multiple execution threads can be done in a two different ways: in a layered fashion or in comprehensive fashion
+
+#### Layered integration
+
+Layered integration is recommended for modular code where many different APIs may be put together at the application level.
+
+Below is an example where various methods implemented with a third party library can be integrated in layered fashion: any of the methods can be used in isolation or in combination.
+
+Notice how `doBoth` repeatedly calls `m.startComputation` since that method calls both `doSomething` and `doAnother`. This is perfectly valid: there are three asynchronous computations pending after the `jQuery.when` method is called, and therefore, three pairs of `m.startComputation` / `m.endComputation` in play.
+
+```javascript
+var doSomething = function(callback) {
+ m.startComputation(); //call `startComputation` before the asynchronous AJAX request
+
+ return jQuery.ajax("/something").done(function() {
+ if (callback) callback();
+
+ m.endComputation(); //call `endComputation` at the end of the callback
+ });
+};
+var doAnother = function(callback) {
+ m.startComputation(); //call `startComputation` before the asynchronous AJAX request
+
+ return jQuery.ajax("/another").done(function() {
+ if (callback) callback();
+ m.endComputation(); //call `endComputation` at the end of the callback
+ });
+};
+var doBoth = function(callback) {
+ m.startComputation(); //call `startComputation` before the asynchronous synchronization method
+
+ jQuery.when(doSomething(), doAnother()).then(function() {
+ if (callback) callback();
+
+ m.endComputation(); //call `endComputation` at the end of the callback
+ })
+};
+```
+
+#### Comprehensive integration
+
+Comprehensive integration is recommended if integrating a monolithic series of asynchronous operations. In contrast to layered integration, it minimizes the number of `m.startComputation` / `m.endComputation` to avoid clutter.
+
+The example below shows a convoluted series of AJAX requests implemented with a third party library.
+
+```javascript
+var doSomething = function(callback) {
+ m.startComputation(); //call `startComputation` before everything else
+
+ jQuery.ajax("/something").done(function() {
+ doStuff();
+ jQuery.ajax("/another").done(function() {
+ doMoreStuff();
+ jQuery.ajax("/more").done(function() {
+ if (callback) callback();
+
+ m.endComputation(); //call `endComputation` at the end of everything
+ });
+ });
+ });
+};
+```
\ No newline at end of file
diff --git a/docs/change-log.md b/docs/change-log.md
new file mode 100644
index 00000000..33b35777
--- /dev/null
+++ b/docs/change-log.md
@@ -0,0 +1,3 @@
+## Change Log
+
+v0.1 - Initial release
\ No newline at end of file
diff --git a/docs/comparison.md b/docs/comparison.md
new file mode 100644
index 00000000..3217b95c
--- /dev/null
+++ b/docs/comparison.md
@@ -0,0 +1,135 @@
+## How is Mithril Different from Other Frameworks
+
+There are a lot of different Javascript MVC frameworks and evaluating their merits and shortcomings can be a daunting task.
+
+This page aims to provide a comparison between Mithril and some of the most widely used frameworks, as well as some of the younger, but relevant ones.
+
+### Code Size
+
+One of the most obvious differences between Mithril and most frameworks is in file size: Mithril is less than 3kb gzipped and has no dependencies on other libraries.
+
+Note that while a small gzipped size can look appealing, that number is often used to "hide the weight" of the uncompressed code: remember that the decompressed Javascript still needs to be parsed and evaluated on every page load, and this cost (which can be in the dozens of milliseconds range for some frameworks in some browsers) cannot be cached.
+
+This cost might be less of a concern in single page apps, but not necessarily if the app is typically opened simultaneously in multiple tabs, or in less powerful devices.
+
+The performance tests in the homepage show execution times for parsing and evaluation of Mithril's code, compared to some popular frameworks. As you can see, it paints a much less flattering picture for some frameworks than when we look at gzipped size alone.
+
+### Documentation
+
+Another point of comparison is documentation. Most of the popular frameworks have at least a bare minimum amount of documentation nowadays, but many leave a bit to be desired: some lack usage examples, and some frameworks' communities need to rely heavily on third party sites for explanations of more advanced topics, and sometimes even for learning the basics.
+
+This is a problem particularly for frameworks that had breaking changes in the past: It's common to find answers in StackOverflow that are out-of-date and no longer work with the latest version of said frameworks.
+
+Mithril has more documentation in this site than the amount of code in the framework, and none of the documentation is auto-generated.
+
+All API points are explained in prose, and have code examples. Because the entire documentation is hand-crafted, you get the benefit of actually having explanations for things that documentation generator tools don't support well (for example, interfaces and callback parameter documentation).
+
+In addition, this guide section covers topics related to how to fit all the pieces together.
+
+From the get-go, Mithril's build system produces archived versions of the code and documentation so that you'll never be stuck without docs for out-of-date versions.
+
+Given how young Mithril is, hopefully you can appreciate the level of commitment for providing good documentation.
+
+### Architecture
+
+In terms of architecture, one of Mithril's main differences is that it does not provide base classes to extend from.
+
+It's often said that *frameworks*, in contrast to *libraries*, dictate how code should be written. In this sense, one could argue that Mithril isn't really a framework.
+
+Instead of locking developers down to very specific implementations of design patterns, Mithril's approach is to provide an idiomatic pattern to follow, and tools to aid the developer when required. This approach means that developers can get discoverable codebases without necessarily getting locked into the framework.
+
+One related difference is that other frameworks often hard-coded base classes where every conceivable convenience method are inherited by the developer's classes (remember, in Javascript, this can mean copying all of the utility methods over to the child class, regardless of whether they're going to be used or now).
+
+Mithril's on-demand tooling approach means there are no hidden performance costs when implementing core MVC patterns, and there's also no extra learning curve for framework-specific syntax for those patterns.
+
+### View Layer Paradigm
+
+Some of the older frameworks among the popular ones (out-of-the-box jQuery and Backbone, specifically) take a more procedural paradigm when it comes to the view layer: this means every action requires the developer to write custom view-level code to handle it.
+
+This can get noticeably bulky when you look at thing like collections: you often need to implement insertion code and deletion code, in addition to a "draw everything" routine for performance. And this is for every list that needs to be displayed in some way.
+
+Mithril's view layer paradigm is designed be **declarative**, much like HTML, such that the same code implicitly does everything it needs to. As it turns out, this design decision is actually a compromise: it offers the benefit of decreased application code complexity at the cost of some performance loss. However, as the performance tests in the homepage show, this does not necessarily hurt Mithril in a meaningful way.
+
+---
+
+## Specific Framework Comparisons
+
+Warning: this section is likely biased. Take it with a grain of salt.
+
+### jQuery
+
+jQuery is ubiquitous and has a large ecosystem, but it's not an MVC framework.
+
+There's no idiomatic way to organize jQuery code in an MVC pattern and many frameworks were created specifically to overcome that shortcoming.
+
+As summarized above, Mithril differs from jQuery by allowing DOM-related code to be written largely in a declarative style (thereby decreasing code complexity), in addition to providing an idiomatic way to structure applications.
+
+One other difference that is extremely clear is the treatment of data. In jQuery it's common to use the DOM as a data storage mechanism, whereas Mithril encourages data to exist in an isolated model layer.
+
+### Backbone
+
+Backbone was originally designed as a way to structure jQuery-based applications. One of its selling points is that it allows developers to leverage their existing jQuery knowledge, while providing some "walls" to organize the code in a more structured manner.
+
+As with jQuery, Mithril differs from Backbone by enforcing view code to be written in a declarative style.
+
+Another marking difference is that Backbone is workflow agnostic, that is, there's no one idiomatic way to organize applications. This is good for framework adoption, but not necessarily ideal for team scalability and codebase discoverability.
+
+In contrast, Mithril encourages that applications be developed using the patterns found throughout this guide. This discourages "bastardized" MVC pattern variations and architecturing style fragmentation.
+
+One technical aspect that is also different is that Backbone is heavily event-oriented. Mithril, on the other hand, purposely avoids the observer pattern in an attempt to abolish "come-from hell", i.e. a class of debugging problems where you don't know what triggers some code because of a long chain of events triggering other events.
+
+A particularly nasty instance of this problem that sometimes occurs in "real-time" applications is when event triggering chains become circular due to a conditional statement bug, casuing infinite loops and browser crashes.
+
+Another significant difference between Backbone and Mithril is in their approach to familiarity: Backbone appeals to people familiar w/ jQuery; Mithril is designed to be familiar to people with server-side MVC framework experience.
+
+### Angular
+
+Angular is an MVC framework maintained by Google, and it provides a declarative view layer and an emphasis on testability. It leverages developer experience with server-side MVC frameworks, and in many ways, is very similar in scope to Mithril.
+
+The main difference between Angular templates and Mithril templates is that Angular templates follow the tradition of being defined in HTML. This has the benefit of cleaner syntax for writing static text, but it comes with the disadvantage of features getting awkwardly tied to HTML syntax, as well as providing poor debugging support.
+
+One thing you may have noticed in the homepage is that, out of the box, Angular is not as performant as other frameworks. Steep performance degradation is a notoriously common issue in non-trivial Angular applications and there are several third party libraries which attempt to get around performance problems. Speaking from experience, it's generally difficult to reason about performance in Angular.
+
+Mithril takes some learnings from that and implements a templating redrawing system that renders less aggressively, is less complex and is easier to profile.
+
+A noteworthy difference between Angular and Mithril is in framework complexity: Angular implements several subsystems that would seem more logical in programming language implementations (e.g. a parser, a dynamic scoping mechanism, decorators, etc). Mithril, on the other hand, tries to provide only features to support a more classic MVC paradigm.
+
+### Ember
+
+Ember is a highly comprehensive MVC framework, providing a large API that covers not only traditional MVC patterns, but also a vast range of helper utilities as well.
+
+The biggest difference between Ember and Mithril is summarized in the Architecture section above: Ember's comprehensiveness come at a cost of a steep learning curve, and a high degree of vendor lock-in.
+
+Ember is also more opinionated in terms of how application architecture should look, and as a result, tends to be less transparent in terms of what is actually happening under the hood.
+
+### React
+
+React is a templating engine developed by Facebook. It's relevant for comparison because it uses the same architecture as Mithril's templating engine: i.e. it acknowledges that DOM operations are the bottleneck of templating systems, and implements a virtual DOM tree which keeps track of changes and only applies diffs to the real DOM where needed.
+
+The most visible difference between React and Mithril is that React's *JSX* syntax does not run natively in the browser, whereas Mithril's uncompiled templates do. Both can be compiled, but React's compiled code still has function calls for each virtual DOM element; Mithril templates compile into static javascript data structures.
+
+Another difference is that Mithril, being an MVC framework, rather than a templating engine, provides an auto-redrawing system that is aware of network asynchrony and that can render views efficiently without cluttering application code with redraw calls, and without letting the developer unintentionally bleed out of the MVC pattern.
+
+Note also that, despite having a bigger scope, Mithril has a smaller file size than React.
+
+### Knockout
+
+Knockout is a library focused on data binding. It is not an MVC framework in the traditional sense, but idiomatic Knockout code uses the similar concept of view models.
+
+A Knockout view model is an amalgamation of model and controller layers in a single class. In contrast, Mithril separates the two layers more distinctly.
+
+Generally speaking, Knockout applications tend to be more tightly coupled than Mithril since Knockout doesn't provide an equivalent to Mithril's modules and components.
+
+As with Angular, Knockout templates are written in HTML, and therefore have the same pros and cons as Angular templates.
+
+### Vue
+
+Vue is a relatively new and unknown templating engine, but it boasts impressive results in its performance benchmark.
+
+It is not a full MVC framework, but it is similar to Angular templates, and uses the same terminology for its features (e.g. directives and filters).
+
+The most relevant difference is that Vue uses browser features that don't work (and cannot be made to work) in Internet Explorer 8. Mithril allows developers to support browsers all the way back to IE6 and Blackberry.
+
+Vue's implementation cleverly hijacks array methods, but it should be noted that Javascript Arrays cannot be truly subclassed and as such, Vue suffers from abstraction leaks.
+
+In contrast, Mithril avoids "magic" types.
diff --git a/docs/compiling-templates.md b/docs/compiling-templates.md
new file mode 100644
index 00000000..faa66fa3
--- /dev/null
+++ b/docs/compiling-templates.md
@@ -0,0 +1,94 @@
+## Compiling Templates
+
+If performance is absolutely critical, you can optionally pre-compile templates that use `m()` by running the [`template-compiler.sjs`](tools/template-compiler.sjs) macro with [Sweet.js](https://github.com/mozilla/sweet.js)
+
+Compiling a template transforms the nested function calls into a raw virtual DOM tree (which is merely a collection of native Javascript objects that is ready to be rendered via [`m.render`](mithril.render.md))
+
+For example, given the following template:
+
+```javascript
+var view = function() {
+ return m("a", {href: "http://google.com"}, "test");
+}
+```
+
+It would be compiled into:
+
+```javascript
+var view = function() {
+ return {tag: "a", attrs: {href: "http://google.com"}, children: "test"};
+}
+```
+
+Note that compiled templates are meant to be generated by an automated build process and are not meant to be human editable.
+
+---
+
+### Installing NodeJS and SweetJS for one-off compilations
+
+SweetJS requires a [NodeJS](http://nodejs.org) environment. To install it, go to its website and use the installer provided.
+
+To install SweetJS, NodeJS provides a command-line package manager tool. In a command line, type:
+
+```
+npm install -g sweet.js
+```
+
+To compile a file, type:
+
+```
+sjs --module /mithril.compile.sjs --output .js .js
+```
+
+---
+
+### Automating Compilation
+
+If you want to automate compilation, you can use [GruntJS](http://gruntjs.com), a task automation tool. If you're not familiar with GruntJS, you can find a tutorial on their website.
+
+Assuming NodeJS is already installed, run the following command to install GruntJS:
+
+```
+npm install -g grunt-cli
+```
+
+Once installed, create two files in the root of your project, `package.json` and `Gruntfile.js`
+
+`package.json`
+
+```javascript
+{
+ "name": "project-name-goes-here",
+ "version": "0.0.0", //must follow this format
+ "devDependencies": {
+ "grunt-sweet.js": "*"
+ }
+}
+```
+
+`Gruntfile.js`
+
+```javascript
+module.exports = function(grunt) {
+ grunt.initConfig({
+ sweetjs: {
+ modules: ["mithril.compile.sjs"],
+ compile: {expand: true, cwd: ".", src: "**/*.js", dest: "destination-folder-goes-here/"}
+ }
+ });
+
+ grunt.loadNpmTasks('grunt-sweet.js');
+
+ grunt.registerTask('default', ['sweetjs']);
+}
+```
+
+Make sure to replace the `project-name-goes-here` and `destination-folder-goes-here` placeholders with appropriate values.
+
+To run the automation task, run the following command from the root folder of your project:
+
+```
+grunt
+```
+
+More documentation on the grunt-sweet.js task and its options [can be found here](https://github.com/natefaubion/grunt-sweet.js)
diff --git a/docs/components.md b/docs/components.md
new file mode 100644
index 00000000..4a51fa19
--- /dev/null
+++ b/docs/components.md
@@ -0,0 +1,153 @@
+## Components
+
+Components are Mithril's mechanism for [hierarchical MVC](http://en.wikipedia.org/wiki/Hierarchical_model%E2%80%93view%E2%80%93controller).
+
+They allow complex, repeating logic to be abstracted into a logical unit of code, and they help modularize applications with widgets or multi-concern views (e.g. dashboards).
+
+You can also use components for a number of other advanced techniques, like recursive templating (e.g. tree views) and partial template mixins (i.e. injecting part of a template into another).
+
+---
+
+### Nesting components
+
+Here's an example of nested modules in a widgetization scenario:
+
+```javascript
+//root module
+var dashboard = {};
+
+dashboard.controller = function() {
+ this.userProfile = new userProfile.controller();
+ this.projectList = new projectList.controller();
+}
+
+dashboard.view = function(ctrl) {
+ return m("#example", [
+ m(".profile", [
+ new userProfile.view(this.userProfile);
+ ]),
+ m(".projects", [
+ new projectList.view(this.projectList);
+ ])
+ ])
+}
+
+
+
+//components
+
+//user profile component
+var userProfile = {};
+
+userProfile.controller = function() {
+ this.name = m.prop("John Doe");
+};
+
+userProfile.view = function(ctrl) {
+ return [
+ m("h1", "Profile"),
+ "Name: " + ctrl.name()
+ ];
+};
+
+
+
+//project list component
+var projectList = {};
+
+projectList.controller = function() {};
+
+projectList.view = function(ctrl) {
+ return "There are no projects";
+};
+
+
+
+//initialize
+m.module(document.body, dashboard);
+```
+
+As you can see, components look exactly like regular modules - it's turtles all the way down! Remember that modules are simply dumb containers for `controller` and `view` classes.
+
+This means components are decoupled both *horizontally* and *vertically*. It's possible to refactor each component as a isolated unit of logic (which itself follows the MVC pattern). And we can do so without touching the rest of the application (as long as the component API stays the same).
+
+Similarly, it's possible to mix and match different classes to make mix-in anonymous components (e.g. it's straightforward to build several views - for, say, a mobile app - that use the same controller).
+
+It's also possible to keep references to parent and even sibling components. This is useful, for example, when implementing notification badges in a navigation component, which are triggered and managed by other components in the system.
+
+---
+
+### Librarization
+
+Applications often reuse rich UI controls that aren't provided out of the box by HTML. Below is a basic example of a component of that type: a minimalist autocompleter component.
+
+*Note: Be mindful that, for the sake of code clarity and brevity, the example below does not support keyboard navigation and other real world features.*
+
+```javascript
+var autocompleter = {};
+
+autocompleter.controller = function(data, getter) {
+ //binding for the text input
+ this.value = m.prop("");
+ //store for the list of items
+ this.data = m.prop([]);
+
+ //method to determine what property of a list item to compare the text input's value to
+ this.getter = getter;
+
+ //this method changes the relevance list depending on what's currently in the text input
+ this.change = function(value) {
+ this.value(value);
+
+ var data = value === "" ? [] : data.filter(function(item) {
+ return this.getter(item).toLowerCase().indexOf(value.toLowerCase()) > -1;
+ }, this);
+ this.data(data);
+ };
+
+ //this method is called when an option is selected. It triggers an `onchange` event
+ this.select = function(value) {
+ this.value(value);
+ this.data([]);
+ if (this.onchange) this.onchange({target: {value: value}});
+ };
+}
+
+autocompleter.view = function(ctrl, options) {
+ if (options) ctrl.onchange = options.onchange;
+ return [
+ m("input", {oninput: m.withAttr("value", ctrl.change.bind(ctrl)), value: ctrl.value()}),
+ ctrl.data().map(function(item) {
+ return m("div", {data: ctrl.getter(item), onclick: m.withAttr("data", ctrl.select.bind(ctrl))}, ctrl.getter(item));
+ })
+ ];
+}
+
+
+
+//here's an example of using the autocompleter
+var dashboard = {}
+
+dashboard.controller = function() {
+ this.names = m.prop([{id: 1, name: "John"}, {id: 2, name: "Bob"}, {id: 2, name: "Mary"}]);
+ this.autocompleter = new autocompleter.controller(this.names(), function(item) {
+ return item.name;
+ });
+};
+
+dashboard.view = function(ctrl) {
+ //assuming there's an element w/ id = "example" somewhere on the page
+ return m("#example", [
+ new autocompleter.view(ctrl.autocompleter, {onchange: m.withAttr("value", console.log)}),
+ ]);
+};
+
+
+
+//initialize
+m.module(document.body, dashboard);
+```
+
+It's recommended that libraries that provide extra functionality to Mithril be implemented using this modular pattern, as opposed to trying to hide implementation in a [virtual element's `config` attribute](mithril.md).
+
+You should only consider using `config`-based components when leveraging existing libraries.
diff --git a/docs/getting-started.md b/docs/getting-started.md
new file mode 100644
index 00000000..69e1f8a9
--- /dev/null
+++ b/docs/getting-started.md
@@ -0,0 +1,566 @@
+## Getting Started
+
+### What is Mithril?
+
+Mithril is a client-side Javascript MVC framework, i.e. it's a tool to make application code divided into a data layer (called "**M**odel"), a UI layer (called **V**iew), and a glue layer (called **C**ontroller)
+
+Mithril is around 3kb gzipped thanks to its [small, focused, API](mithril.md). It provides a templating engine with a virtual DOM diff implementation for performant rendering, utilities for high-level modelling via functional composition, as well as support for routing and componentization.
+
+The goal of the framework is to make application code discoverable, readable and maintainable, and hopefully help you become an even better developer.
+
+Unlike some frameworks, Mithril tries very hard to avoid locking you into a web of dependencies: you can use as *little* of the framework as you need.
+
+However, using its entire toolset idiomatically can bring lots of benefits: learning to use functional programming in real world scenarios and solidifying good coding practices for OOP and MVC are just some of them.
+
+---
+
+## A Simple Application
+
+Getting started is surprisingly boilerplate-free:
+
+```markup
+
+
+
+```
+
+Yes, this is valid HTML 5! According to the specs, the ``, `` and `` tags can be omitted, but their respective DOM elements will still be there implicitly when a browser renders that markup.
+
+---
+
+### Model
+
+In Mithril, typically an application lives in an namespace and contains modules. Modules are merely structures that represent a viewable "page" or component.
+
+For simplicity, our application will have only one module, and we're going to use it as the namespace for our application:
+
+```markup
+
+```
+
+This object will namespace our two Model classes:
+
+```javascript
+var todo = {};
+
+//for simplicity, we use this module to namespace the model classes
+
+//the Todo class has two properties
+todo.Todo = function(data) {
+ this.description = m.prop(data.description);
+ this.done = m.prop(false);
+};
+
+//the TodoList class is a list of Todo's
+todo.TodoList = Array;
+```
+
+[`m.prop`](mithril.prop.md) is simply a factory for a getter-setter function. Getter-setters work like this:
+
+```javascript
+//define a getter-setter with initial value `John`
+var name = m.prop("John");
+
+//read the value
+var a = name(); //a == "John"
+
+//set the value to `Mary`
+name("Mary"); //Mary
+
+//read the value
+var b = name(); //b == "Mary"
+```
+
+Note that the `Todo` and `TodoList` classes we defined above are plain vanilla Javascript constructors. They can be initialized and used like this:
+
+```javascript
+var myTask = new todo.Todo({description: "Write code"});
+
+//read the description
+myTask.description(); //Write code
+
+//is it done?
+var isDone = myTask.done(); //isDone == false
+
+//mark as done
+myTask.done(true); //true
+
+//now it's done
+isDone = myTask.done(); //isDone == true
+```
+
+The `TodoList` class is simply an alias of the native `Array` class.
+
+```javascript
+var list = new todo.TodoList();
+list.length; //0
+```
+
+---
+
+### Controller
+
+Our next step is to write a controller that will use our model classes.
+
+```javascript
+//the controller uses 3 model-level entities, of which one is a custom defined class:
+//`Todo` is the central class in this application
+//`list` is merely a generic array, with standard array methods
+//`description` is a temporary storage box that holds a string
+//
+//the `add` method simply adds a new todo to the list
+todo.controller = function() {
+ this.list = new todo.TodoList();
+ this.description = m.prop("");
+
+ this.add = function(description) {
+ if (description()) {
+ this.list.push(new todo.Todo({description: description()}));
+ this.description("");
+ }
+ };
+}
+```
+
+The code above should hopefully be self-explanatory. You can use the controller like this:
+
+```javascript
+var ctrl = new todo.controller();
+
+ctrl.description(); //[empty string]
+
+//try adding a to-do
+ctrl.add(ctrl.description);
+ctrl.list.length; //0
+
+//you can't add a to-do with an empty description
+
+//add it properly
+ctrl.description("Write code");
+ctrl.add(ctrl.description);
+ctrl.list.length; //1
+```
+
+---
+
+### View
+
+The next step is to write a view so users can interact with the application
+
+```javascript
+todo.view = function(ctrl) {
+ return m("html", [
+ m("body", [
+ m("input"),
+ m("button", "Add"),
+ m("table", [
+ m("tr", [
+ m("td", [
+ m("input[type=checkbox]")
+ ]),
+ m("td", "task description"),
+ ])
+ ])
+ ])
+ ]);
+};
+```
+
+The utility method `m()` creates virtual DOM elements. As you can see, you can use CSS selectors to specify attributes. You can also use the `.` syntax to add CSS classes and the `#` to add an id.
+
+The view can be rendered using the `m.render` method:
+
+```javascript
+//assuming the `ctrl` variable from earlier
+m.render(document, todo.view(ctrl));
+```
+
+Notice that we pass a root DOM element to attach our template to, as well as the template itself.
+
+This renders the following markup:
+
+```markup
+
+
+
+
+
+
+
+
task description
+
+
+
+
+```
+
+---
+
+#### Data Bindings
+
+Let's implement a **data binding** on the text input. Data bindings connect a DOM element to a javascript variable so that updating one updates the other.
+
+```javascript
+m("input")
+
+//becomes
+m("input", {value: ctrl.description()})
+```
+
+This binds the `description` getter-setter to the text input. Updating the value of the description updates the input when Mithril redraws.
+
+```javascript
+var ctrl = new todo.controller();
+ctrl.description(); // empty string
+m.render(todo.view(ctrl)); // input is empty
+ctrl.description("Write code"); //set the description in the controller
+m.render(todo.view(ctrl)); // input now says "Write code"
+```
+
+Note that calling the `todo.view` method multiple times does not re-render the entire template.
+
+Mithril internally keeps a virtual representation of the DOM in cache, scans for changes, and then only modifies the minimum required to apply the change.
+
+In this case, Mithril only touches the `value` attribute of the input.
+
+---
+
+Bindings can also be **bi-directional**: that is, they can be made such that, in addition to what we saw just now, a user typing on the input updates the description getter-setter.
+
+Here's the idiomatic way of implementing the view-to-controller part of the binding:
+
+```javascript
+m("input", {onchange: m.withAttr("value", ctrl.description), value: ctrl.description()})
+```
+
+The code bound to the `onchange` can be read like this: "with the attribute value, set ctrl.description".
+
+Note that Mithril does not prescribe how the binding updates: you can bind it to `onchange`, `onkeypress`, `oninput`, `onblur` or any other event that you prefer.
+
+You can also specify what attribute to bind. This means that just as you are able to bind the `value` attribute in an `