diff --git a/docs/src/tutorial/template-deep-dive/cargo-toml.md b/docs/src/tutorial/template-deep-dive/cargo-toml.md
index d6af282..3e26a48 100644
--- a/docs/src/tutorial/template-deep-dive/cargo-toml.md
+++ b/docs/src/tutorial/template-deep-dive/cargo-toml.md
@@ -3,11 +3,11 @@
`Cargo.toml` is the manifest file for Rust's package manager, `cargo`. This file contains
metadata such as name, version, and dependencies for packages, which are call "crates" in Rust.
-There's a bunch of metadata that the template gives us, but there are 3 key parts to discuss:
+There's a bunch of metadata that the template gives us, but there are three key parts to discuss:
-- [`crate-type`](#a1-crate-type)
-- [`wasm-bindgen` dependency](#a2-wasm-bindgen-dependency)
-- [`[features]` and `wee-alloc`, `console-error-panic-hook` dependencies](#a3-features-and-wee-alloc-console-error-panic-hook-dependencies)
+1. [`crate-type`](#a1-crate-type)
+2. [`wasm-bindgen` dependency](#a2-wasm-bindgen-dependency)
+3. [`[features]` and `wee_alloc`, `console_error_panic_hook` dependencies](#a3-features-and-wee_alloc-console_error_panic_hook-dependencies)
@@ -15,7 +15,7 @@ There's a bunch of metadata that the template gives us, but there are 3 key part
```toml
[lib]
-crate-type = ["cdylib"]
+crate-type = ["cdylib", "rlib"]
```
A Rust-`wasm` crate is a bit different from a normal crate, and as a result, we need to note
@@ -33,6 +33,9 @@ as a dynamic library to be loaded from another language. In our case, we'll be c
`.wasm` file, but this output type will create `*.so` files on Linux, `*.dylib` files on
macOS, and `*.dll` files on Windows in non-`wasm` circumstances.
+`#[crate_type = "rlib"]` signifies that an intermediate "Rust library" file will be produced.
+This allows tests to use the main crate.
+
You can read more about linking and crate types, [here](https://doc.rust-lang.org/reference/linkage.html).
## 2. `wasm-bindgen` dependency
@@ -52,23 +55,24 @@ We'll see more about how to use this library when we discuss what has been gener
there is no `^` or `~` symbol- it looks like we're locking to the `0.2` version.
However, that's not the case! In Rust, the `^` is implied.
-## 3. `[features]` and `wee-alloc`, `console-error-panic-hook` dependencies
+## 3. `[features]` and `wee_alloc`, `console_error_panic_hook` dependencies
As part of our effort to design a template that helps people discover useful crates
-for their particular use case, this template includes 2 dependencies that can be
+for their particular use case, this template includes two dependencies that can be
very useful for folks developing Rust-`wasm` crates: `console-error-panic-hook` and
`wee-alloc`.
-Because these dependencies are useful primarily in a specifc portion of the Rust-`wasm`
+Because these dependencies are useful primarily in a specific portion of the Rust-`wasm`
crate development workflow, we've also set up a bit of glue code that allows us to include
-them both as dependences, but allowing for them to be optionally included.
+them both as dependencies, but also allows them to be optionally included.
```toml
[features]
-default-features = ["console_error_panic_hook", "wee_alloc"]
+default = ["console_error_panic_hook"]
[dependencies]
cfg-if = "0.1.2"
+wasm-bindgen = "0.2"
# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
@@ -79,12 +83,22 @@ console_error_panic_hook = { version = "0.1.1", optional = true }
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
# compared to the default allocator's ~10K. It is slower than the default
# allocator, however.
-wee_alloc = { version = "0.4.1", optional = true }
+#
+# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
+wee_alloc = { version = "0.4.2", optional = true }
```
-[`cfg-if`] allows us to check if certain features are enabled on a rust crate. We'll
-use this crate in `utils.rs` to optionally enable `console_error_panic_hook` or
-`wee_alloc`. By default, we have them enabled. To disable them, we can remove their
-entry from the `default-features` vector.
+[`cfg-if`] allows us to check if certain features are enabled on a Rust crate. We'll
+use this crate later to optionally enable `console_error_panic_hook` or
+`wee_alloc`.
+
+By default, only `console_error_panic_hook` is enabled. To disable either
+feature, we can remove its name from the `default` vector.
+
+To learn more about these features, we discuss them in-depth in the `src/lib.rs` and
+`src/utils.rs` sections.
+
+Briefly, they include:
-To learn more about these features, we discuss them in depth in the `utils.rs` section.
++ **console_error_panic_hook** for logging panic messages to the developer console.
++ **wee_alloc**, an allocator optimized for small code size.
diff --git a/docs/src/tutorial/template-deep-dive/src-lib-rs.md b/docs/src/tutorial/template-deep-dive/src-lib-rs.md
index 1e31777..e5f72fe 100644
--- a/docs/src/tutorial/template-deep-dive/src-lib-rs.md
+++ b/docs/src/tutorial/template-deep-dive/src-lib-rs.md
@@ -1,3 +1,127 @@
# src/lib.rs
-🚧 COMING SOON 🚧
+`lib.rs` is the template's main source file. The name `lib.rs` commonly implies that this Rust project will be compiled as a library.
+
+It contains three key parts:
+
+1. [`#[wasm_bindgen] functions`](#a1-wasm_bindgen-functions)
+2. [Crate imports](#a2-crate-imports)
+3. [`wee_alloc` optional dependecy](#a3-wee_alloc-optional-dependecy)
+ - [What is `wee_alloc`?](#what-is-wee_alloc)
+
+---
+
+We'll start with the most important part of `lib.rs` -- the two `#[wasm_bindgen]` functions. In many cases, this is the only part of `lib.rs` you will need to modify.
+
+## 1. `#[wasm_bindgen]` functions
+
+The `#[wasm_bindgen]` attribute indicates that the function below it will be accessible both in JavaScript and Rust.
+
+```rust
+#[wasm_bindgen]
+extern {
+ fn alert(s: &str);
+}
+```
+
+The `extern` block imports the external JavaScript function `alert` into Rust. This declaration is required to call `alert` from Rust. By declaring it in this way, `wasm-bindgen` will create JavaScript stubs for `alert` which allow us to pass strings back and forth between Rust and JavaScript.
+
+We can see that the `alert` function requires a single parameter `s` of type `&str`, a string. In Rust, any string literal such as `"Hello, test-wasm!"` is of type `&str`. So, `alert` could be called by writing `alert("Hello, test-wasm!");`.
+
+We knew to declare `alert` in this way because it is how we would call `alert` in JavaScript -- by passing it a string argument.
+
+```rust
+#[wasm_bindgen]
+pub fn greet() {
+ alert("Hello, test-wasm!");
+}
+```
+
+If we were to write the `greet` function without the `#[wasm_bindgen]` attribute, then `greet` would not be easily accessible within JavaScript. Furthermore, we wouldn't be able to natively convert certain types such as `&str` between JavaScript and Rust. So, both the `#[wasm_bindgen]` attribute and the prior import of `alert` allow `greet` to be called from JavaScript.
+
+This is all you need to know to interface with JavaScript! If you are curious about the rest, read on.
+
+## 2. Crate imports
+
+```rust
+extern crate cfg_if;
+extern crate wasm_bindgen;
+```
+
+In `Cargo.toml`, we included the crates `cfg_if` and `wasm_bindgen` as project dependencies.
+
+Here, we explicitly declare that these crates will be used in `lib.rs`.
+
+```rust
+mod utils;
+```
+This statement declares a new module named `utils` that is defined by the contents of `utils.rs`. Equivalently, we could place the contents of `utils.rs` inside the `utils` declaration, replacing the line with:
+
+```rust
+mod utils {
+ // contents of utils.rs
+}
+```
+
+Either way, the contents of `utils.rs` define a single public function `set_panic_hook`. Because we are placing it inside the `utils` module, we will be able to call the function directly by writing `utils::set_panic_hook()`. We will discuss how and why to use this function in `src/utils.rs`.
+
+
+```rust
+use cfg_if::cfg_if;
+```
+
+`use` allows us to conveniently refer to parts of a crate or module. For example, suppose the crate `cfg_if` contains a function `func`. It is always possible to call this function directly by writing `cfg_if::func()`. However, this is often tedious to write. If we first specify `use cfg_if::func;`, then `func` can be called by just writing `func()` instead.
+
+With this in mind, this `use` allows us to call the macro `cfg_if!` inside the crate `cfg_if` without writing `cfg_if::cfg_if!`.
+
+```rust
+use wasm_bindgen::prelude::*;
+```
+
+Many modules contain a prelude, a list of things that should be automatically imported. This allows common features of the module to be conveniently accessed without a lengthy prefix. For example, in this file we can use `#[wasm_bindgen]` only because it is brought into scope by the prelude.
+
+The asterisk at the end of this `use` indicates that everything inside the module `wasm_bindgen::prelude` (i.e. the module `prelude` inside the crate `wasm_bindgen`) can be referred to without prefixing it with `wasm_bindgen::prelude`.
+
+For example, `#[wasm_bindgen]` could also be written as `#[wasm_bindgen::prelude::wasm_bindgen]`, although this is not recommended.
+
+## 3. `wee_alloc` optional dependecy
+
+```rust
+cfg_if! {
+ if #[cfg(feature = "wee_alloc")] {
+ extern crate wee_alloc;
+ #[global_allocator]
+ static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
+ }
+}
+```
+
+This code block is intended to initialize `wee_alloc` as the global memory allocator, but only if the `wee_alloc` feature is enabled in `Cargo.toml`.
+
+We immediately notice that `cfg_if!` is a macro because it ends in `!`, similarly to other Rust macros such as `println!` and `vec!`. A macro is directly replaced by other code during compile time.
+
+During compile time, `cfg_if!` evaluates the `if` statement. This tests whether the feature `wee_alloc` is present in the `[features]` section of `Cargo.toml` (among other possible ways to set it).
+
+As we saw earlier, the `default` vector in `[features]` only contains `"console_error_panic_hook"` and not `"wee_alloc"`. So, in this case, the `cfg_if!` block will be replaced by no code at all, and hence the default memory allocator will be used instead of `wee_alloc`.
+
+```rust
+extern crate wee_alloc;
+#[global_allocator]
+static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
+```
+
+However, suppose `"wee_alloc"` is appended to the `default` vector in `Cargo.toml`. Then, the `cfg_if!` block is instead replaced with the contents of the `if` block, shown above.
+
+This code sets the `wee_alloc` allocator to be used as the global memory allocator.
+
+### What is `wee_alloc`?
+
+Reducing the size of compiled WebAssembly code is important, since it is often transmitted over the Internet or placed on embedded devices.
+
+> `wee_alloc` is a tiny allocator designed for WebAssembly that has a (pre-compression) code-size footprint of only a single kilobyte.
+
+[An analysis](http://fitzgeraldnick.com/2018/02/09/wee-alloc.html) suggests that over half of the bare minimum WebAssembly memory footprint is required by Rust's default memory allocator. Yet, WebAssembly code often does not require a sophisticated allocator, since it often just requests a couple of large initial allocations.
+
+`wee_alloc` trades off size for speed. Although it has a tiny code-size footprint, it is relatively slow if additional allocations are needed.
+
+For more details, see the [`wee_alloc` repository](https://github.com/rustwasm/wee_alloc).
\ No newline at end of file
diff --git a/docs/src/tutorial/template-deep-dive/src-utils-rs.md b/docs/src/tutorial/template-deep-dive/src-utils-rs.md
index ea0c3c0..3ea5cb2 100644
--- a/docs/src/tutorial/template-deep-dive/src-utils-rs.md
+++ b/docs/src/tutorial/template-deep-dive/src-utils-rs.md
@@ -1,3 +1,66 @@
# src/utils.rs
-🚧 COMING SOON 🚧
+The purpose of `utils.rs` is to define the `utils` module, which contains a single function `set_panic_hook`. This function becomes part of the `utils` module in `lib.rs`, as described in the preceding section.
+
+If the `console_error_panic_hook` feature is not enabled, then `set_panic_hook` is defined to be an inlined empty function. So, there is no run-time performance or code-size penalty incurred by its use.
+
+We will discuss:
+1. [Defining `set_panic_hook`](#a1-defining-set_panic_hook)
+2. [What is `console_error_panic_hook`?](#a2-what-is-console_error_panic_hook)
+
+
+---
+
+## 1. Defining `set_panic_hook`
+
+```
+use cfg_if::cfg_if;
+```
+
+This allows us to write `cfg_if!` instead of `cfg_if::cfg_if!`, identically to the line in `src/lib.rs`.
+
+```
+cfg_if! {
+ if #[cfg(feature = "console_error_panic_hook")] {
+ extern crate console_error_panic_hook;
+ pub use self::console_error_panic_hook::set_once as set_panic_hook;
+ } else {
+ #[inline]
+ pub fn set_panic_hook() {}
+ }
+}
+```
+
+As described in the preceding section, the macro `cfg_if!` evaluates the `if` statement during compile time. This is possible because it is essentially testing whether `"console_error_panic_hook"` is defined in the `[features]` section of `Cargo.toml`, which is available during compile time.
+
+The entire macro block will either be replaced with the statements in the `if` block or with those in the `else` block. These two cases are now described in turn:
+
+```
+extern crate console_error_panic_hook;
+pub use self::console_error_panic_hook::set_once as set_panic_hook;
+```
+
+Due to the `use` statement, the function `self::console_error_panic_hook::set_once` can now be accessed more conveniently as `set_panic_hook`. Due to `pub`, this function will be publicly accessible outside of the `utils` module as `utils::set_panic_hook`.
+
+```
+#[inline]
+pub fn set_panic_hook() {}
+```
+
+An inline function replaces the function call with the contents of the function during compile time. Here, `set_panic_hook` is defined to be an empty inline function. This allows the use of `set_panic_hook` without any run-time or code-size performance penalty if the feature is not enabled.
+
+## 2. What is `console_error_panic_hook`?
+
+The crate `console_error_panic_hook` enhances error messages in the web browser. This allows you to easily debug WebAssembly code.
+
+Let's compare error messages before and after enabling the feature:
+
+**Before:** `"RuntimeError: Unreachable executed"`
+
+**After:** `"panicked at 'index out of bounds: the len is 3 but the index is 4', libcore/slice/mod.rs:2046:10"`
+
+To do this, a panic hook for WebAssembly is provided that logs panics to the developer console via the JavaScript `console.error` function.
+
+Note that although the template sets up the function, your error messages will not automatically be enhanced. To enable the enhanced errors, call the function `utils::set_panic_hook()` in `lib.rs` when your code first runs. The function may be called multiple times if needed.
+
+For more details, see the [`console_error_panic_hook` repository](https://github.com/rustwasm/console_error_panic_hook).
\ No newline at end of file