diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..3c1f41bd
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,25 @@
+# EditorConfig helps developers define and maintain consistent
+# coding styles between different editors and IDEs
+# editorconfig.org
+
+root = true
+
+
+[*]
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+
+[*.rs]
+indent_style = space
+indent_size = 4
+
+[*.toml]
+indent_style = space
+indent_size = 4
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..7585238e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+book
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..730a9747
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,18 @@
+sudo: false
+dist: trusty
+language: rust
+
+before_install:
+ - cargo install mdbook --vers '0.1.8' --debug --force
+
+script:
+ - mdbook build
+
+deploy:
+ provider: pages
+ skip-cleanup: true
+ github-token: $GITHUB_TOKEN # Set in travis-ci.org dashboard, marked secure
+ local-dir: book
+ keep-history: false
+ on:
+ branch: master
diff --git a/book.toml b/book.toml
new file mode 100644
index 00000000..c3b7fe0f
--- /dev/null
+++ b/book.toml
@@ -0,0 +1,9 @@
+[book]
+authors = ["The Rust CLI Working Group"]
+multilingual = false
+src = "src"
+title = "Rust CLI WG"
+
+[output.html]
+curly-quotes = true
+additional-css = ["src/special-content.css"]
diff --git a/src/SUMMARY.md b/src/SUMMARY.md
new file mode 100644
index 00000000..1a1f7a04
--- /dev/null
+++ b/src/SUMMARY.md
@@ -0,0 +1,20 @@
+# Summary
+
+[Getting started](./getting_started.md)
+
+- [A command line app in 15 minutes](./tutorial/intro.md)
+ - [Project setup](./tutorial/setup.md)
+ - [Parsing command line arguments](./tutorial/cli-args.md)
+ - [First implementation of our example tool](./tutorial/impl-draft.md)
+ - [Nicer error reporting](./tutorial/errors.md)
+ - [Output for humans and machines](./tutorial/output.md)
+ - [Testing](./tutorial/testing.md)
+ - [Packaging and documentation](./tutorial/packaging.md)
+- [In-depth topics](./in-depth/intro.md)
+ - [Signal handling](./in-depth/signals.md)
+ - [Using config files](./in-depth/config-files.md)
+ - [Exit codes](./in-depth/exit-code.md)
+ - [Communicating with humans](./in-depth/human-communication.md)
+ - [Communicating with machines](./in-depth/machine-communication.md)
+ - [Rendering documentation for you CLI apps](./in-depth/docs.md)
+ - [Packaging apps and distributing them for different platforms](./in-depth/packaging-distribution.md)
diff --git a/src/getting_started.md b/src/getting_started.md
new file mode 100644
index 00000000..3f203b75
--- /dev/null
+++ b/src/getting_started.md
@@ -0,0 +1,30 @@
+# Command line apps in Rust
+
+Rust is a statically compiled, fast language with great tooling and a rapidly growing ecosystem.
+That makes it a great fit for writing command line applications:
+They should be small, portable, and quick to run.
+Command line applications are also a great way to get started with learning Rust;
+or if you want to introduce Rust to your team!
+
+Writing a program with a simple command line interface (CLI)
+is great a exercise for a beginner
+who is new to the language and wants to get a feel for it.
+There are many aspects to this topic, though,
+that often only reveal themselves later on.
+
+This book is structure like this:
+We start with a quick tutorial,
+after which you'll end up with a working CLI tool.
+You'll be exposed to a few of the core concepts of Rust
+as well as the main aspects of CLI applications.
+What follows are chapters that go into more detail
+on some of these aspects.
+
+One last thing before we dive right into CLI applications:
+If you found an error in this book
+or want to help us write more content for it,
+you can find its source [in the CLI WG repository][book-src].
+We'd love to year your feedback!
+Thank you!
+
+[book-src]: https://github.com/rust-lang-nursery/cli-wg
diff --git a/src/in-depth/config-files.md b/src/in-depth/config-files.md
new file mode 100644
index 00000000..1d295fa1
--- /dev/null
+++ b/src/in-depth/config-files.md
@@ -0,0 +1 @@
+# Using config files
diff --git a/src/in-depth/docs.md b/src/in-depth/docs.md
new file mode 100644
index 00000000..fd05044a
--- /dev/null
+++ b/src/in-depth/docs.md
@@ -0,0 +1 @@
+# Rendering documentation for you CLI apps
diff --git a/src/in-depth/exit-code.md b/src/in-depth/exit-code.md
new file mode 100644
index 00000000..4f13cfab
--- /dev/null
+++ b/src/in-depth/exit-code.md
@@ -0,0 +1 @@
+# Exit codes
diff --git a/src/in-depth/human-communication.md b/src/in-depth/human-communication.md
new file mode 100644
index 00000000..687fdad8
--- /dev/null
+++ b/src/in-depth/human-communication.md
@@ -0,0 +1 @@
+# Communicating with humans
diff --git a/src/in-depth/intro.md b/src/in-depth/intro.md
new file mode 100644
index 00000000..467d41cf
--- /dev/null
+++ b/src/in-depth/intro.md
@@ -0,0 +1 @@
+# In-depth topics
diff --git a/src/in-depth/machine-communication.md b/src/in-depth/machine-communication.md
new file mode 100644
index 00000000..f685448d
--- /dev/null
+++ b/src/in-depth/machine-communication.md
@@ -0,0 +1 @@
+# Communicating with machines
diff --git a/src/in-depth/packaging-distribution.md b/src/in-depth/packaging-distribution.md
new file mode 100644
index 00000000..5ee5e758
--- /dev/null
+++ b/src/in-depth/packaging-distribution.md
@@ -0,0 +1 @@
+# Packaging apps and distributing them for different platforms
diff --git a/src/in-depth/signals.md b/src/in-depth/signals.md
new file mode 100644
index 00000000..dc42837f
--- /dev/null
+++ b/src/in-depth/signals.md
@@ -0,0 +1 @@
+# Signal handling
diff --git a/src/special-content.css b/src/special-content.css
new file mode 100644
index 00000000..3d94850e
--- /dev/null
+++ b/src/special-content.css
@@ -0,0 +1,20 @@
+.content aside {
+ padding-top: 0.1em;
+ margin-left: 0.1em;
+ padding-left: 1em;
+ border-left: 3px solid #ccc;
+ padding-bottom: 0.1em;
+ margin-bottom: 0.6em;
+}
+
+.content aside *:first-child {
+ margin-top: 0.2em;
+}
+
+.content aside *:last-child {
+ margin-bottom: 0.2em;
+}
+
+.content aside.todo {
+ border-left-color: yellow;
+}
diff --git a/src/tutorial/cli-args.md b/src/tutorial/cli-args.md
new file mode 100644
index 00000000..6f420525
--- /dev/null
+++ b/src/tutorial/cli-args.md
@@ -0,0 +1,58 @@
+## Parsing command line arguments
+
+A typical invocation of our CLI tool will look like this:
+`grrs foobar test.txt`.
+You can think of CLI arguments as a data type.
+In our case, we have two fields,
+`pattern` (the string to look for),
+and `path` (the file to look in).
+In Rust, it is very common to try and structure programs around the data they deal with.
+This is a good start:
+
+```rust
+struct Cli {
+ pattern: String,
+ path: std::path::PathBuf,
+}
+```
+
+
+
+Now, we still need to actually get the arguments the user passed into this form.
+One option would be manually parse the list of strings we get from the operating system,
+but a much nicer way is to use one of the many available libraries.
+As you can see in the `src/main.rs` file,
+our templates already contains some code using `clap`,
+and in particular use it’s “derive” feature.
+This is quite nice:
+All we have to do is annotate a struct and it’ll generate the code that parses the arguments into the fields.
+Let’s add our fields to the `Cli` struct in the template
+and also some documentation comments along the way.
+It’ll look like this:
+
+```rust
+/// Search for a pattern in a file and display the lines that contain it.
+#[derive(Clap)]
+struct Cli {
+ /// The pattern to look for
+ pattern: String,
+ /// The path to the file to read
+ path: std::path::PathBuf,
+}
+```
+
+Right below the `Cli` struct our template contains its `main` function.
+When the program starts, it will call this function.
+The first line is
+
+```rust
+let args = Cli::parse();
+```
+
+This will try to parse the arguments the user gave when executing the program into our `Cli` struct.
+You might be wondering what happens if this fails.
+Give it a try!
diff --git a/src/tutorial/errors.md b/src/tutorial/errors.md
new file mode 100644
index 00000000..c1807d8a
--- /dev/null
+++ b/src/tutorial/errors.md
@@ -0,0 +1,7 @@
+## Nicer error reporting
+
+
diff --git a/src/tutorial/impl-draft.md b/src/tutorial/impl-draft.md
new file mode 100644
index 00000000..e4154cb1
--- /dev/null
+++ b/src/tutorial/impl-draft.md
@@ -0,0 +1,35 @@
+## First implementation of `grrs`
+
+Right, now that we have our input data,
+we can start to write our actual tool.
+Let’s start by opening the file:
+
+```rust
+let content = std::fs::read_to_string(&args.path)?;
+```
+
+
+
+Now, let’s iterate over the lines and print each one that contains our pattern:
+
+```rust
+for line in content.lines() {
+ if line.contains(args.pattern) {
+ println!("{}", line);
+ }
+}
+```
+
+Give it a try: `cargo run -- main src/main.rs` should work now!
+
+
diff --git a/src/tutorial/intro.md b/src/tutorial/intro.md
new file mode 100644
index 00000000..c3e5836f
--- /dev/null
+++ b/src/tutorial/intro.md
@@ -0,0 +1,12 @@
+# Learning Rust by Writing a Command Line App in 15 Minutes
+
+This short tutorial will guide you through writing
+a CLI (command line interface) application
+in [Rust].
+It will take you roughly fifteen minutes;
+but feel free to skip parts you don't need to know right now
+or jump in at any point.
+You’ll learn all the essentials about how to get going,
+and where to find more information.
+
+[Rust]: https://rust-lang.org/
diff --git a/src/tutorial/output.md b/src/tutorial/output.md
new file mode 100644
index 00000000..75496b66
--- /dev/null
+++ b/src/tutorial/output.md
@@ -0,0 +1,15 @@
+## Output
+
+### Logging
+
+To make it easier to understand what is happening in our program,
+we might want to add some log statements.
+This is usually easy while writing your application.
+But it will become super helpful when running this program again in half a year.
+
+
diff --git a/src/tutorial/packaging.md b/src/tutorial/packaging.md
new file mode 100644
index 00000000..f275e04c
--- /dev/null
+++ b/src/tutorial/packaging.md
@@ -0,0 +1,15 @@
+## Packaging and rendering documentation
+
+If you feel confident that your program is ready to for other people to use,
+it is time to package it!
+
+
+
diff --git a/src/tutorial/setup.md b/src/tutorial/setup.md
new file mode 100644
index 00000000..ae4f17fc
--- /dev/null
+++ b/src/tutorial/setup.md
@@ -0,0 +1,27 @@
+## Project setup
+
+If you haven’t already,
+[install Rust](https://www.rust-lang.org/install.html) on your computer (it should only take a few minutes).
+After that, open a terminal and navigate to the directory you want to put your application code into.
+
+What kind of project do you want to write?
+How about we start with something simple:
+Let’s write a small `grep` clone.
+That is a tool that we can give a string and a path and it’ll tell us which lines contain the string.
+Let’s call it `grrs` (pronounced “grass”).
+
+If you’ve already seen the basic Rust tutorials,
+you might be inclined to start with `cargo new --bin my-cool-app`.
+To save us some time,
+we’ll instead start with a CLI-specific template:
+`cargo generate --git https://github.com/rust-clique/cargo-template-cli`.
+When you run this, it’ll ask you for a project name.
+
+If look at the newly created `grrs` directory,
+you’ll find a typical setup for a Rust project:
+
+- A `Cargo.toml` file that contains metadata for our project, incl. a list of dependencies/external libraries we use.
+- A `src/main.rs` file that is the entry point for our (main) binary.
+- A `tests/` directory that will contain integration tests for our tool.
+
+If you can execute `cargo run` in the `grrs` directory and see it greet you, you’re all set up.
diff --git a/src/tutorial/testing.md b/src/tutorial/testing.md
new file mode 100644
index 00000000..9e68f1f1
--- /dev/null
+++ b/src/tutorial/testing.md
@@ -0,0 +1,12 @@
+## Testing
+
+
+