diff --git a/.travis.yml b/.travis.yml
index 9f9ca012..bd04fbde 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -67,6 +67,19 @@ matrix:
- |
(cd examples/comments && sed -i 's/: "webpack-dev-server"/: "webpack"/' package.json && ./build.sh)
+ # Build the guide.
+ - rust: stable
+ script: (cd guide && cargo install mdbook --vers "^0.1.0" && mdbook build)
+ deploy:
+ provider: pages
+ skip-cleanup: true
+ github-token: $GITHUB_TOKEN # Set in travis-ci.org dashboard, marked secure
+ local-dir: guide
+ keep-history: false
+ on:
+ branch: master
+
+
install:
- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..e57cc943
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,49 @@
+# `wasm-bindgen` Change Log
+
+--------------------------------------------------------------------------------
+
+## Unreleased
+
+Released YYYY/MM/DD.
+
+### Added
+
+* TODO (or remove section if none)
+
+### Changed
+
+* TODO (or remove section if none)
+
+### Deprecated
+
+* TODO (or remove section if none)
+
+### Removed
+
+* TODO (or remove section if none)
+
+### Fixed
+
+* TODO (or remove section if none)
+
+### Security
+
+* TODO (or remove section if none)
+
+--------------------------------------------------------------------------------
+
+## 0.2.11
+
+Released 2018/05/24.
+
+--------------------------------------------------------------------------------
+
+## 0.2.10
+
+Released 2018/05/17.
+
+--------------------------------------------------------------------------------
+
+## 0.2.9
+
+Released 2018/05/11.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ca5ed2cf..f3df5504 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,40 +1,4 @@
# Contributing
-This document contains instructions on how to get this project up and running.
-For more information on the architecture, design, and goals of this project
-please checkout [`DESIGN.md`](DESIGN.md).
-
-## Prerequisites
-
-1. Rust Nightly. [Install Rust]. Once Rust is installed, run
-
- ```
- rustup default nightly
- ```
-
-[install Rust]: https://www.rust-lang.org/en-US/install.html
-
-2. The tests for this project use Node. Make sure you have node >= 8 installed,
- as that is when WebAssembly support was introduced. [Install Node].
-
-[Install Node]: https://nodejs.org/en/
-
-3. The tests for this project also use yarn, a package manager for Node. To install yarn, run:
-
- ```
- npm install yarn -g
- ```
-
- ... or follow other platform-specific instructions [here](https://yarnpkg.com/en/docs/install).
-
- Once `yarn` is installed, run it in the top level directory:
-
- ```
- yarn
- ```
-
- Finally, you can run the tests with `cargo`:
-
- ```
- cargo test
- ```
+See the ["Contributing" section of the `wasm-bindgen`
+guide](https://rustwasm.github.io/wasm-bindgen/contributing.html).
diff --git a/README.md b/README.md
index 242fa259..a66abb55 100644
--- a/README.md
+++ b/README.md
@@ -1,561 +1,62 @@
-# wasm-bindgen
+
-A project for facilitating high-level interactions between wasm modules and JS.
+# `wasm-bindgen`
-[Introduction blog post][post]
+**Facilitating high-level interactions between wasm modules and JavaScript.**
+
+[Introduction blog post: "JavaScript to Rust and Back Again: A `wasm-bindgen` Tale"][post]
[host]: https://github.com/WebAssembly/host-bindings
[post]: https://hacks.mozilla.org/2018/04/javascript-to-rust-and-back-again-a-wasm-bindgen-tale/
[](https://travis-ci.org/rustwasm/wasm-bindgen)
[](https://ci.appveyor.com/project/alexcrichton/wasm-bindgen)
+[](https://crates.io/crates/wasm-bindgen)
+[](https://crates.io/crates/wasm-bindgen)
+[](https://docs.rs/wasm-bindgen)
-This project is sort of half polyfill for features like the [host bindings
-proposal][host] and half features for empowering high-level interactions between
-JS and wasm-compiled code (currently mostly from Rust). More specifically this
-project allows JS/wasm to communicate with strings, JS objects, classes, etc, as
-opposed to purely integers and floats. Using `wasm-bindgen` for example you can
-define a JS class in Rust or take a string from JS or return one. The
-functionality is growing as well!
+Import JavaScript things into Rust and export Rust things to JavaScript.
-Currently this tool is Rust-focused but the underlying foundation is
-language-independent, and it's hoping that over time as this tool stabilizes
-that it can be used for languages like C/C++!
-
-Notable features of this project includes:
-
-* Importing JS functionality in to Rust such as [DOM manipulation][dom-ex],
- [console logging][console-log], or [performance monitoring][perf-ex].
-* [Exporting Rust functionality][smorg-ex] to JS such as classes, functions, etc.
-* Working with rich types like strings, numbers, classes, closures, and objects
- rather than simply `u32` and floats.
-
-This project is still relatively new but feedback is of course always
-welcome! If you're curious about the design plus even more information about
-what this crate can do, check out the [design doc].
-
-[design doc]: https://github.com/rustwasm/wasm-bindgen/blob/master/DESIGN.md
-[dom-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/dom
-[console-log]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/console_log
-[perf-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/performance
-[smorg-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/smorgasboard
-
-[hello-online]: https://webassembly.studio/?f=gzubao6tg3
-
-## Basic usage
-
-Let's implement the equivalent of "Hello, world!" for this crate.
-
-> **Note:** Currently this projects uses *nightly Rust* which you can acquire
-> through [rustup] and configure with `rustup default nightly`
-
-[rustup]: https://rustup.rs
-
-If you'd like you dive [straight into an online example][hello-online], but
-if you'd prefer to follow along in your own console let's install the tools we
-need:
-
-```
-$ rustup target add wasm32-unknown-unknown
-$ cargo install wasm-bindgen-cli
-```
-
-The first command here installs the wasm target so you can compile to it, and
-the latter will install the `wasm-bindgen` CLI tool we'll be using later.
-
-Next up let's make our project
-
-```
-$ cargo new js-hello-world --lib
-```
-
-Now let's add a dependency on this project inside `Cargo.toml` as well as
-configuring our build output:
-
-```toml
-[lib]
-crate-type = ["cdylib"]
-
-[dependencies]
-wasm-bindgen = "0.2"
-```
-
-Next up our actual code! We'll write this in `src/lib.rs`:
+`src/lib.rs`:
```rust
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
-
use wasm_bindgen::prelude::*;
+// Import the `window.alert` function from the Web.
#[wasm_bindgen]
extern {
fn alert(s: &str);
}
+// Export a `greet` function from Rust to JavaScript, that alerts a
+// hello message.
#[wasm_bindgen]
pub fn greet(name: &str) {
alert(&format!("Hello, {}!", name));
}
```
-And that's it! If we were to write the `greet` function naively without the
-`#[wasm_bindgen]` attribute then JS wouldn't be able to communicate with the
-types like `str`, so slapping a `#[wasm_bindgen]` on the function and the import
-of `alert` ensures that the right shims are generated.
+Use exported Rust things from JavaScript!
-Next up let's build our project:
-
-```
-$ cargo build --target wasm32-unknown-unknown
-```
-
-After this you'll have a wasm file at
-`target/wasm32-unknown-unknown/debug/js_hello_world.wasm`. Don't be alarmed at
-the size, this is an unoptimized program!
-
-Now that we've generated the wasm module it's time to run the bindgen tool
-itself! This tool will postprocess the wasm file rustc generated, generating a
-new wasm file and a set of JS bindings as well. Let's invoke it!
-
-```
-$ wasm-bindgen target/wasm32-unknown-unknown/debug/js_hello_world.wasm \
- --out-dir .
-```
-
-This is the main point where the magic happens. The `js_hello_world.wasm` file
-emitted by rustc contains *descriptors* of how to communicate via richer types
-than wasm currently supports. The `wasm-bindgen` tool will interpret this
-information, emitting a **replacement module** for the wasm file.
-
-The previous `js_hello_world.wasm` file is interpreted as if it were an ES6
-module. The `js_hello_world.js` file emitted by `wasm-bindgen` should have the
-intended interface of the wasm file, notably with rich types like strings,
-classes, etc.
-
-The `wasm-bindgen` tool also emits a few other files needed to implement this
-module. For example `js_hello_world_bg.wasm` is the original wasm file but
-postprocessed a bit. It's intended that the `js_hello_world_bg.wasm` file,
-like before, acts like an ES6 module.
-
-At this point you'll probably plug these files into a larger build system.
-Files emitted by `wasm-bindgen` act like normal ES6 modules (one just happens to
-be wasm). As of the time of this writing there's unfortunately not a lot of
-tools that natively do this, but Webpack's 4.0 beta release has native wasm
-support!. Let's take a look at that and see how it works.
-
-First create an `index.js` file:
+`index.js`:
```js
-const helloWorld = import("./js_hello_world");
-
-helloWorld.then(wasmModule => {
- wasmModule.greet("World!");
+// Asynchronously load, compile, and import the Rust's WebAssembly
+// and JavaScript interface.
+import("./hello_world").then(module => {
+ // Alert "Hello, World!"
+ module.greet("World!");
});
```
-Note that we're using `import(..)` here because Webpack [doesn't
-support][webpack-issue] synchronously importing modules from the main chunk just
-yet.
+## Guide
-[webpack-issue]: https://github.com/webpack/webpack/issues/6615
+[📚 Read the `wasm-bindgen` guide here! 📚](https://rustwasm.github.io/wasm-bindgen)
-Next our JS dependencies by creating a `package.json`:
-
-```json
-{
- "scripts": {
- "serve": "webpack-dev-server"
- },
- "devDependencies": {
- "webpack": "^4.0.1",
- "webpack-cli": "^2.0.10",
- "webpack-dev-server": "^3.1.0"
- }
-}
-```
-
-and our webpack configuration
-
-```js
-// webpack.config.js
-const path = require('path');
-
-module.exports = {
- entry: "./index.js",
- output: {
- path: path.resolve(__dirname, "dist"),
- filename: "index.js",
- },
- mode: "development"
-};
-```
-
-Our corresponding `index.html`:
-
-```html
-
-
-
-
-
-
-
-
-```
-
-And finally:
-
-```
-$ npm run serve
-```
-
-If you open https://localhost:8080 in a browser you should see a `Hello, world!`
-dialog pop up!
-
-If that was all a bit much, no worries! You can [execute this code
-online][hello-online] thanks to [WebAssembly Studio](https://webassembly.studio)
-or you can [follow along on GitHub][hello-tree] to see all the files necessary
-as well as a script to set it all up.
-
-[hello-tree]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/hello_world
-[hello-readme]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/hello_world/README.md
-
-## What just happened?
-
-Phew! That was a lot of words and a lot ended up happening along the way. There
-were two main pieces of magic happening: the `#[wasm_bindgen]` attribute and the
-`wasm-bindgen` CLI tool.
-
-**The `#[wasm_bindgen]` attribute**
-
-This attribute, exported from the `wasm-bindgen` crate, is the entrypoint to
-exposing Rust functions to JS. This is a procedural macro (hence requiring the
-nightly Rust toolchain) which will generate the appropriate shims in Rust to
-translate from your type signature to one that JS can interface with. Finally
-the attribute also serializes some information to the output artifact which
-`wasm-bindgen`-the-tool will discard after it parses.
-
-There's a more thorough explanation below of the various bits and pieces of the
-attribute, but it suffices for now to say that you can attach it to free
-functions, structs, impl blocks for those structs and `extern { ... }` blocks.
-Some Rust features like generics, lifetime parameters, etc, aren't supported on
-functions tagged with `#[wasm_bindgen]` right now.
-
-**The `wasm-bindgen` CLI tool**
-
-The next half of what happened here was all in the `wasm-bindgen` tool. This
-tool opened up the wasm module that rustc generated and found an encoded
-description of what was passed to the `#[wasm_bindgen]` attribute. You can
-think of this as the `#[wasm_bindgen]` attribute created a special section of
-the output module which `wasm-bindgen` strips and processes.
-
-This information gave `wasm-bindgen` all it needed to know to generate the JS
-file that we then imported. The JS file wraps instantiating the underlying wasm
-module (aka calling `WebAssembly.instantiate`) and then provides wrappers for
-classes/functions within.
-
-## What else can we do?
-
-Much more! Here's a taste of various features you can use in this project. You
-can also [explore this code online](https://webassembly.studio/?f=t61j18noqz):
-
-```rust
-// src/lib.rs
-#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
-
-extern crate wasm_bindgen;
-
-use wasm_bindgen::prelude::*;
-
-// Strings can both be passed in and received
-#[wasm_bindgen]
-pub fn concat(a: &str, b: &str) -> String {
- let mut a = a.to_string();
- a.push_str(b);
- return a
-}
-
-// A struct will show up as a class on the JS side of things
-#[wasm_bindgen]
-pub struct Foo {
- contents: u32,
-}
-
-#[wasm_bindgen]
-impl Foo {
- pub fn new() -> Foo {
- Foo { contents: 0 }
- }
-
- // Methods can be defined with `&mut self` or `&self`, and arguments you
- // can pass to a normal free function also all work in methods.
- pub fn add(&mut self, amt: u32) -> u32 {
- self.contents += amt;
- return self.contents
- }
-
- // You can also take a limited set of references to other types as well.
- pub fn add_other(&mut self, bar: &Bar) {
- self.contents += bar.contents;
- }
-
- // Ownership can work too!
- pub fn consume_other(&mut self, bar: Bar) {
- self.contents += bar.contents;
- }
-}
-
-#[wasm_bindgen]
-pub struct Bar {
- contents: u32,
- opaque: JsValue, // defined in `wasm_bindgen`, imported via prelude
-}
-
-#[wasm_bindgen(module = "./index")] // what ES6 module to import from
-extern {
- fn bar_on_reset(to: &str, opaque: &JsValue);
-
- // We can import classes and annotate functionality on those classes as well
- type Awesome;
- #[wasm_bindgen(constructor)]
- fn new() -> Awesome;
- #[wasm_bindgen(method)]
- fn get_internal(this: &Awesome) -> u32;
-}
-
-#[wasm_bindgen]
-impl Bar {
- pub fn from_str(s: &str, opaque: JsValue) -> Bar {
- let contents = s.parse().unwrap_or_else(|_| {
- Awesome::new().get_internal()
- });
- Bar { contents, opaque }
- }
-
- pub fn reset(&mut self, s: &str) {
- if let Ok(n) = s.parse() {
- bar_on_reset(s, &self.opaque);
- self.contents = n;
- }
- }
-}
-```
-
-The generated JS bindings for this invocation of the macro [look like
-this][bindings]. You can view them in action like so:
-
-[bindings]: https://gist.github.com/alexcrichton/3d85c505e785fb8ff32e2c1cf9618367
-
-and our corresponding `index.js`:
-
-```js
-import { Foo, Bar, concat } from "./js_hello_world";
-import { booted } from "./js_hello_world_wasm";
-
-export function bar_on_reset(s, token) {
- console.log(token);
- console.log(`this instance of bar was reset to ${s}`);
-}
-
-function assertEq(a, b) {
- if (a !== b)
- throw new Error(`${a} != ${b}`);
- console.log(`found ${a} === ${b}`);
-}
-
-function main() {
- assertEq(concat('a', 'b'), 'ab');
-
- // Note the `new Foo()` syntax cannot be used, static function
- // constructors must be used instead. Additionally objects allocated
- // corresponding to Rust structs will need to be deallocated on the
- // Rust side of things with an explicit call to `free`.
- let foo = Foo.new();
- assertEq(foo.add(10), 10);
- foo.free();
-
- // Pass objects to one another
- let foo1 = Foo.new();
- let bar = Bar.from_str("22", { opaque: 'object' });
- foo1.add_other(bar);
-
- // We also don't have to `free` the `bar` variable as this function is
- // transferring ownership to `foo1`
- bar.reset('34');
- foo1.consume_other(bar);
-
- assertEq(foo1.add(2), 22 + 34 + 2);
- foo1.free();
-
- alert('all passed!')
-}
-
-export class Awesome {
- constructor() {
- this.internal = 32;
- }
-
- get_internal() {
- return this.internal;
- }
-}
-
-booted.then(main);
-```
-
-## Closures
-
-The `#[wasm_bindgen]` attribute supports some Rust closures being passed to JS.
-Examples of what you can do are:
-
-```rust
-#[wasm_bindgen]
-extern {
- fn foo(a: &Fn()); // could also be `&mut FnMut()`
-}
-```
-
-Here a function `foo` is imported from JS where the first argument is a *stack
-closure*. You can call this function with a `&Fn()` argument and JS will receive
-a JS function. When the `foo` function returns, however, the JS function will be
-invalidated and any future usage of it will raise an exception.
-
-Closures also support arguments and return values like exports do, for example:
-
-```rust
-#[wasm_bindgen]
-extern {
- type Foo;
-
- fn bar(a: &Fn(u32, String) -> Foo);
-}
-```
-
-Sometimes the stack behavior of these closures is not desired. For example you'd
-like to schedule a closure to be run on the next turn of the event loop in JS
-through `setTimeout`. For this you want the imported function to return but the
-JS closure still needs to be valid!
-
-To support this use case you can do:
-
-```rust
-use wasm_bindgen::prelude::*;
-
-#[wasm_bindgen]
-extern {
- fn baz(a: &Closure);
-}
-```
-
-The `Closure` type is defined in the `wasm_bindgen` crate and represents a "long
-lived" closure. The JS closure passed to `baz` is still valid after `baz`
-returns, and the validity of the JS closure is tied to the lifetime of the
-`Closure` in Rust. Once `Closure` is dropped it will deallocate its internal
-memory and invalidate the corresponding JS function.
-
-Like stack closures a `Closure` also supports `FnMut`:
-
-```rust
-use wasm_bindgen::prelude::*;
-
-#[wasm_bindgen]
-extern {
- fn another(a: &Closure u32>);
-}
-```
-
-At this time you cannot [pass a JS closure to Rust][cbjs], you can only pass a
-Rust closure to JS in limited circumstances.
-
-[cbjs]: https://github.com/rustwasm/wasm-bindgen/issues/103
-
-## Feature reference
-
-Here this section will attempt to be a reference for the various features
-implemented in this project. This is likely not exhaustive but the [tests]
-should also be a great place to look for examples.
-
-[tests]: https://github.com/rustwasm/wasm-bindgen/tree/master/tests
-
-The `#[wasm_bindgen]` attribute can be attached to functions, structs,
-impls, and foreign modules. Impls can only contain functions, and the attribute
-cannot be attached to functions in an impl block or functions in a foreign
-module. No lifetime parameters or type parameters are allowed on any of these
-types. Foreign modules must have the `"C"` abi (or none listed). Free functions
-with `#[wasm_bindgen]` might not have the `"C"` abi or none listed, and it's also not
-necessary to annotate with the `#[no_mangle]` attribute.
-
-All structs referenced through arguments to functions should be defined in the
-macro itself. Arguments allowed implement the `WasmBoundary` trait, and examples
-are:
-
-* Integers (u64/i64 require `BigInt` support)
-* Floats
-* Borrowed strings (`&str`)
-* Owned strings (`String`)
-* Exported structs (`Foo`, annotated with `#[wasm_bindgen]`)
-* Exported C-like enums (`Foo`, annotated with `#[wasm_bindgen]`)
-* Imported types in a foreign module annotated with `#[wasm_bindgen]`
-* Borrowed exported structs (`&Foo` or `&mut Bar`)
-* The `JsValue` type and `&JsValue` (not mutable references)
-* Vectors and slices of supported integer types and of the `JsValue` type.
-
-All of the above can also be returned except borrowed references. Passing
-`Vec` as an argument to a function is not currently supported. Strings are
-implemented with shim functions to copy data in/out of the Rust heap. That is, a
-string passed to Rust from JS is copied to the Rust heap (using a generated shim
-to malloc some space) and then will be freed appropriately.
-
-Owned values are implemented through boxes. When you return a `Foo` it's
-actually turned into `Box>` under the hood and returned to JS as a
-pointer. The pointer is to have a defined ABI, and the `RefCell` is to ensure
-safety with reentrancy and aliasing in JS. In general you shouldn't see
-`RefCell` panics with normal usage.
-
-JS-values-in-Rust are implemented through indexes that index a table generated
-as part of the JS bindings. This table is managed via the ownership specified in
-Rust and through the bindings that we're returning. More information about this
-can be found in the [design doc].
-
-All of these constructs currently create relatively straightforward code on the
-JS side of things, mostly having a 1:1 match in Rust with JS.
-
-## CLI Reference
-
-The `wasm-bindgen` tool has a number of options available to it to tweak the JS
-that is generated. By default the generated JS uses ES modules and is compatible
-with both Node and browsers (but will likely require a bundler for both use
-cases).
-
-Supported flags of the CLI tool can be learned via `wasm-bindgen --help`, but
-some notable options are:
-
-* `--nodejs` - this flag will tailor output for Node instead of browsers,
- allowing for native usage of `require` of the generated JS and internally
- using `require` instead of ES modules. When using this flag no further
- postprocessing (aka a bundler) should be necessary to work with the wasm.
-
-* `--browser` - this flag will tailor the output specifically for browsers,
- making it incompatible with Node. This will basically make the generated JS a
- tiny bit smaller as runtime checks for Node won't be necessary.
-
-* `--no-modules` - the default output of `wasm-bindgen` uses ES modules but this
- option indicates that ES modules should not be used and output should be
- tailored for a web browser. In this mode `window.wasm_bindgen` will be a
- function that takes a path to the wasm file to fetch and instantiate.
- Afterwards exported functions from the wasm are available through
- `window.wasm_bindgen.foo`. Note that the name `wasm_bindgen` can be configured
- with the `--no-modules-global FOO` flag.
-
-* `--no-typescript` - by default a `*.d.ts` file is generated for the generated
- JS file, but this flag will disable generating this TypeScript file.
-
-* `--debug` - generates a bit more JS and wasm in "debug mode" to help catch
- programmer errors, but this output isn't intended to be shipped to production
-
-# License
+## License
This project is licensed under either of
@@ -566,13 +67,13 @@ This project is licensed under either of
at your option.
-### Contribution
+## Contribution
+
+**[See the "Contributing" section of the guide for information on
+hacking on `wasm-bindgen`!][contributing]**
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.
-### Tests
-
-In order to run the tests you will need [node.js](https://nodejs.org/) version
-8.9.4 or above. Running the tests is done by running `cargo test`.
+[contributing]: https://rustwasm.github.io/wasm-bindgen/contributing.html
diff --git a/guide/.gitignore b/guide/.gitignore
new file mode 100644
index 00000000..7585238e
--- /dev/null
+++ b/guide/.gitignore
@@ -0,0 +1 @@
+book
diff --git a/guide/book.toml b/guide/book.toml
new file mode 100644
index 00000000..0bc365df
--- /dev/null
+++ b/guide/book.toml
@@ -0,0 +1,5 @@
+[book]
+authors = ["Nick Fitzgerald"]
+multilingual = false
+src = "src"
+title = "The `wasm-bindgen` Guide"
diff --git a/guide/src/SUMMARY.md b/guide/src/SUMMARY.md
new file mode 100644
index 00000000..ab0a23ef
--- /dev/null
+++ b/guide/src/SUMMARY.md
@@ -0,0 +1,18 @@
+# Summary
+
+[Introduction](./introduction.md)
+
+--------------------------------------------------------------------------------
+
+- [Basic Usage](./basic-usage.md)
+- [What Just Happened?](./what-just-happened.md)
+- [What Else Can We Do?](./what-else-can-we-do.md)
+- [Closures](./closures.md)
+- [Feature Reference](./feature-reference.md)
+- [CLI Reference](./cli-reference.md)
+
+--------------------------------------------------------------------------------
+
+- [Contributing](./contributing.md)
+ - [Design](./design.md)
+ - [Team](./team.md)
diff --git a/guide/src/basic-usage.md b/guide/src/basic-usage.md
new file mode 100644
index 00000000..173ed288
--- /dev/null
+++ b/guide/src/basic-usage.md
@@ -0,0 +1,178 @@
+# Basic Usage
+
+Let's implement the equivalent of "Hello, world!" for this crate.
+
+> **Note:** Currently this projects uses *nightly Rust* which you can acquire
+> through [rustup] and configure with `rustup default nightly`
+
+[rustup]: https://rustup.rs
+
+If you'd like you dive [straight into an online example][hello-online], but
+if you'd prefer to follow along in your own console let's install the tools we
+need:
+
+```shell
+$ rustup target add wasm32-unknown-unknown
+$ cargo +nightly install wasm-bindgen-cli
+```
+
+The first command here installs the wasm target so you can compile to it, and
+the latter will install the `wasm-bindgen` CLI tool we'll be using later.
+
+Next up let's make our project
+
+```shell
+$ cargo +nightly new js-hello-world --lib
+```
+
+Now let's add a dependency on this project inside `Cargo.toml` as well as
+configuring our build output:
+
+```toml
+[lib]
+crate-type = ["cdylib"]
+
+[dependencies]
+wasm-bindgen = "0.2"
+```
+
+Next up our actual code! We'll write this in `src/lib.rs`:
+
+```rust,ignore
+#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
+
+extern crate wasm_bindgen;
+use wasm_bindgen::prelude::*;
+
+#[wasm_bindgen]
+extern {
+ fn alert(s: &str);
+}
+
+#[wasm_bindgen]
+pub fn greet(name: &str) {
+ alert(&format!("Hello, {}!", name));
+}
+```
+
+And that's it! If we were to write the `greet` function naively without the
+`#[wasm_bindgen]` attribute then JS wouldn't be able to communicate with the
+types like `str`, so slapping a `#[wasm_bindgen]` on the function and the import
+of `alert` ensures that the right shims are generated.
+
+Next up let's build our project:
+
+```shell
+$ cargo +nightly build --target wasm32-unknown-unknown
+```
+
+After this you'll have a wasm file at
+`target/wasm32-unknown-unknown/debug/js_hello_world.wasm`. Don't be alarmed at
+the size, this is an unoptimized program!
+
+Now that we've generated the wasm module it's time to run the bindgen tool
+itself! This tool will postprocess the wasm file rustc generated, generating a
+new wasm file and a set of JS bindings as well. Let's invoke it!
+
+```shell
+$ wasm-bindgen target/wasm32-unknown-unknown/debug/js_hello_world.wasm \
+ --out-dir .
+```
+
+This is the main point where the magic happens. The `js_hello_world.wasm` file
+emitted by rustc contains *descriptors* of how to communicate via richer types
+than wasm currently supports. The `wasm-bindgen` tool will interpret this
+information, emitting a **replacement module** for the wasm file.
+
+The previous `js_hello_world.wasm` file is interpreted as if it were an ES6
+module. The `js_hello_world.js` file emitted by `wasm-bindgen` should have the
+intended interface of the wasm file, notably with rich types like strings,
+classes, etc.
+
+The `wasm-bindgen` tool also emits a few other files needed to implement this
+module. For example `js_hello_world_bg.wasm` is the original wasm file but
+postprocessed a bit. It's intended that the `js_hello_world_bg.wasm` file,
+like before, acts like an ES6 module.
+
+At this point you'll probably plug these files into a larger build system.
+Files emitted by `wasm-bindgen` act like normal ES6 modules (one just happens to
+be wasm). As of the time of this writing there's unfortunately not a lot of
+tools that natively do this, but Webpack's 4.0 beta release has native wasm
+support!. Let's take a look at that and see how it works.
+
+First create an `index.js` file:
+
+```js
+const js = import("./js_hello_world");
+
+js.then(js => {
+ js.greet("World!");
+});
+```
+
+Note that we're using `import(..)` here because Webpack [doesn't
+support][webpack-issue] synchronously importing modules from the main chunk just
+yet.
+
+[webpack-issue]: https://github.com/webpack/webpack/issues/6615
+
+Next our JS dependencies by creating a `package.json`:
+
+```json
+{
+ "scripts": {
+ "serve": "webpack-dev-server"
+ },
+ "devDependencies": {
+ "webpack": "^4.0.1",
+ "webpack-cli": "^2.0.10",
+ "webpack-dev-server": "^3.1.0"
+ }
+}
+```
+
+and our webpack configuration
+
+```js
+// webpack.config.js
+const path = require('path');
+
+module.exports = {
+ entry: "./index.js",
+ output: {
+ path: path.resolve(__dirname, "dist"),
+ filename: "index.js",
+ },
+ mode: "development"
+};
+```
+
+Our corresponding `index.html`:
+
+```html
+
+
+
+
+
+
+
+
+```
+
+And finally:
+
+```shell
+$ npm run serve
+```
+
+If you open https://localhost:8080 in a browser you should see a `Hello, world!`
+dialog pop up!
+
+If that was all a bit much, no worries! You can [execute this code
+online][hello-online] thanks to [WebAssembly Studio](https://webassembly.studio)
+or you can [follow along on GitHub][hello-tree] to see all the files necessary
+as well as a script to set it all up.
+
+[hello-tree]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/hello_world
+[hello-readme]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/hello_world/README.md
diff --git a/guide/src/cli-reference.md b/guide/src/cli-reference.md
new file mode 100644
index 00000000..d8878120
--- /dev/null
+++ b/guide/src/cli-reference.md
@@ -0,0 +1,32 @@
+# CLI Reference
+
+The `wasm-bindgen` tool has a number of options available to it to tweak the JS
+that is generated. By default the generated JS uses ES modules and is compatible
+with both Node and browsers (but will likely require a bundler for both use
+cases).
+
+Supported flags of the CLI tool can be learned via `wasm-bindgen --help`, but
+some notable options are:
+
+* `--nodejs`: this flag will tailor output for Node instead of browsers,
+ allowing for native usage of `require` of the generated JS and internally
+ using `require` instead of ES modules. When using this flag no further
+ postprocessing (aka a bundler) should be necessary to work with the wasm.
+
+* `--browser`: this flag will tailor the output specifically for browsers,
+ making it incompatible with Node. This will basically make the generated JS a
+ tiny bit smaller as runtime checks for Node won't be necessary.
+
+* `--no-modules`: the default output of `wasm-bindgen` uses ES modules but this
+ option indicates that ES modules should not be used and output should be
+ tailored for a web browser. In this mode `window.wasm_bindgen` will be a
+ function that takes a path to the wasm file to fetch and instantiate.
+ Afterwards exported functions from the wasm are available through
+ `window.wasm_bindgen.foo`. Note that the name `wasm_bindgen` can be configured
+ with the `--no-modules-global FOO` flag.
+
+* `--no-typescript`: by default a `*.d.ts` file is generated for the generated
+ JS file, but this flag will disable generating this TypeScript file.
+
+* `--debug`: generates a bit more JS and wasm in "debug mode" to help catch
+ programmer errors, but this output isn't intended to be shipped to production
diff --git a/guide/src/closures.md b/guide/src/closures.md
new file mode 100644
index 00000000..1b921505
--- /dev/null
+++ b/guide/src/closures.md
@@ -0,0 +1,65 @@
+# Closures
+
+The `#[wasm_bindgen]` attribute supports some Rust closures being passed to JS.
+Examples of what you can do are:
+
+```rust
+#[wasm_bindgen]
+extern {
+ fn foo(a: &Fn()); // could also be `&mut FnMut()`
+}
+```
+
+Here a function `foo` is imported from JS where the first argument is a *stack
+closure*. You can call this function with a `&Fn()` argument and JS will receive
+a JS function. When the `foo` function returns, however, the JS function will be
+invalidated and any future usage of it will raise an exception.
+
+Closures also support arguments and return values like exports do, for example:
+
+```rust
+#[wasm_bindgen]
+extern {
+ type Foo;
+
+ fn bar(a: &Fn(u32, String) -> Foo);
+}
+```
+
+Sometimes the stack behavior of these closures is not desired. For example you'd
+like to schedule a closure to be run on the next turn of the event loop in JS
+through `setTimeout`. For this you want the imported function to return but the
+JS closure still needs to be valid!
+
+To support this use case you can do:
+
+```rust
+use wasm_bindgen::prelude::*;
+
+#[wasm_bindgen]
+extern {
+ fn baz(a: &Closure);
+}
+```
+
+The `Closure` type is defined in the `wasm_bindgen` crate and represents a "long
+lived" closure. The JS closure passed to `baz` is still valid after `baz`
+returns, and the validity of the JS closure is tied to the lifetime of the
+`Closure` in Rust. Once `Closure` is dropped it will deallocate its internal
+memory and invalidate the corresponding JS function.
+
+Like stack closures a `Closure` also supports `FnMut`:
+
+```rust
+use wasm_bindgen::prelude::*;
+
+#[wasm_bindgen]
+extern {
+ fn another(a: &Closure u32>);
+}
+```
+
+At this time you cannot [pass a JS closure to Rust][cbjs], you can only pass a
+Rust closure to JS in limited circumstances.
+
+[cbjs]: https://github.com/rustwasm/wasm-bindgen/issues/103
diff --git a/guide/src/contributing.md b/guide/src/contributing.md
new file mode 100644
index 00000000..8804e4c6
--- /dev/null
+++ b/guide/src/contributing.md
@@ -0,0 +1,43 @@
+# Contributing to `wasm-bindgen`
+
+This section contains instructions on how to get this project up and running for
+development.
+
+## Prerequisites
+
+1. Rust Nightly. [Install Rust]. Once Rust is installed, run
+
+ ```shell
+ rustup default nightly
+ ```
+
+[install Rust]: https://www.rust-lang.org/en-US/install.html
+
+2. The tests for this project use Node. Make sure you have node >= 8 installed,
+ as that is when WebAssembly support was introduced. [Install Node].
+
+[Install Node]: https://nodejs.org/en/
+
+3. The tests for this project also use `yarn`, a package manager for Node. To
+ install `yarn`, run:
+
+ ```shell
+ npm install -g yarn
+ ```
+
+ or follow other platform-specific instructions
+ [here](https://yarnpkg.com/en/docs/install).
+
+ Once `yarn` is installed, run it in the top level directory:
+
+ ```shell
+ yarn
+ ```
+
+## Running Tests
+
+Finally, you can run the tests with `cargo`:
+
+```shell
+cargo test
+```
diff --git a/DESIGN.md b/guide/src/design.md
similarity index 100%
rename from DESIGN.md
rename to guide/src/design.md
diff --git a/guide/src/feature-reference.md b/guide/src/feature-reference.md
new file mode 100644
index 00000000..d361f7f7
--- /dev/null
+++ b/guide/src/feature-reference.md
@@ -0,0 +1,50 @@
+# Feature Reference
+
+Here this section will attempt to be a reference for the various features
+implemented in this project. This is likely not exhaustive but the [tests]
+should also be a great place to look for examples.
+
+[tests]: https://github.com/rustwasm/wasm-bindgen/tree/master/tests
+
+The `#[wasm_bindgen]` attribute can be attached to functions, structs,
+impls, and foreign modules. Impls can only contain functions, and the attribute
+cannot be attached to functions in an impl block or functions in a foreign
+module. No lifetime parameters or type parameters are allowed on any of these
+types. Foreign modules must have the `"C"` abi (or none listed). Free functions
+with `#[wasm_bindgen]` might not have the `"C"` abi or none listed, and it's also not
+necessary to annotate with the `#[no_mangle]` attribute.
+
+All structs referenced through arguments to functions should be defined in the
+macro itself. Arguments allowed implement the `WasmBoundary` trait, and examples
+are:
+
+* Integers (u64/i64 require `BigInt` support)
+* Floats
+* Borrowed strings (`&str`)
+* Owned strings (`String`)
+* Exported structs (`Foo`, annotated with `#[wasm_bindgen]`)
+* Exported C-like enums (`Foo`, annotated with `#[wasm_bindgen]`)
+* Imported types in a foreign module annotated with `#[wasm_bindgen]`
+* Borrowed exported structs (`&Foo` or `&mut Bar`)
+* The `JsValue` type and `&JsValue` (not mutable references)
+* Vectors and slices of supported integer types and of the `JsValue` type.
+
+All of the above can also be returned except borrowed references. Passing
+`Vec` as an argument to a function is not currently supported. Strings are
+implemented with shim functions to copy data in/out of the Rust heap. That is, a
+string passed to Rust from JS is copied to the Rust heap (using a generated shim
+to malloc some space) and then will be freed appropriately.
+
+Owned values are implemented through boxes. When you return a `Foo` it's
+actually turned into `Box>` under the hood and returned to JS as a
+pointer. The pointer is to have a defined ABI, and the `RefCell` is to ensure
+safety with reentrancy and aliasing in JS. In general you shouldn't see
+`RefCell` panics with normal usage.
+
+JS-values-in-Rust are implemented through indexes that index a table generated
+as part of the JS bindings. This table is managed via the ownership specified in
+Rust and through the bindings that we're returning. More information about this
+can be found in the [design doc].
+
+All of these constructs currently create relatively straightforward code on the
+JS side of things, mostly having a 1:1 match in Rust with JS.
diff --git a/guide/src/introduction.md b/guide/src/introduction.md
new file mode 100644
index 00000000..e1cf5366
--- /dev/null
+++ b/guide/src/introduction.md
@@ -0,0 +1,36 @@
+# Introduction
+
+`wasm-bindgen` facilitates high-level interactions between wasm modules and
+JavaScript.
+
+This project is sort of half polyfill for features like the [host bindings
+proposal][host] and half features for empowering high-level interactions between
+JS and wasm-compiled code (currently mostly from Rust). More specifically this
+project allows JS/wasm to communicate with strings, JS objects, classes, etc, as
+opposed to purely integers and floats. Using `wasm-bindgen` for example you can
+define a JS class in Rust or take a string from JS or return one. The
+functionality is growing as well!
+
+Currently this tool is Rust-focused but the underlying foundation is
+language-independent, and it's hoping that over time as this tool stabilizes
+that it can be used for languages like C/C++!
+
+Notable features of this project includes:
+
+* Importing JS functionality in to Rust such as [DOM manipulation][dom-ex],
+ [console logging][console-log], or [performance monitoring][perf-ex].
+* [Exporting Rust functionality][smorg-ex] to JS such as classes, functions, etc.
+* Working with rich types like strings, numbers, classes, closures, and objects
+ rather than simply `u32` and floats.
+
+This project is still relatively new but feedback is of course always
+welcome! If you're curious about the design plus even more information about
+what this crate can do, check out the [design doc].
+
+[host]: https://github.com/WebAssembly/host-bindings
+[design doc]: https://rustwasm.github.io/wasm-bindgen/design.html
+[dom-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/dom
+[console-log]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/console_log
+[perf-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/performance
+[smorg-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/smorgasboard
+[hello-online]: https://webassembly.studio/?f=gzubao6tg3
diff --git a/guide/src/team.md b/guide/src/team.md
new file mode 100644
index 00000000..261be7f2
--- /dev/null
+++ b/guide/src/team.md
@@ -0,0 +1,30 @@
+# Team
+
+`wasm-bindgen` follows the [`rustwasm` organization's governance described
+here][governance]:
+
+* All pull requests (including those made by a team member) must be approved by
+ at least one other team member.
+
+* Larger, more nuanced decisions about design, architecture, breaking changes,
+ trade offs, etc are made by team consensus.
+
+[governance]: https://github.com/rustwasm/team/blob/master/GOVERNANCE.md#repositories
+
+## Members
+
+
+
+| [][alexcrichton] | [][fitzgen] | [][spastorino] | [][ohanar] |
+|:---:|:---:|:---:|:---:|
+| [`alexcrichton`][alexcrichton] | [`fitzgen`][fitzgen] | [`spastorino`][spastorino] | [`ohanar`][ohanar] |
+
+[alexcrichton]: https://github.com/alexcrichton
+[fitzgen]: https://github.com/fitzgen
+[spastorino]: https://github.com/spastorino
+[ohanar]: https://github.com/ohanar
diff --git a/guide/src/what-else-can-we-do.md b/guide/src/what-else-can-we-do.md
new file mode 100644
index 00000000..b6f58a7b
--- /dev/null
+++ b/guide/src/what-else-can-we-do.md
@@ -0,0 +1,148 @@
+# What Else Can We Do?
+
+Much more! Here's a taste of various features you can use in this project. You
+can also [explore this code online](https://webassembly.studio/?f=t61j18noqz):
+
+```rust,ignore
+// src/lib.rs
+#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
+
+extern crate wasm_bindgen;
+
+use wasm_bindgen::prelude::*;
+
+// Strings can both be passed in and received
+#[wasm_bindgen]
+pub fn concat(a: &str, b: &str) -> String {
+ let mut a = a.to_string();
+ a.push_str(b);
+ return a
+}
+
+// A struct will show up as a class on the JS side of things
+#[wasm_bindgen]
+pub struct Foo {
+ contents: u32,
+}
+
+#[wasm_bindgen]
+impl Foo {
+ pub fn new() -> Foo {
+ Foo { contents: 0 }
+ }
+
+ // Methods can be defined with `&mut self` or `&self`, and arguments you
+ // can pass to a normal free function also all work in methods.
+ pub fn add(&mut self, amt: u32) -> u32 {
+ self.contents += amt;
+ return self.contents
+ }
+
+ // You can also take a limited set of references to other types as well.
+ pub fn add_other(&mut self, bar: &Bar) {
+ self.contents += bar.contents;
+ }
+
+ // Ownership can work too!
+ pub fn consume_other(&mut self, bar: Bar) {
+ self.contents += bar.contents;
+ }
+}
+
+#[wasm_bindgen]
+pub struct Bar {
+ contents: u32,
+ opaque: JsValue, // defined in `wasm_bindgen`, imported via prelude
+}
+
+#[wasm_bindgen(module = "./index")] // what ES6 module to import from
+extern {
+ fn bar_on_reset(to: &str, opaque: &JsValue);
+
+ // We can import classes and annotate functionality on those classes as well
+ type Awesome;
+ #[wasm_bindgen(constructor)]
+ fn new() -> Awesome;
+ #[wasm_bindgen(method)]
+ fn get_internal(this: &Awesome) -> u32;
+}
+
+#[wasm_bindgen]
+impl Bar {
+ pub fn from_str(s: &str, opaque: JsValue) -> Bar {
+ let contents = s.parse().unwrap_or_else(|_| {
+ Awesome::new().get_internal()
+ });
+ Bar { contents, opaque }
+ }
+
+ pub fn reset(&mut self, s: &str) {
+ if let Ok(n) = s.parse() {
+ bar_on_reset(s, &self.opaque);
+ self.contents = n;
+ }
+ }
+}
+```
+
+The generated JS bindings for this invocation of the macro [look like
+this][bindings]. You can view them in action like so:
+
+[bindings]: https://gist.github.com/alexcrichton/3d85c505e785fb8ff32e2c1cf9618367
+
+and our corresponding `index.js`:
+
+```js
+import { Foo, Bar, concat } from "./js_hello_world";
+import { booted } from "./js_hello_world_wasm";
+
+export function bar_on_reset(s, token) {
+ console.log(token);
+ console.log(`this instance of bar was reset to ${s}`);
+}
+
+function assertEq(a, b) {
+ if (a !== b)
+ throw new Error(`${a} != ${b}`);
+ console.log(`found ${a} === ${b}`);
+}
+
+function main() {
+ assertEq(concat('a', 'b'), 'ab');
+
+ // Note the `new Foo()` syntax cannot be used, static function
+ // constructors must be used instead. Additionally objects allocated
+ // corresponding to Rust structs will need to be deallocated on the
+ // Rust side of things with an explicit call to `free`.
+ let foo = Foo.new();
+ assertEq(foo.add(10), 10);
+ foo.free();
+
+ // Pass objects to one another
+ let foo1 = Foo.new();
+ let bar = Bar.from_str("22", { opaque: 'object' });
+ foo1.add_other(bar);
+
+ // We also don't have to `free` the `bar` variable as this function is
+ // transferring ownership to `foo1`
+ bar.reset('34');
+ foo1.consume_other(bar);
+
+ assertEq(foo1.add(2), 22 + 34 + 2);
+ foo1.free();
+
+ alert('all passed!')
+}
+
+export class Awesome {
+ constructor() {
+ this.internal = 32;
+ }
+
+ get_internal() {
+ return this.internal;
+ }
+}
+
+booted.then(main);
+```
diff --git a/guide/src/what-just-happened.md b/guide/src/what-just-happened.md
new file mode 100644
index 00000000..48a45b11
--- /dev/null
+++ b/guide/src/what-just-happened.md
@@ -0,0 +1,33 @@
+# What Just Happened?
+
+Phew! That was a lot of words and a lot ended up happening along the way. There
+were two main pieces of magic happening: the `#[wasm_bindgen]` attribute and the
+`wasm-bindgen` CLI tool.
+
+**The `#[wasm_bindgen]` attribute**
+
+This attribute, exported from the `wasm-bindgen` crate, is the entrypoint to
+exposing Rust functions to JS. This is a procedural macro (hence requiring the
+nightly Rust toolchain) which will generate the appropriate shims in Rust to
+translate from your type signature to one that JS can interface with. Finally
+the attribute also serializes some information to the output artifact which
+`wasm-bindgen`-the-tool will discard after it parses.
+
+There's a more thorough explanation below of the various bits and pieces of the
+attribute, but it suffices for now to say that you can attach it to free
+functions, structs, impl blocks for those structs and `extern { ... }` blocks.
+Some Rust features like generics, lifetime parameters, etc, aren't supported on
+functions tagged with `#[wasm_bindgen]` right now.
+
+**The `wasm-bindgen` CLI tool**
+
+The next half of what happened here was all in the `wasm-bindgen` tool. This
+tool opened up the wasm module that rustc generated and found an encoded
+description of what was passed to the `#[wasm_bindgen]` attribute. You can
+think of this as the `#[wasm_bindgen]` attribute created a special section of
+the output module which `wasm-bindgen` strips and processes.
+
+This information gave `wasm-bindgen` all it needed to know to generate the JS
+file that we then imported. The JS file wraps instantiating the underlying wasm
+module (aka calling `WebAssembly.instantiate`) and then provides wrappers for
+classes/functions within.
diff --git a/releases/friends.sh b/releases/friends.sh
new file mode 100755
index 00000000..4486b422
--- /dev/null
+++ b/releases/friends.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+set -eu
+set -o pipefail
+
+cd $(dirname $0)
+
+if [[ -z "${1+x}" ]]; then
+ read -p "List friends since which commit/tag? " since
+ echo
+else
+ since=$1
+fi
+
+git shortlog -s -n "$since.." \
+ | cut -f 2- \
+ | sort -u \
+ | grep -v bors\-servo \
+ | xargs -d '\n' -I{} echo "- {}"
diff --git a/releases/release-announcement-template.md b/releases/release-announcement-template.md
new file mode 100644
index 00000000..a1feaf4b
--- /dev/null
+++ b/releases/release-announcement-template.md
@@ -0,0 +1,39 @@
+# Announcing `wasm-bindgen` $TODO_VERSION
+
+`wasm-bindgen` facilitates high-level interactions between wasm modules and
+JavaScript.
+
+* [GitHub][]
+* [crates.io][]
+* [The `wasm-bindgen` Guide][guide]
+
+Upgrade to this release by updating your `Cargo.toml`:
+
+```toml
+wasm-bindgen = "$TODO_VERSION"
+```
+
+## Changelog
+
+
+
+## Friends
+
+Thanks to everyone who contributed to this release!
+
+
+
+## Contributing
+
+Want to join us? Check out our [The "Contributing" section of the
+guide][contributing] and take a look at some of these issues:
+
+* [Issues labeled "good first issue"][good-first-issue]
+* [Issues labeled "help wanted"][help-wanted]
+
+[GitHub]: https://github.com/rustwasm/wasm-bindgen
+[crates.io]: https://crates.io/crates/wasm-bindgen
+[guide]: https://rustwasm.github.io/wasm-bindgen
+[contributing]: https://rustwasm.github.io/wasm-bindgen/contributing.md
+[good-first-issue]: https://github.com/rustwasm/wasm-bindgen/labels/good%20first%20issue
+[help-wanted]: https://github.com/rustwasm/wasm-bindgen/labels/help%20wanted