diff --git a/maud/src/lib.rs b/maud/src/lib.rs
index 446d5de..d046b7b 100644
--- a/maud/src/lib.rs
+++ b/maud/src/lib.rs
@@ -1,4 +1,152 @@
-//! Super fast HTML template engine.
+//! A macro for writing HTML templates.
+//!
+//! This crate, along with its sister `maud_macros`, lets you generate
+//! HTML markup from within Rust. It exposes a single macro, `html!`,
+//! which compiles your markup to specialized Rust code.
+//!
+//! # Dependencies
+//!
+//! To get started, add `maud` and `maud_macros` to your `Cargo.toml`:
+//!
+//! ```toml
+//! [dependencies]
+//! # ...
+//! maud = "*"
+//! maud_macros = "*"
+//! ```
+//!
+//! # Example
+//!
+//! ```rust
+//! #![feature(plugin)]
+//! #![allow(unstable)]
+//!
+//! extern crate maud;
+//! #[plugin] #[no_link] extern crate maud_macros;
+//!
+//! fn main() {
+//!     let name = "Lyra";
+//!     let markup = html! {
+//!         p { "Hi, " $name "!" }
+//!     };
+//!     assert_eq!(markup.render(), "<p>Hi, Lyra!</p>");
+//! }
+//! ```
+//!
+//! # Syntax
+//!
+//! Maud uses its own syntax, loosely inspired by HTML and Rust.
+//!
+//! ## Literals
+//!
+//! ```
+//! html! {
+//!     "Oatmeal, are you crazy?\n"
+//!     "<script>alert(\"XSS\")</script>\n"
+//!     $$"<script>alert(\"XSS\")</script>\n"
+//! }
+//! ```
+//!
+//! ```html
+//! Oatmeal, are you crazy?
+//! &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;
+//! <script>alert("XSS")</script>
+//! ```
+//!
+//! Literal strings use the same syntax as Rust.
+//!
+//! By default, HTML special characters are escaped automatically. Add a
+//! `$$` prefix to disable this escaping.
+//!
+//! ## Elements
+//!
+//! ```
+//! html! {
+//!     h1 "Pinkie's Brew"
+//!     p {
+//!         "Watch as I work my gypsy magic"
+//!         br /
+//!         "Eye of a newt and cinnamon"
+//!     }
+//!     p small em "squee"
+//! }
+//! ```
+//!
+//! ```html
+//! <h1>Pinkie's Brew</h1>
+//! <p>
+//!   Watch as I work my gypsy magic
+//!   <br>
+//!   Eye of a newt and cinnamon
+//! </p>
+//! <p><small><em>squee</em></small></p>
+//! ```
+//!
+//! Write an element using curly braces (`p {}`).
+//!
+//! Terminate a void element using a slash (`br /`).
+//!
+//! If the element has only a single child, you can omit the brackets
+//! (`h1 "Pinkie's Brew"`). This shorthand works with nested elements
+//! too.
+//!
+//! ## Attributes
+//!
+//! ```
+//! html! {
+//!     form method="POST" {
+//!         label for="waffles" "Do you like waffles?"
+//!         input name="waffles" type="checkbox" checked=! /
+//!     }
+//! }
+//! ```
+//!
+//! ```html
+//! <form method="POST">
+//!   <label for="waffles">Do you like waffles?</label>
+//!   <input name="waffles" type="checkbox" checked>
+//! </form>
+//! ```
+//!
+//! Add attributes using the syntax `attr="value"`. Attributes must be
+//! quoted: they are parsed as string literals.
+//!
+//! To declare an empty attribute, use `!` for the value: `checked=!`.
+//!
+//! ## Splices
+//!
+//! ```
+//! let best_pony = "Pinkie Pie";
+//! let numbers = [1, 2, 3, 4];
+//! let secret_message = "Surprise!";
+//! let pre_escaped = "<p>Pre-escaped</p>";
+//! html! {
+//!     h1 { $best_pony " says:" }
+//!     p {
+//!         "I have " $numbers.len() " numbers, "
+//!         "and the first one is " $numbers[0]
+//!     }
+//!     p title=$secret_message {
+//!         "1 + 1 = " $(1 + 1)
+//!     }
+//!     $$pre_escaped
+//! }
+//! ```
+//!
+//! ```html
+//! <h1>Pinkie Pie says:</h1>
+//! <p>I have 4 numbers, and the first one is 1</p>
+//! <p title="Surprise!">1 + 1 = 2</p>
+//! <p>Pre-escaped</p>
+//! ```
+//!
+//! Use `$(expr)` syntax to splice a Rust expression into the output.
+//! You can omit the brackets if it's just a variable (`$var`), indexing
+//! operation (`$var[0]`), method call (`$var.method()`), or property
+//! lookup (`$var.property`).
+//!
+//! As with literals, expression values are escaped by default. Use a
+//! `$$` prefix to disable this behavior.
 
 #![allow(unstable)]