From f73b53c5ab2e530f4fd065094b7cc1034457d09d Mon Sep 17 00:00:00 2001
From: printfn <printfn@users.noreply.github.com>
Date: Sat, 29 Oct 2022 09:08:09 +1300
Subject: [PATCH] Switch from failure to anyhow

---
 Cargo.lock                         | 870 ++++++++++++++++++++++-------
 Cargo.toml                         |   6 +-
 src/bindgen.rs                     |  12 +-
 src/build/mod.rs                   |  14 +-
 src/build/wasm_target.rs           |  12 +-
 src/cache.rs                       |   3 +-
 src/child.rs                       |   6 +-
 src/command/build.rs               |  34 +-
 src/command/generate.rs            |   9 +-
 src/command/login.rs               |   4 +-
 src/command/mod.rs                 |   5 +-
 src/command/pack.rs                |   7 +-
 src/command/publish/access.rs      |   4 +-
 src/command/publish/mod.rs         |   7 +-
 src/command/test.rs                |  30 +-
 src/command/utils.rs               |   8 +-
 src/generate.rs                    |   8 +-
 src/install/arch.rs                |   3 +-
 src/install/krate.rs               |   3 +-
 src/install/mod.rs                 |  33 +-
 src/install/mode.rs                |   5 +-
 src/install/os.rs                  |   3 +-
 src/installer.rs                   |  12 +-
 src/lib.rs                         |   5 +-
 src/license.rs                     |  18 +-
 src/lockfile.rs                    |  14 +-
 src/main.rs                        |  10 +-
 src/manifest/mod.rs                |  32 +-
 src/npm.rs                         |  12 +-
 src/progressbar.rs                 |   5 +-
 src/readme.rs                      |   4 +-
 src/stamps.rs                      |  24 +-
 src/test/mod.rs                    |   4 +-
 src/test/webdriver.rs              |   4 +-
 src/test/webdriver/chromedriver.rs |  16 +-
 src/test/webdriver/geckodriver.rs  |  22 +-
 src/test/webdriver/safaridriver.rs |   3 +-
 src/wasm_opt.rs                    |  13 +-
 tests/all/download.rs              |   6 +-
 tests/all/license.rs               |   2 +-
 tests/all/main.rs                  |   5 +-
 tests/all/readme.rs                |   2 +-
 tests/all/test.rs                  |   3 +
 tests/all/utils/file.rs            |   4 +-
 tests/all/utils/manifest.rs        |   6 +-
 tests/all/webdriver.rs             |   1 +
 46 files changed, 857 insertions(+), 456 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index cebccd6..69eef93 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -17,15 +17,36 @@ version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
 
+[[package]]
+name = "aes"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
+dependencies = [
+ "cfg-if 1.0.0",
+ "cipher",
+ "cpufeatures",
+ "opaque-debug",
+]
+
 [[package]]
 name = "aho-corasick"
-version = "0.7.18"
+version = "0.7.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
 dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "ansi_term"
 version = "0.12.1"
@@ -36,16 +57,10 @@ dependencies = [
 ]
 
 [[package]]
-name = "arrayref"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
-
-[[package]]
-name = "arrayvec"
-version = "0.5.2"
+name = "anyhow"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
+checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
 
 [[package]]
 name = "assert_cmd"
@@ -87,9 +102,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
 [[package]]
 name = "backtrace"
-version = "0.3.65"
+version = "0.3.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61"
+checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
 dependencies = [
  "addr2line",
  "cc",
@@ -110,24 +125,24 @@ dependencies = [
 ]
 
 [[package]]
-name = "base64"
-version = "0.13.0"
+name = "base64ct"
+version = "1.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf"
 
 [[package]]
 name = "binary-install"
-version = "0.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b5bc5f8c50dd6a80d0b303ddab79f42ddcb52fd43d68107ecf622c551fd4cd4"
+version = "0.0.3-alpha.1"
+source = "git+https://github.com/rustwasm/binary-install?rev=6d60f6731c8294000ea8f3a0260659b025cf7f94#6d60f6731c8294000ea8f3a0260659b025cf7f94"
 dependencies = [
+ "anyhow",
  "curl",
- "dirs",
- "failure",
+ "dirs-next",
  "flate2",
+ "fs2",
  "hex",
  "is_executable",
- "siphasher",
+ "siphasher 0.3.10",
  "tar",
  "zip",
 ]
@@ -139,16 +154,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
-name = "blake2b_simd"
-version = "0.5.11"
+name = "block-buffer"
+version = "0.10.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
+checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
 dependencies = [
- "arrayref",
- "arrayvec",
- "constant_time_eq",
+ "generic-array",
 ]
 
+[[package]]
+name = "bumpalo"
+version = "3.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
+
 [[package]]
 name = "byteorder"
 version = "1.4.3"
@@ -204,6 +223,9 @@ name = "cc"
 version = "1.0.73"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
+dependencies = [
+ "jobserver",
+]
 
 [[package]]
 name = "cfg-if"
@@ -219,17 +241,28 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chrono"
-version = "0.4.19"
+version = "0.4.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
+checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1"
 dependencies = [
- "libc",
+ "iana-time-zone",
+ "js-sys",
  "num-integer",
  "num-traits",
- "time",
+ "time 0.1.44",
+ "wasm-bindgen",
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "cipher"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
+dependencies = [
+ "generic-array",
+]
+
 [[package]]
 name = "clap"
 version = "2.34.0"
@@ -266,6 +299,16 @@ dependencies = [
  "bitflags",
 ]
 
+[[package]]
+name = "codespan-reporting"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
+dependencies = [
+ "termcolor",
+ "unicode-width",
+]
+
 [[package]]
 name = "console"
 version = "0.6.2"
@@ -285,14 +328,13 @@ dependencies = [
 
 [[package]]
 name = "console"
-version = "0.15.0"
+version = "0.15.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31"
+checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c"
 dependencies = [
  "encode_unicode",
+ "lazy_static 1.4.0",
  "libc",
- "once_cell",
- "regex",
  "terminal_size",
  "unicode-width",
  "winapi 0.3.9",
@@ -310,7 +352,7 @@ version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5"
 dependencies = [
- "time",
+ "time 0.1.44",
  "url 1.7.2",
 ]
 
@@ -327,7 +369,7 @@ dependencies = [
  "publicsuffix",
  "serde",
  "serde_json",
- "time",
+ "time 0.1.44",
  "try_from",
  "url 1.7.2",
 ]
@@ -348,6 +390,15 @@ version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
 
+[[package]]
+name = "cpufeatures"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "crc32fast"
 version = "1.3.2"
@@ -407,19 +458,28 @@ dependencies = [
 
 [[package]]
 name = "crossbeam-utils"
-version = "0.8.8"
+version = "0.8.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
+checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
 dependencies = [
  "cfg-if 1.0.0",
- "lazy_static 1.4.0",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
 ]
 
 [[package]]
 name = "curl"
-version = "0.4.43"
+version = "0.4.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d855aeef205b43f65a5001e0997d81f8efca7badad4fad7d897aa7f0d0651f"
+checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22"
 dependencies = [
  "curl-sys",
  "libc",
@@ -432,9 +492,9 @@ dependencies = [
 
 [[package]]
 name = "curl-sys"
-version = "0.4.55+curl-7.83.1"
+version = "0.4.58+curl-7.86.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23734ec77368ec583c2e61dd3f0b0e5c98b93abe6d2a004ca06b91dd7e3e2762"
+checksum = "430e2ecf0c5f4445334472cf8f9611a6eea404b4135ca5500f38a97a128c913e"
 dependencies = [
  "cc",
  "libc",
@@ -445,13 +505,57 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "cxx"
+version = "1.0.80"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b7d4e43b25d3c994662706a1d4fcfc32aaa6afd287502c111b237093bb23f3a"
+dependencies = [
+ "cc",
+ "cxxbridge-flags",
+ "cxxbridge-macro",
+ "link-cplusplus",
+]
+
+[[package]]
+name = "cxx-build"
+version = "1.0.80"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84f8829ddc213e2c1368e51a2564c552b65a8cb6a28f31e576270ac81d5e5827"
+dependencies = [
+ "cc",
+ "codespan-reporting",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "scratch",
+ "syn",
+]
+
+[[package]]
+name = "cxxbridge-flags"
+version = "1.0.80"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e72537424b474af1460806647c41d4b6d35d09ef7fe031c5c2fa5766047cc56a"
+
+[[package]]
+name = "cxxbridge-macro"
+version = "1.0.80"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "dialoguer"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1ad1c29a0368928e78c551354dbff79f103a962ad820519724ef0d74f1c62fa9"
 dependencies = [
- "console 0.15.0",
+ "console 0.15.2",
  "lazy_static 1.4.0",
  "tempfile 2.2.0",
 ]
@@ -463,10 +567,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
 
 [[package]]
-name = "dirs"
-version = "1.0.5"
+name = "digest"
+version = "0.10.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
+checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+ "subtle",
+]
+
+[[package]]
+name = "dirs-next"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
+dependencies = [
+ "cfg-if 1.0.0",
+ "dirs-sys-next",
+]
+
+[[package]]
+name = "dirs-sys-next"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
 dependencies = [
  "libc",
  "redox_users",
@@ -481,9 +606,9 @@ checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
 
 [[package]]
 name = "either"
-version = "1.6.1"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
 
 [[package]]
 name = "encode_unicode"
@@ -548,23 +673,23 @@ dependencies = [
 
 [[package]]
 name = "fastrand"
-version = "1.7.0"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
+checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
 dependencies = [
  "instant",
 ]
 
 [[package]]
 name = "filetime"
-version = "0.2.16"
+version = "0.2.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c"
+checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3"
 dependencies = [
  "cfg-if 1.0.0",
  "libc",
- "redox_syscall 0.2.13",
- "winapi 0.3.9",
+ "redox_syscall 0.2.16",
+ "windows-sys 0.42.0",
 ]
 
 [[package]]
@@ -609,12 +734,21 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
 
 [[package]]
 name = "form_urlencoded"
-version = "1.0.1"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
+checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
 dependencies = [
- "matches",
- "percent-encoding 2.1.0",
+ "percent-encoding 2.2.0",
+]
+
+[[package]]
+name = "fs2"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
+dependencies = [
+ "libc",
+ "winapi 0.3.9",
 ]
 
 [[package]]
@@ -656,32 +790,31 @@ dependencies = [
 ]
 
 [[package]]
-name = "getrandom"
-version = "0.1.16"
+name = "generic-array"
+version = "0.14.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
 dependencies = [
- "cfg-if 1.0.0",
- "libc",
- "wasi 0.9.0+wasi-snapshot-preview1",
+ "typenum",
+ "version_check",
 ]
 
 [[package]]
 name = "getrandom"
-version = "0.2.6"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
+checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
 dependencies = [
  "cfg-if 1.0.0",
  "libc",
- "wasi 0.10.2+wasi-snapshot-preview1",
+ "wasi 0.11.0+wasi-snapshot-preview1",
 ]
 
 [[package]]
 name = "gimli"
-version = "0.26.1"
+version = "0.26.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
+checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
 
 [[package]]
 name = "glob"
@@ -709,9 +842,9 @@ dependencies = [
 
 [[package]]
 name = "hashbrown"
-version = "0.11.2"
+version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
 
 [[package]]
 name = "heck"
@@ -733,9 +866,18 @@ dependencies = [
 
 [[package]]
 name = "hex"
-version = "0.3.2"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "hmac"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+dependencies = [
+ "digest",
+]
 
 [[package]]
 name = "http"
@@ -762,9 +904,9 @@ dependencies = [
 
 [[package]]
 name = "httparse"
-version = "1.7.1"
+version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c"
+checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
 
 [[package]]
 name = "human-panic"
@@ -808,7 +950,7 @@ dependencies = [
  "log",
  "net2",
  "rustc_version",
- "time",
+ "time 0.1.44",
  "tokio",
  "tokio-buf",
  "tokio-executor",
@@ -833,6 +975,30 @@ dependencies = [
  "tokio-io",
 ]
 
+[[package]]
+name = "iana-time-zone"
+version = "0.1.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
+dependencies = [
+ "cxx",
+ "cxx-build",
+]
+
 [[package]]
 name = "idna"
 version = "0.1.5"
@@ -855,11 +1021,21 @@ dependencies = [
  "unicode-normalization",
 ]
 
+[[package]]
+name = "idna"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
 [[package]]
 name = "indexmap"
-version = "1.8.2"
+version = "1.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
+checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
 dependencies = [
  "autocfg 1.1.0",
  "hashbrown",
@@ -900,9 +1076,27 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
 
 [[package]]
 name = "itoa"
-version = "1.0.2"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
+checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
+
+[[package]]
+name = "jobserver"
+version = "0.1.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
 
 [[package]]
 name = "kernel32-sys"
@@ -928,9 +1122,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "libc"
-version = "0.2.126"
+version = "0.2.137"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
+checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
 
 [[package]]
 name = "libz-sys"
@@ -944,6 +1138,15 @@ dependencies = [
  "vcpkg",
 ]
 
+[[package]]
+name = "link-cplusplus"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369"
+dependencies = [
+ "cc",
+]
+
 [[package]]
 name = "lock_api"
 version = "0.1.5"
@@ -965,9 +1168,9 @@ dependencies = [
 
 [[package]]
 name = "lock_api"
-version = "0.4.7"
+version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
+checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
 dependencies = [
  "autocfg 1.1.0",
  "scopeguard 1.1.0",
@@ -1027,9 +1230,9 @@ dependencies = [
 
 [[package]]
 name = "miniz_oxide"
-version = "0.5.3"
+version = "0.5.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
+checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
 dependencies = [
  "adler",
 ]
@@ -1085,9 +1288,9 @@ dependencies = [
 
 [[package]]
 name = "net2"
-version = "0.2.37"
+version = "0.2.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
+checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631"
 dependencies = [
  "cfg-if 0.1.10",
  "libc",
@@ -1129,26 +1332,41 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "num_threads"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "object"
-version = "0.28.4"
+version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
+checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
 dependencies = [
  "memchr",
 ]
 
 [[package]]
 name = "once_cell"
-version = "1.12.0"
+version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
+checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
+
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
 [[package]]
 name = "openssl"
-version = "0.10.40"
+version = "0.10.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e"
+checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13"
 dependencies = [
  "bitflags",
  "cfg-if 1.0.0",
@@ -1178,18 +1396,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
 
 [[package]]
 name = "openssl-src"
-version = "111.20.0+1.1.1o"
+version = "111.22.0+1.1.1q"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92892c4f87d56e376e469ace79f1128fdaded07646ddf73aa0be4706ff712dec"
+checksum = "8f31f0d509d1c1ae9cada2f9539ff8f37933831fd5098879e482aa687d659853"
 dependencies = [
  "cc",
 ]
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.74"
+version = "0.9.77"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "835363342df5fba8354c5b453325b110ffd54044e588c539cf2f20a8014e4cb1"
+checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a"
 dependencies = [
  "autocfg 1.1.0",
  "cc",
@@ -1201,9 +1419,9 @@ dependencies = [
 
 [[package]]
 name = "os_type"
-version = "2.4.0"
+version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3df761f6470298359f84fcfb60d86db02acc22c251c37265c07a3d1057d2389"
+checksum = "e24d44c0eea30167516ed8f6daca4b5e3eebcde1bde1e4e6e08b809fb02c7ba5"
 dependencies = [
  "regex",
 ]
@@ -1244,8 +1462,8 @@ version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
 dependencies = [
- "lock_api 0.4.7",
- "parking_lot_core 0.9.3",
+ "lock_api 0.4.9",
+ "parking_lot_core 0.9.4",
 ]
 
 [[package]]
@@ -1278,15 +1496,38 @@ dependencies = [
 
 [[package]]
 name = "parking_lot_core"
-version = "0.9.3"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
+checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
 dependencies = [
  "cfg-if 1.0.0",
  "libc",
- "redox_syscall 0.2.13",
- "smallvec 1.8.0",
- "windows-sys",
+ "redox_syscall 0.2.16",
+ "smallvec 1.10.0",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "password-hash"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
+dependencies = [
+ "base64ct",
+ "rand_core 0.6.4",
+ "subtle",
+]
+
+[[package]]
+name = "pbkdf2"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
+dependencies = [
+ "digest",
+ "hmac",
+ "password-hash",
+ "sha2",
 ]
 
 [[package]]
@@ -1297,15 +1538,15 @@ checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 
 [[package]]
 name = "percent-encoding"
-version = "2.1.0"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
 
 [[package]]
 name = "pkg-config"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
+checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
 
 [[package]]
 name = "predicates"
@@ -1362,9 +1603,9 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.39"
+version = "1.0.47"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
 dependencies = [
  "unicode-ident",
 ]
@@ -1376,7 +1617,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "95b4ce31ff0a27d93c8de1849cf58162283752f065a90d508f1105fa6c9a213f"
 dependencies = [
  "idna 0.2.3",
- "url 2.2.2",
+ "url 2.3.1",
 ]
 
 [[package]]
@@ -1387,9 +1628,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
 
 [[package]]
 name = "quote"
-version = "1.0.18"
+version = "1.0.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
 dependencies = [
  "proc-macro2",
 ]
@@ -1474,6 +1715,12 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
 
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+
 [[package]]
 name = "rand_hc"
 version = "0.1.0"
@@ -1553,29 +1800,29 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
 
 [[package]]
 name = "redox_syscall"
-version = "0.2.13"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
 dependencies = [
  "bitflags",
 ]
 
 [[package]]
 name = "redox_users"
-version = "0.3.5"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
+checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
 dependencies = [
- "getrandom 0.1.16",
- "redox_syscall 0.1.57",
- "rust-argon2",
+ "getrandom",
+ "redox_syscall 0.2.16",
+ "thiserror",
 ]
 
 [[package]]
 name = "regex"
-version = "1.5.6"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
+checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -1584,9 +1831,9 @@ dependencies = [
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.26"
+version = "0.6.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
+checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
 
 [[package]]
 name = "remove_dir_all"
@@ -1603,7 +1850,7 @@ version = "0.9.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab"
 dependencies = [
- "base64 0.10.1",
+ "base64",
  "bytes",
  "cookie",
  "cookie_store",
@@ -1620,7 +1867,7 @@ dependencies = [
  "serde",
  "serde_json",
  "serde_urlencoded",
- "time",
+ "time 0.1.44",
  "tokio",
  "tokio-executor",
  "tokio-io",
@@ -1631,18 +1878,6 @@ dependencies = [
  "winreg",
 ]
 
-[[package]]
-name = "rust-argon2"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
-dependencies = [
- "base64 0.13.0",
- "blake2b_simd",
- "constant_time_eq",
- "crossbeam-utils 0.8.8",
-]
-
 [[package]]
 name = "rustc-demangle"
 version = "0.1.21"
@@ -1660,9 +1895,9 @@ dependencies = [
 
 [[package]]
 name = "ryu"
-version = "1.0.10"
+version = "1.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
+checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
 
 [[package]]
 name = "same-file"
@@ -1680,7 +1915,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
 dependencies = [
  "lazy_static 1.4.0",
- "windows-sys",
+ "windows-sys 0.36.1",
 ]
 
 [[package]]
@@ -1695,11 +1930,17 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
 
+[[package]]
+name = "scratch"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898"
+
 [[package]]
 name = "security-framework"
-version = "2.6.1"
+version = "2.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc"
+checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c"
 dependencies = [
  "bitflags",
  "core-foundation",
@@ -1736,18 +1977,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 
 [[package]]
 name = "serde"
-version = "1.0.137"
+version = "1.0.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
+checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.137"
+version = "1.0.147"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
+checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1765,11 +2006,11 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.81"
+version = "1.0.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
+checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
 dependencies = [
- "itoa 1.0.2",
+ "itoa 1.0.4",
  "ryu",
  "serde",
 ]
@@ -1808,17 +2049,48 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "sha1"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
+dependencies = [
+ "cfg-if 1.0.0",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
+dependencies = [
+ "cfg-if 1.0.0",
+ "cpufeatures",
+ "digest",
+]
+
 [[package]]
 name = "siphasher"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
 
+[[package]]
+name = "siphasher"
+version = "0.3.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
+
 [[package]]
 name = "slab"
-version = "0.4.6"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
+checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
+dependencies = [
+ "autocfg 1.1.0",
+]
 
 [[package]]
 name = "smallvec"
@@ -1831,15 +2103,15 @@ dependencies = [
 
 [[package]]
 name = "smallvec"
-version = "1.8.0"
+version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
+checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
 
 [[package]]
 name = "socket2"
-version = "0.4.4"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
+checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
 dependencies = [
  "libc",
  "winapi 0.3.9",
@@ -1890,11 +2162,17 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "subtle"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
+
 [[package]]
 name = "syn"
-version = "1.0.96"
+version = "1.0.103"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
+checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1946,7 +2224,7 @@ dependencies = [
  "cfg-if 1.0.0",
  "fastrand",
  "libc",
- "redox_syscall 0.2.13",
+ "redox_syscall 0.2.16",
  "remove_dir_all",
  "winapi 0.3.9",
 ]
@@ -1996,18 +2274,18 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "1.0.31"
+version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
+checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.31"
+version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
+checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2016,14 +2294,44 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.1.43"
+version = "0.1.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
+checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
 dependencies = [
  "libc",
+ "wasi 0.10.0+wasi-snapshot-preview1",
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "time"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fab5c8b9980850e06d92ddbe3ab839c062c801f3927c0fb8abd6fc8e918fbca"
+dependencies = [
+ "itoa 1.0.4",
+ "libc",
+ "num_threads",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
+
+[[package]]
+name = "time-macros"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65bb801831d812c562ae7d2bfb531f26e66e4e1f6b17307ba4149c5064710e5b"
+dependencies = [
+ "time-core",
+]
+
 [[package]]
 name = "tinyvec"
 version = "1.6.0"
@@ -2205,6 +2513,12 @@ dependencies = [
  "cfg-if 0.1.10",
 ]
 
+[[package]]
+name = "typenum"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
+
 [[package]]
 name = "unicase"
 version = "2.6.0"
@@ -2222,36 +2536,36 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.0"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
 
 [[package]]
 name = "unicode-normalization"
-version = "0.1.19"
+version = "0.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
 dependencies = [
  "tinyvec",
 ]
 
 [[package]]
 name = "unicode-segmentation"
-version = "1.9.0"
+version = "1.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
+checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
 
 [[package]]
 name = "unicode-width"
-version = "0.1.9"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
 
 [[package]]
 name = "unicode-xid"
-version = "0.2.3"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
+checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
 
 [[package]]
 name = "url"
@@ -2266,14 +2580,13 @@ dependencies = [
 
 [[package]]
 name = "url"
-version = "2.2.2"
+version = "2.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
+checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
 dependencies = [
  "form_urlencoded",
- "idna 0.2.3",
- "matches",
- "percent-encoding 2.1.0",
+ "idna 0.3.0",
+ "percent-encoding 2.2.0",
 ]
 
 [[package]]
@@ -2291,7 +2604,7 @@ version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
 dependencies = [
- "getrandom 0.2.6",
+ "getrandom",
 ]
 
 [[package]]
@@ -2336,20 +2649,75 @@ dependencies = [
 
 [[package]]
 name = "wasi"
-version = "0.9.0+wasi-snapshot-preview1"
+version = "0.10.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
 
 [[package]]
 name = "wasi"
-version = "0.10.2+wasi-snapshot-preview1"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if 1.0.0",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
 
 [[package]]
 name = "wasm-pack"
 version = "0.10.3"
 dependencies = [
+ "anyhow",
  "assert_cmd",
  "atty",
  "binary-install",
@@ -2359,7 +2727,6 @@ dependencies = [
  "curl",
  "dialoguer",
  "env_logger",
- "failure",
  "glob",
  "human-panic",
  "lazy_static 1.4.0",
@@ -2374,7 +2741,7 @@ dependencies = [
  "serde_ignored",
  "serde_json",
  "serial_test",
- "siphasher",
+ "siphasher 0.2.3",
  "strsim",
  "structopt",
  "tempfile 3.3.0",
@@ -2385,12 +2752,13 @@ dependencies = [
 
 [[package]]
 name = "which"
-version = "2.0.1"
+version = "4.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164"
+checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b"
 dependencies = [
- "failure",
+ "either",
  "libc",
+ "once_cell",
 ]
 
 [[package]]
@@ -2442,43 +2810,100 @@ version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
 dependencies = [
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_msvc",
+ "windows_aarch64_msvc 0.36.1",
+ "windows_i686_gnu 0.36.1",
+ "windows_i686_msvc 0.36.1",
+ "windows_x86_64_gnu 0.36.1",
+ "windows_x86_64_msvc 0.36.1",
 ]
 
+[[package]]
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc 0.42.0",
+ "windows_i686_gnu 0.42.0",
+ "windows_i686_msvc 0.42.0",
+ "windows_x86_64_gnu 0.42.0",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc 0.42.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
+
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
 
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
+
 [[package]]
 name = "windows_i686_gnu"
 version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
 
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
+
 [[package]]
 name = "windows_i686_msvc"
 version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
 
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
+
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
 
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
+
 [[package]]
 name = "windows_x86_64_msvc"
 version = "0.36.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
 
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
+
 [[package]]
 name = "winreg"
 version = "0.6.2"
@@ -2509,14 +2934,49 @@ dependencies = [
 
 [[package]]
 name = "zip"
-version = "0.5.13"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815"
+checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080"
 dependencies = [
+ "aes",
  "byteorder",
  "bzip2",
+ "constant_time_eq",
  "crc32fast",
+ "crossbeam-utils 0.8.12",
  "flate2",
- "thiserror",
- "time",
+ "hmac",
+ "pbkdf2",
+ "sha1",
+ "time 0.3.16",
+ "zstd",
+]
+
+[[package]]
+name = "zstd"
+version = "0.11.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
+dependencies = [
+ "zstd-safe",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "5.0.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
+dependencies = [
+ "libc",
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-sys"
+version = "2.0.1+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b"
+dependencies = [
+ "cc",
+ "libc",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 6fd73cf..cc63749 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,13 +10,13 @@ categories = ["wasm"]
 documentation = "https://rustwasm.github.io/wasm-pack/"
 
 [dependencies]
+anyhow = "1.0.66"
 atty = "0.2.11"
 cargo_metadata = "0.8.0"
 console = "0.6.1"
 dialoguer = "0.3.0"
 curl = "0.4.13"
 env_logger = { version = "0.5.13", default-features = false }
-failure = "0.1.2"
 human-panic = "1.0.1"
 glob = "0.2"
 log = "0.4.6"
@@ -32,8 +32,8 @@ strsim = "0.8.0"
 siphasher = "0.2.3"
 structopt = "0.3"
 toml = "0.4"
-which = "2.0.0"
-binary-install = "0.0.2"
+which = "4.3.0"
+binary-install = { git = "https://github.com/rustwasm/binary-install", rev = "6d60f6731c8294000ea8f3a0260659b025cf7f94" }
 walkdir = "2"
 chrono = "0.4.6"
 
diff --git a/src/bindgen.rs b/src/bindgen.rs
index e9d872c..df97053 100644
--- a/src/bindgen.rs
+++ b/src/bindgen.rs
@@ -1,8 +1,8 @@
 //! Functionality related to running `wasm-bindgen`.
 
+use anyhow::{bail, Context, Result};
 use child;
 use command::build::{BuildProfile, Target};
-use failure::{self, ResultExt};
 use install::{self, Tool};
 use manifest::CrateData;
 use semver;
@@ -19,7 +19,7 @@ pub fn wasm_bindgen_build(
     disable_dts: bool,
     target: Target,
     profile: BuildProfile,
-) -> Result<(), failure::Error> {
+) -> Result<()> {
     let release_or_debug = match profile {
         BuildProfile::Release | BuildProfile::Profiling => "release",
         BuildProfile::Dev => "debug",
@@ -75,7 +75,7 @@ pub fn wasm_bindgen_build(
 }
 
 /// Check if the `wasm-bindgen` dependency is locally satisfied for the web target
-fn supports_web_target(cli_path: &Path) -> Result<bool, failure::Error> {
+fn supports_web_target(cli_path: &Path) -> Result<bool> {
     let cli_version = semver::Version::parse(&install::get_cli_version(
         &install::Tool::WasmBindgen,
         cli_path,
@@ -85,7 +85,7 @@ fn supports_web_target(cli_path: &Path) -> Result<bool, failure::Error> {
 }
 
 /// Check if the `wasm-bindgen` dependency is locally satisfied for the --target flag
-fn supports_dash_dash_target(cli_path: &Path) -> Result<bool, failure::Error> {
+fn supports_dash_dash_target(cli_path: &Path) -> Result<bool> {
     let cli_version = semver::Version::parse(&install::get_cli_version(
         &install::Tool::WasmBindgen,
         cli_path,
@@ -94,7 +94,7 @@ fn supports_dash_dash_target(cli_path: &Path) -> Result<bool, failure::Error> {
     Ok(cli_version >= expected_version)
 }
 
-fn build_target_arg(target: Target, cli_path: &Path) -> Result<String, failure::Error> {
+fn build_target_arg(target: Target, cli_path: &Path) -> Result<String> {
     if !supports_dash_dash_target(cli_path)? {
         Ok(build_target_arg_legacy(target, cli_path)?)
     } else {
@@ -102,7 +102,7 @@ fn build_target_arg(target: Target, cli_path: &Path) -> Result<String, failure::
     }
 }
 
-fn build_target_arg_legacy(target: Target, cli_path: &Path) -> Result<String, failure::Error> {
+fn build_target_arg_legacy(target: Target, cli_path: &Path) -> Result<String> {
     log::info!("Your version of wasm-bindgen is out of date. You should consider updating your Cargo.toml to a version >= 0.2.40.");
     let target_arg = match target {
         Target::Nodejs => "--nodejs",
diff --git a/src/build/mod.rs b/src/build/mod.rs
index c19d12a..a49432e 100644
--- a/src/build/mod.rs
+++ b/src/build/mod.rs
@@ -1,9 +1,9 @@
 //! Building a Rust crate into a `.wasm` binary.
 
+use anyhow::{bail, Context, Result};
 use child;
 use command::build::BuildProfile;
 use emoji;
-use failure::{Error, ResultExt};
 use manifest::Crate;
 use std::path::Path;
 use std::process::Command;
@@ -23,7 +23,7 @@ pub struct WasmPackVersion {
 }
 
 /// Ensure that `rustc` is present and that it is >= 1.30.0
-pub fn check_rustc_version() -> Result<String, Error> {
+pub fn check_rustc_version() -> Result<String> {
     let local_minor_version = rustc_minor_version();
     match local_minor_version {
         Some(mv) => {
@@ -60,7 +60,7 @@ fn rustc_minor_version() -> Option<u32> {
 }
 
 /// Checks and returns local and latest versions of wasm-pack
-pub fn check_wasm_pack_versions() -> Result<WasmPackVersion, Error> {
+pub fn check_wasm_pack_versions() -> Result<WasmPackVersion> {
     match wasm_pack_local_version() {
         Some(local) => Ok(WasmPackVersion {local, latest: Crate::return_wasm_pack_latest_version()?.unwrap_or_else(|| "".to_string())}),
         None => bail!("We can't figure out what your wasm-pack version is, make sure the installation path is correct.")
@@ -77,7 +77,7 @@ pub fn cargo_build_wasm(
     path: &Path,
     profile: BuildProfile,
     extra_options: &[String],
-) -> Result<(), Error> {
+) -> Result<()> {
     let msg = format!("{}Compiling to Wasm...", emoji::CYCLONE);
     PBAR.info(&msg);
 
@@ -125,11 +125,7 @@ pub fn cargo_build_wasm(
 /// * `path`: Path to the crate directory to build tests.
 /// * `debug`: Whether to build tests in `debug` mode.
 /// * `extra_options`: Additional parameters to pass to `cargo` when building tests.
-pub fn cargo_build_wasm_tests(
-    path: &Path,
-    debug: bool,
-    extra_options: &[String],
-) -> Result<(), Error> {
+pub fn cargo_build_wasm_tests(path: &Path, debug: bool, extra_options: &[String]) -> Result<()> {
     let mut cmd = Command::new("cargo");
 
     cmd.current_dir(path).arg("build").arg("--tests");
diff --git a/src/build/wasm_target.rs b/src/build/wasm_target.rs
index f3cdf11..6105470 100644
--- a/src/build/wasm_target.rs
+++ b/src/build/wasm_target.rs
@@ -1,8 +1,8 @@
 //! Checking for the wasm32 target
 
+use anyhow::{anyhow, bail, Context, Result};
 use child;
 use emoji;
-use failure::{Error, ResultExt};
 use log::info;
 use std::fmt;
 use std::path::{Path, PathBuf};
@@ -52,7 +52,7 @@ impl fmt::Display for Wasm32Check {
 
 /// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for
 /// current toolchain
-pub fn check_for_wasm32_target() -> Result<(), Error> {
+pub fn check_for_wasm32_target() -> Result<()> {
     let msg = format!("{}Checking for the Wasm target...", emoji::TARGET);
     PBAR.info(&msg);
 
@@ -65,7 +65,7 @@ pub fn check_for_wasm32_target() -> Result<(), Error> {
 }
 
 /// Get rustc's sysroot as a PathBuf
-fn get_rustc_sysroot() -> Result<PathBuf, Error> {
+fn get_rustc_sysroot() -> Result<PathBuf> {
     let command = Command::new("rustc")
         .args(&["--print", "sysroot"])
         .output()?;
@@ -73,7 +73,7 @@ fn get_rustc_sysroot() -> Result<PathBuf, Error> {
     if command.status.success() {
         Ok(String::from_utf8(command.stdout)?.trim().into())
     } else {
-        Err(format_err!(
+        Err(anyhow!(
             "Getting rustc's sysroot wasn't successful. Got {}",
             command.status
         ))
@@ -97,7 +97,7 @@ fn is_wasm32_target_in_sysroot(sysroot: &Path) -> bool {
     }
 }
 
-fn check_wasm32_target() -> Result<Wasm32Check, Error> {
+fn check_wasm32_target() -> Result<Wasm32Check> {
     let sysroot = get_rustc_sysroot()?;
     let rustc_path = which::which("rustc")?;
 
@@ -132,7 +132,7 @@ fn check_wasm32_target() -> Result<Wasm32Check, Error> {
 }
 
 /// Add wasm32-unknown-unknown using `rustup`.
-fn rustup_add_wasm_target() -> Result<(), Error> {
+fn rustup_add_wasm_target() -> Result<()> {
     let mut cmd = Command::new("rustup");
     cmd.arg("target").arg("add").arg("wasm32-unknown-unknown");
     child::run(cmd, "rustup").context("Adding the wasm32-unknown-unknown target with rustup")?;
diff --git a/src/cache.rs b/src/cache.rs
index 4e3c2d0..cbb07b7 100644
--- a/src/cache.rs
+++ b/src/cache.rs
@@ -1,11 +1,12 @@
 //! Getting and configuring wasm-pack's binary cache.
 
+use anyhow::Result;
 use binary_install::Cache;
 use std::env;
 use std::path::Path;
 
 /// Get wasm-pack's binary cache.
-pub fn get_wasm_pack_cache() -> Result<Cache, failure::Error> {
+pub fn get_wasm_pack_cache() -> Result<Cache> {
     if let Ok(path) = env::var("WASM_PACK_CACHE") {
         Ok(Cache::at(Path::new(&path)))
     } else {
diff --git a/src/child.rs b/src/child.rs
index 9fedc3e..742a186 100644
--- a/src/child.rs
+++ b/src/child.rs
@@ -3,7 +3,7 @@
 //! This module helps us ensure that all child processes that we spawn get
 //! properly logged and their output is logged as well.
 
-use failure::Error;
+use anyhow::{bail, Result};
 use install::Tool;
 use log::info;
 use std::process::{Command, Stdio};
@@ -25,7 +25,7 @@ pub fn new_command(program: &str) -> Command {
 }
 
 /// Run the given command and return on success.
-pub fn run(mut command: Command, command_name: &str) -> Result<(), Error> {
+pub fn run(mut command: Command, command_name: &str) -> Result<()> {
     info!("Running {:?}", command);
 
     let status = command.status()?;
@@ -43,7 +43,7 @@ pub fn run(mut command: Command, command_name: &str) -> Result<(), Error> {
 }
 
 /// Run the given command and return its stdout.
-pub fn run_capture_stdout(mut command: Command, command_name: &Tool) -> Result<String, Error> {
+pub fn run_capture_stdout(mut command: Command, command_name: &Tool) -> Result<String> {
     info!("Running {:?}", command);
 
     let output = command
diff --git a/src/command/build.rs b/src/command/build.rs
index 1f94471..b14b99f 100644
--- a/src/command/build.rs
+++ b/src/command/build.rs
@@ -1,13 +1,13 @@
 //! Implementation of the `wasm-pack build` command.
 
 use crate::wasm_opt;
+use anyhow::{anyhow, bail, Error, Result};
 use binary_install::Cache;
 use bindgen;
 use build;
 use cache;
 use command::utils::{create_pkg_dir, get_crate_path};
 use emoji;
-use failure::Error;
 use install::{self, InstallMode, Tool};
 use license;
 use lockfile::Lockfile;
@@ -81,7 +81,7 @@ impl fmt::Display for Target {
 
 impl FromStr for Target {
     type Err = Error;
-    fn from_str(s: &str) -> Result<Self, Error> {
+    fn from_str(s: &str) -> Result<Self> {
         match s {
             "bundler" | "browser" => Ok(Target::Bundler),
             "web" => Ok(Target::Web),
@@ -185,11 +185,11 @@ impl Default for BuildOptions {
     }
 }
 
-type BuildStep = fn(&mut Build) -> Result<(), Error>;
+type BuildStep = fn(&mut Build) -> Result<()>;
 
 impl Build {
     /// Construct a build command from the given options.
-    pub fn try_from_opts(mut build_opts: BuildOptions) -> Result<Self, Error> {
+    pub fn try_from_opts(mut build_opts: BuildOptions) -> Result<Self> {
         if let Some(path) = &build_opts.path {
             if path.to_string_lossy().starts_with("--") {
                 let path = build_opts.path.take().unwrap();
@@ -234,7 +234,7 @@ impl Build {
     }
 
     /// Execute this `Build` command.
-    pub fn run(&mut self) -> Result<(), Error> {
+    pub fn run(&mut self) -> Result<()> {
         let process_steps = Build::get_process_steps(self.mode);
 
         let started = Instant::now();
@@ -295,7 +295,7 @@ impl Build {
         steps
     }
 
-    fn step_check_rustc_version(&mut self) -> Result<(), Error> {
+    fn step_check_rustc_version(&mut self) -> Result<()> {
         info!("Checking rustc version...");
         let version = build::check_rustc_version()?;
         let msg = format!("rustc version is {}.", version);
@@ -303,21 +303,21 @@ impl Build {
         Ok(())
     }
 
-    fn step_check_crate_config(&mut self) -> Result<(), Error> {
+    fn step_check_crate_config(&mut self) -> Result<()> {
         info!("Checking crate configuration...");
         self.crate_data.check_crate_config()?;
         info!("Crate is correctly configured.");
         Ok(())
     }
 
-    fn step_check_for_wasm_target(&mut self) -> Result<(), Error> {
+    fn step_check_for_wasm_target(&mut self) -> Result<()> {
         info!("Checking for wasm-target...");
         build::wasm_target::check_for_wasm32_target()?;
         info!("Checking for wasm-target was successful.");
         Ok(())
     }
 
-    fn step_build_wasm(&mut self) -> Result<(), Error> {
+    fn step_build_wasm(&mut self) -> Result<()> {
         info!("Building wasm...");
         build::cargo_build_wasm(&self.crate_path, self.profile, &self.extra_options)?;
 
@@ -332,14 +332,14 @@ impl Build {
         Ok(())
     }
 
-    fn step_create_dir(&mut self) -> Result<(), Error> {
+    fn step_create_dir(&mut self) -> Result<()> {
         info!("Creating a pkg directory...");
         create_pkg_dir(&self.out_dir)?;
         info!("Created a pkg directory at {:#?}.", &self.crate_path);
         Ok(())
     }
 
-    fn step_create_json(&mut self) -> Result<(), Error> {
+    fn step_create_json(&mut self) -> Result<()> {
         self.crate_data.write_package_json(
             &self.out_dir,
             &self.scope,
@@ -353,21 +353,21 @@ impl Build {
         Ok(())
     }
 
-    fn step_copy_readme(&mut self) -> Result<(), Error> {
+    fn step_copy_readme(&mut self) -> Result<()> {
         info!("Copying readme from crate...");
         readme::copy_from_crate(&self.crate_path, &self.out_dir)?;
         info!("Copied readme from crate to {:#?}.", &self.out_dir);
         Ok(())
     }
 
-    fn step_copy_license(&mut self) -> Result<(), failure::Error> {
+    fn step_copy_license(&mut self) -> Result<()> {
         info!("Copying license from crate...");
         license::copy_from_crate(&self.crate_data, &self.crate_path, &self.out_dir)?;
         info!("Copied license from crate to {:#?}.", &self.out_dir);
         Ok(())
     }
 
-    fn step_install_wasm_bindgen(&mut self) -> Result<(), failure::Error> {
+    fn step_install_wasm_bindgen(&mut self) -> Result<()> {
         info!("Identifying wasm-bindgen dependency...");
         let lockfile = Lockfile::new(&self.crate_data)?;
         let bindgen_version = lockfile.require_wasm_bindgen()?;
@@ -383,7 +383,7 @@ impl Build {
         Ok(())
     }
 
-    fn step_run_wasm_bindgen(&mut self) -> Result<(), Error> {
+    fn step_run_wasm_bindgen(&mut self) -> Result<()> {
         info!("Building the wasm bindings...");
         bindgen::wasm_bindgen_build(
             &self.crate_data,
@@ -398,7 +398,7 @@ impl Build {
         Ok(())
     }
 
-    fn step_run_wasm_opt(&mut self) -> Result<(), Error> {
+    fn step_run_wasm_opt(&mut self) -> Result<()> {
         let args = match self
             .crate_data
             .configured_profile(self.profile)
@@ -414,7 +414,7 @@ impl Build {
             &args,
             self.mode.install_permitted(),
         ).map_err(|e| {
-            format_err!(
+            anyhow!(
                 "{}\nTo disable `wasm-opt`, add `wasm-opt = false` to your package metadata in your `Cargo.toml`.", e
             )
         })
diff --git a/src/command/generate.rs b/src/command/generate.rs
index 8c793b8..2f72186 100644
--- a/src/command/generate.rs
+++ b/src/command/generate.rs
@@ -1,18 +1,13 @@
+use anyhow::Result;
 use cache;
-use failure::Error;
 use generate;
 use install::{self, Tool};
 use log::info;
-use std::result;
 use PBAR;
 
 /// Executes the 'cargo-generate' command in the current directory
 /// which generates a new rustwasm project from a template.
-pub fn generate(
-    template: String,
-    name: String,
-    install_permitted: bool,
-) -> result::Result<(), Error> {
+pub fn generate(template: String, name: String, install_permitted: bool) -> Result<()> {
     info!("Generating a new rustwasm project...");
     let download = install::download_prebuilt_or_cargo_install(
         Tool::CargoGenerate,
diff --git a/src/command/login.rs b/src/command/login.rs
index 6df51f5..f24156d 100644
--- a/src/command/login.rs
+++ b/src/command/login.rs
@@ -1,6 +1,6 @@
+use anyhow::Result;
 use log::info;
 use npm;
-use std::result;
 use PBAR;
 
 pub fn login(
@@ -8,7 +8,7 @@ pub fn login(
     scope: &Option<String>,
     always_auth: bool,
     auth_type: &Option<String>,
-) -> result::Result<(), failure::Error> {
+) -> Result<()> {
     let registry = registry.unwrap_or_else(|| npm::DEFAULT_NPM_REGISTRY.to_string());
 
     info!("Logging in to npm...");
diff --git a/src/command/mod.rs b/src/command/mod.rs
index 6e1bfa7..86eaf3f 100644
--- a/src/command/mod.rs
+++ b/src/command/mod.rs
@@ -17,10 +17,9 @@ use self::pack::pack;
 use self::publish::{access::Access, publish};
 use self::test::{Test, TestOptions};
 use crate::install::InstallMode;
-use failure::Error;
+use anyhow::Result;
 use log::info;
 use std::path::PathBuf;
-use std::result;
 
 /// The various kinds of commands that `wasm-pack` can execute.
 #[derive(Debug, StructOpt)]
@@ -113,7 +112,7 @@ pub enum Command {
 }
 
 /// Run a command with the given logger!
-pub fn run_wasm_pack(command: Command) -> result::Result<(), Error> {
+pub fn run_wasm_pack(command: Command) -> Result<()> {
     // Run the correct command based off input and store the result of it so that we can clear
     // the progress bar then return it
     match command {
diff --git a/src/command/pack.rs b/src/command/pack.rs
index 18a0315..6b3da04 100644
--- a/src/command/pack.rs
+++ b/src/command/pack.rs
@@ -1,19 +1,18 @@
+use anyhow::{anyhow, Result};
 use command::utils::{find_pkg_directory, get_crate_path};
-use failure::Error;
 use log::info;
 use npm;
 use std::path::PathBuf;
-use std::result;
 use PBAR;
 
 /// Executes the 'npm pack' command on the 'pkg' directory
 /// which creates a tarball that can be published to the NPM registry
-pub fn pack(path: Option<PathBuf>) -> result::Result<(), Error> {
+pub fn pack(path: Option<PathBuf>) -> Result<()> {
     let crate_path = get_crate_path(path)?;
 
     info!("Packing up the npm package...");
     let pkg_directory = find_pkg_directory(&crate_path).ok_or_else(|| {
-        format_err!(
+        anyhow!(
             "Unable to find the pkg directory at path {:#?}, or in a child directory of {:#?}",
             &crate_path,
             &crate_path
diff --git a/src/command/publish/access.rs b/src/command/publish/access.rs
index 6562e96..6b374b4 100644
--- a/src/command/publish/access.rs
+++ b/src/command/publish/access.rs
@@ -1,4 +1,4 @@
-use failure::Error;
+use anyhow::{bail, Error, Result};
 use std::fmt;
 use std::str::FromStr;
 
@@ -14,7 +14,7 @@ pub enum Access {
 impl FromStr for Access {
     type Err = Error;
 
-    fn from_str(s: &str) -> Result<Self, Error> {
+    fn from_str(s: &str) -> Result<Self> {
         match s {
       "public" => Ok(Access::Public),
       "restricted" => Ok(Access::Restricted),
diff --git a/src/command/publish/mod.rs b/src/command/publish/mod.rs
index 64c14c8..7ac495b 100644
--- a/src/command/publish/mod.rs
+++ b/src/command/publish/mod.rs
@@ -2,14 +2,13 @@
 pub mod access;
 
 use self::access::Access;
+use anyhow::{anyhow, bail, Result};
 use command::build::{Build, BuildOptions, Target};
 use command::utils::{find_pkg_directory, get_crate_path};
 use dialoguer::{Confirmation, Input, Select};
-use failure::Error;
 use log::info;
 use npm;
 use std::path::PathBuf;
-use std::result;
 use std::str::FromStr;
 use PBAR;
 
@@ -20,7 +19,7 @@ pub fn publish(
     path: Option<PathBuf>,
     access: Option<Access>,
     tag: Option<String>,
-) -> result::Result<(), Error> {
+) -> Result<()> {
     let crate_path = get_crate_path(path)?;
 
     info!("Publishing the npm package...");
@@ -58,7 +57,7 @@ pub fn publish(
                     .and_then(|mut build| build.run())
                     .map(|()| crate_path.join(out_dir))
                     .map_err(|_| {
-                        format_err!(
+                        anyhow!(
                             "Unable to find the pkg directory at path '{:#?}',\
                              or in a child directory of '{:#?}'",
                             &crate_path,
diff --git a/src/command/test.rs b/src/command/test.rs
index 9c5ab9b..8fc0a85 100644
--- a/src/command/test.rs
+++ b/src/command/test.rs
@@ -1,11 +1,11 @@
 //! Implementation of the `wasm-pack test` command.
 
+use anyhow::{bail, Result};
 use binary_install::Cache;
 use build;
 use cache;
 use command::utils::get_crate_path;
 use console::style;
-use failure::Error;
 use install::{self, InstallMode, Tool};
 use lockfile::Lockfile;
 use log::info;
@@ -108,11 +108,11 @@ pub struct Test {
     extra_options: Vec<String>,
 }
 
-type TestStep = fn(&mut Test) -> Result<(), Error>;
+type TestStep = fn(&mut Test) -> Result<()>;
 
 impl Test {
     /// Construct a test command from the given options.
-    pub fn try_from_opts(test_opts: TestOptions) -> Result<Self, Error> {
+    pub fn try_from_opts(test_opts: TestOptions) -> Result<Self> {
         let TestOptions {
             node,
             mode,
@@ -181,7 +181,7 @@ impl Test {
     }
 
     /// Execute this test command.
-    pub fn run(mut self) -> Result<(), Error> {
+    pub fn run(mut self) -> Result<()> {
         let process_steps = self.get_process_steps();
 
         let started = Instant::now();
@@ -249,21 +249,21 @@ impl Test {
         }
     }
 
-    fn step_check_rustc_version(&mut self) -> Result<(), Error> {
+    fn step_check_rustc_version(&mut self) -> Result<()> {
         info!("Checking rustc version...");
         let _ = build::check_rustc_version()?;
         info!("Rustc version is correct.");
         Ok(())
     }
 
-    fn step_check_for_wasm_target(&mut self) -> Result<(), Error> {
+    fn step_check_for_wasm_target(&mut self) -> Result<()> {
         info!("Adding wasm-target...");
         build::wasm_target::check_for_wasm32_target()?;
         info!("Adding wasm-target was successful.");
         Ok(())
     }
 
-    fn step_build_tests(&mut self) -> Result<(), Error> {
+    fn step_build_tests(&mut self) -> Result<()> {
         info!("Compiling tests to wasm...");
 
         // If the user has run `wasm-pack test -- --features "f1" -- test_name`, then we want to only pass through
@@ -280,7 +280,7 @@ impl Test {
         Ok(())
     }
 
-    fn step_install_wasm_bindgen(&mut self) -> Result<(), Error> {
+    fn step_install_wasm_bindgen(&mut self) -> Result<()> {
         info!("Identifying wasm-bindgen dependency...");
         let lockfile = Lockfile::new(&self.crate_data)?;
         let bindgen_version = lockfile.require_wasm_bindgen()?;
@@ -315,7 +315,7 @@ impl Test {
         Ok(())
     }
 
-    fn step_test_node(&mut self) -> Result<(), Error> {
+    fn step_test_node(&mut self) -> Result<()> {
         assert!(self.node);
         info!("Running tests in node...");
         test::cargo_test_wasm(
@@ -334,7 +334,7 @@ impl Test {
         Ok(())
     }
 
-    fn step_get_chromedriver(&mut self) -> Result<(), Error> {
+    fn step_get_chromedriver(&mut self) -> Result<()> {
         assert!(self.chrome && self.chromedriver.is_none());
 
         self.chromedriver = Some(webdriver::get_or_install_chromedriver(
@@ -344,7 +344,7 @@ impl Test {
         Ok(())
     }
 
-    fn step_test_chrome(&mut self) -> Result<(), Error> {
+    fn step_test_chrome(&mut self) -> Result<()> {
         let chromedriver = self.chromedriver.as_ref().unwrap().display().to_string();
         let chromedriver = chromedriver.as_str();
         info!(
@@ -359,7 +359,7 @@ impl Test {
         Ok(())
     }
 
-    fn step_get_geckodriver(&mut self) -> Result<(), Error> {
+    fn step_get_geckodriver(&mut self) -> Result<()> {
         assert!(self.firefox && self.geckodriver.is_none());
 
         self.geckodriver = Some(webdriver::get_or_install_geckodriver(
@@ -369,7 +369,7 @@ impl Test {
         Ok(())
     }
 
-    fn step_test_firefox(&mut self) -> Result<(), Error> {
+    fn step_test_firefox(&mut self) -> Result<()> {
         let geckodriver = self.geckodriver.as_ref().unwrap().display().to_string();
         let geckodriver = geckodriver.as_str();
         info!(
@@ -384,14 +384,14 @@ impl Test {
         Ok(())
     }
 
-    fn step_get_safaridriver(&mut self) -> Result<(), Error> {
+    fn step_get_safaridriver(&mut self) -> Result<()> {
         assert!(self.safari && self.safaridriver.is_none());
 
         self.safaridriver = Some(webdriver::get_safaridriver()?);
         Ok(())
     }
 
-    fn step_test_safari(&mut self) -> Result<(), Error> {
+    fn step_test_safari(&mut self) -> Result<()> {
         let safaridriver = self.safaridriver.as_ref().unwrap().display().to_string();
         let safaridriver = safaridriver.as_str();
         info!(
diff --git a/src/command/utils.rs b/src/command/utils.rs
index 0158abf..152dd99 100644
--- a/src/command/utils.rs
+++ b/src/command/utils.rs
@@ -1,7 +1,7 @@
 //! Utility functions for commands.
 #![allow(clippy::redundant_closure)]
 
-use failure;
+use anyhow::Result;
 use std::fs;
 use std::path::{Path, PathBuf};
 use std::time::Duration;
@@ -9,7 +9,7 @@ use walkdir::WalkDir;
 
 /// If an explicit path is given, then use it, otherwise assume the current
 /// directory is the crate path.
-pub fn get_crate_path(path: Option<PathBuf>) -> Result<PathBuf, failure::Error> {
+pub fn get_crate_path(path: Option<PathBuf>) -> Result<PathBuf> {
     match path {
         Some(p) => Ok(p),
         None => find_manifest_from_cwd(),
@@ -19,7 +19,7 @@ pub fn get_crate_path(path: Option<PathBuf>) -> Result<PathBuf, failure::Error>
 /// Search up the path for the manifest file from the current working directory
 /// If we don't find the manifest file then return back the current working directory
 /// to provide the appropriate error
-fn find_manifest_from_cwd() -> Result<PathBuf, failure::Error> {
+fn find_manifest_from_cwd() -> Result<PathBuf> {
     let mut parent_path = std::env::current_dir()?;
     let mut manifest_path = parent_path.join("Cargo.toml");
     loop {
@@ -36,7 +36,7 @@ fn find_manifest_from_cwd() -> Result<PathBuf, failure::Error> {
 }
 
 /// Construct our `pkg` directory in the crate.
-pub fn create_pkg_dir(out_dir: &Path) -> Result<(), failure::Error> {
+pub fn create_pkg_dir(out_dir: &Path) -> Result<()> {
     let _ = fs::remove_file(out_dir.join("package.json")); // Clean up package.json from previous runs
     fs::create_dir_all(&out_dir)?;
     fs::write(out_dir.join(".gitignore"), "*")?;
diff --git a/src/generate.rs b/src/generate.rs
index 5a385f2..552618f 100644
--- a/src/generate.rs
+++ b/src/generate.rs
@@ -1,18 +1,14 @@
 //! Functionality related to running `cargo-generate`.
 
+use anyhow::{Context, Result};
 use child;
 use emoji;
-use failure::{self, ResultExt};
 use install::{self, Tool};
 use std::process::Command;
 
 /// Run `cargo generate` in the current directory to create a new
 /// project from a template
-pub fn generate(
-    template: &str,
-    name: &str,
-    install_status: &install::Status,
-) -> Result<(), failure::Error> {
+pub fn generate(template: &str, name: &str, install_status: &install::Status) -> Result<()> {
     let bin_path = install::get_tool_path(install_status, Tool::CargoGenerate)?
         .binary(&Tool::CargoGenerate.to_string())?;
     let mut cmd = Command::new(&bin_path);
diff --git a/src/install/arch.rs b/src/install/arch.rs
index 63516fa..b8c1f68 100644
--- a/src/install/arch.rs
+++ b/src/install/arch.rs
@@ -1,3 +1,4 @@
+use anyhow::{bail, Result};
 use std::fmt;
 
 use crate::target;
@@ -15,7 +16,7 @@ pub enum Arch {
 
 impl Arch {
     /// Gets the current architecture
-    pub fn get() -> Result<Self, failure::Error> {
+    pub fn get() -> Result<Self> {
         if target::x86_64 {
             Ok(Arch::X86_64)
         } else if target::x86 {
diff --git a/src/install/krate.rs b/src/install/krate.rs
index 4a76530..6f9c62f 100644
--- a/src/install/krate.rs
+++ b/src/install/krate.rs
@@ -1,3 +1,4 @@
+use anyhow::Result;
 use install::Tool;
 use serde::Deserialize;
 
@@ -13,7 +14,7 @@ pub struct KrateResponse {
 }
 
 impl Krate {
-    pub fn new(name: &Tool) -> Result<Krate, failure::Error> {
+    pub fn new(name: &Tool) -> Result<Krate> {
         let krate_address = format!("https://crates.io/api/v1/crates/{}", name);
         let client = reqwest::Client::new();
         let mut res = client.get(&krate_address).send()?;
diff --git a/src/install/mod.rs b/src/install/mod.rs
index 612c6da..8215b37 100644
--- a/src/install/mod.rs
+++ b/src/install/mod.rs
@@ -1,10 +1,10 @@
 //! Functionality related to installing prebuilt binaries and/or running cargo install.
 
 use self::krate::Krate;
+use anyhow::{anyhow, bail, Context, Result};
 use binary_install::{Cache, Download};
 use child;
 use emoji;
-use failure::{self, ResultExt};
 use install;
 use log::debug;
 use log::{info, warn};
@@ -36,7 +36,7 @@ pub enum Status {
 }
 
 /// Handles possible installs status and returns the download or a error message
-pub fn get_tool_path(status: &Status, tool: Tool) -> Result<&Download, failure::Error> {
+pub fn get_tool_path(status: &Status, tool: Tool) -> Result<&Download> {
     match status {
         Status::Found(download) => Ok(download),
         Status::CannotInstall => bail!("Not able to find or install a local {}.", tool),
@@ -57,7 +57,7 @@ pub fn download_prebuilt_or_cargo_install(
     cache: &Cache,
     version: &str,
     install_permitted: bool,
-) -> Result<Status, failure::Error> {
+) -> Result<Status> {
     // If the tool is installed globally and it has the right version, use
     // that. Assume that other tools are installed next to it.
     //
@@ -89,11 +89,7 @@ pub fn download_prebuilt_or_cargo_install(
 }
 
 /// Check if the tool dependency is locally satisfied.
-pub fn check_version(
-    tool: &Tool,
-    path: &Path,
-    expected_version: &str,
-) -> Result<bool, failure::Error> {
+pub fn check_version(tool: &Tool, path: &Path, expected_version: &str) -> Result<bool> {
     let expected_version = if expected_version == "latest" {
         let krate = Krate::new(tool)?;
         krate.max_version
@@ -110,7 +106,7 @@ pub fn check_version(
 }
 
 /// Fetches the version of a CLI tool
-pub fn get_cli_version(tool: &Tool, path: &Path) -> Result<String, failure::Error> {
+pub fn get_cli_version(tool: &Tool, path: &Path) -> Result<String> {
     let mut cmd = Command::new(path);
     cmd.arg("--version");
     let stdout = child::run_capture_stdout(cmd, tool)?;
@@ -127,7 +123,7 @@ pub fn download_prebuilt(
     cache: &Cache,
     version: &str,
     install_permitted: bool,
-) -> Result<Status, failure::Error> {
+) -> Result<Status> {
     let url = match prebuilt_url(tool, version) {
         Ok(url) => url,
         Err(e) => bail!(
@@ -164,19 +160,14 @@ pub fn download_prebuilt(
 
 /// Returns the URL of a precompiled version of wasm-bindgen, if we have one
 /// available for our host platform.
-fn prebuilt_url(tool: &Tool, version: &str) -> Result<String, failure::Error> {
+fn prebuilt_url(tool: &Tool, version: &str) -> Result<String> {
     let os = Os::get()?;
     let arch = Arch::get()?;
     prebuilt_url_for(tool, version, &arch, &os)
 }
 
 /// Get the download URL for some tool at some version, architecture and operating system
-pub fn prebuilt_url_for(
-    tool: &Tool,
-    version: &str,
-    arch: &Arch,
-    os: &Os,
-) -> Result<String, failure::Error> {
+pub fn prebuilt_url_for(tool: &Tool, version: &str, arch: &Arch, os: &Os) -> Result<String> {
     let target = match (os, arch, tool) {
         (Os::Linux, Arch::X86_64, Tool::WasmOpt) => "x86_64-linux",
         (Os::Linux, Arch::X86_64, _) => "x86_64-unknown-linux-musl",
@@ -220,7 +211,7 @@ pub fn cargo_install(
     cache: &Cache,
     version: &str,
     install_permitted: bool,
-) -> Result<Status, failure::Error> {
+) -> Result<Status> {
     debug!(
         "Attempting to use a `cargo install`ed version of `{}={}`",
         tool, version,
@@ -275,7 +266,7 @@ pub fn cargo_install(
     // just want them in `$root/*` directly (which matches how the tarballs are
     // laid out, and where the rest of our code expects them to be). So we do a
     // little renaming here.
-    let binaries: Result<Vec<&str>, failure::Error> = match tool {
+    let binaries: Result<Vec<&str>> = match tool {
         Tool::WasmBindgen => Ok(vec!["wasm-bindgen", "wasm-bindgen-test-runner"]),
         Tool::CargoGenerate => Ok(vec!["cargo-generate"]),
         Tool::WasmOpt => bail!("Cannot install wasm-opt with cargo."),
@@ -287,8 +278,8 @@ pub fn cargo_install(
             .join(b)
             .with_extension(env::consts::EXE_EXTENSION);
         let to = tmp.join(from.file_name().unwrap());
-        fs::rename(&from, &to).with_context(|_| {
-            format!(
+        fs::rename(&from, &to).with_context(|| {
+            anyhow!(
                 "failed to move {} to {} for `cargo install`ed `{}`",
                 from.display(),
                 to.display(),
diff --git a/src/install/mode.rs b/src/install/mode.rs
index ae548e2..a55153d 100644
--- a/src/install/mode.rs
+++ b/src/install/mode.rs
@@ -1,3 +1,4 @@
+use anyhow::{bail, Error, Result};
 use std::str::FromStr;
 
 /// The `InstallMode` determines which mode of initialization we are running, and
@@ -20,8 +21,8 @@ impl Default for InstallMode {
 }
 
 impl FromStr for InstallMode {
-    type Err = failure::Error;
-    fn from_str(s: &str) -> Result<Self, failure::Error> {
+    type Err = Error;
+    fn from_str(s: &str) -> Result<Self> {
         match s {
             "no-install" => Ok(InstallMode::Noinstall),
             "normal" => Ok(InstallMode::Normal),
diff --git a/src/install/os.rs b/src/install/os.rs
index 7d31b35..b5ef640 100644
--- a/src/install/os.rs
+++ b/src/install/os.rs
@@ -1,3 +1,4 @@
+use anyhow::{bail, Result};
 use std::fmt;
 
 use crate::target;
@@ -15,7 +16,7 @@ pub enum Os {
 
 impl Os {
     /// Get the current operating system
-    pub fn get() -> Result<Self, failure::Error> {
+    pub fn get() -> Result<Self> {
         if target::LINUX {
             Ok(Os::Linux)
         } else if target::MACOS {
diff --git a/src/installer.rs b/src/installer.rs
index 47e64ec..67f2b6b 100644
--- a/src/installer.rs
+++ b/src/installer.rs
@@ -22,14 +22,14 @@ use std::io;
 use std::path::Path;
 use std::process;
 
+use anyhow::{anyhow, bail, Context, Result};
 use atty;
-use failure::{self, ResultExt};
 use which;
 
 pub fn install() -> ! {
     if let Err(e) = do_install() {
         eprintln!("{}", e);
-        for cause in e.iter_causes() {
+        for cause in e.chain() {
             eprintln!("Caused by: {}", cause);
         }
     }
@@ -47,7 +47,7 @@ pub fn install() -> ! {
     process::exit(0);
 }
 
-fn do_install() -> Result<(), failure::Error> {
+fn do_install() -> Result<()> {
     // Find `rustup.exe` in PATH, we'll be using its installation directory as
     // our installation directory.
     let rustup = match which::which("rustup") {
@@ -74,7 +74,7 @@ fn do_install() -> Result<(), failure::Error> {
     // Our relatively simple install step!
     let me = env::current_exe()?;
     fs::copy(&me, &destination)
-        .with_context(|_| format!("failed to copy executable to `{}`", destination.display()))?;
+        .with_context(|| anyhow!("failed to copy executable to `{}`", destination.display()))?;
     println!(
         "info: successfully installed wasm-pack to `{}`",
         destination.display()
@@ -85,7 +85,7 @@ fn do_install() -> Result<(), failure::Error> {
     Ok(())
 }
 
-fn confirm_can_overwrite(dst: &Path) -> Result<(), failure::Error> {
+fn confirm_can_overwrite(dst: &Path) -> Result<()> {
     // If the `-f` argument was passed, we can always overwrite everything.
     if env::args().any(|arg| arg == "-f") {
         return Ok(());
@@ -112,7 +112,7 @@ fn confirm_can_overwrite(dst: &Path) -> Result<(), failure::Error> {
     let mut line = String::new();
     io::stdin()
         .read_line(&mut line)
-        .with_context(|_| "failed to read stdin")?;
+        .context("failed to read stdin")?;
 
     if line.starts_with('y') || line.starts_with('Y') {
         return Ok(());
diff --git a/src/lib.rs b/src/lib.rs
index 3efc15f..db0ecf8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,15 +2,14 @@
 
 #![deny(missing_docs)]
 
+extern crate anyhow;
 extern crate cargo_metadata;
 extern crate console;
-extern crate strsim;
-#[macro_use]
-extern crate failure;
 extern crate glob;
 extern crate parking_lot;
 extern crate semver;
 extern crate serde;
+extern crate strsim;
 extern crate which;
 #[macro_use]
 extern crate serde_derive;
diff --git a/src/license.rs b/src/license.rs
index 4297344..c804853 100644
--- a/src/license.rs
+++ b/src/license.rs
@@ -1,6 +1,6 @@
 //! Copy `LICENSE` file(s) for the packaged wasm.
 
-use failure;
+use anyhow::{anyhow, Result};
 use std::fs;
 use std::path::Path;
 
@@ -8,14 +8,12 @@ use glob::glob;
 use manifest::CrateData;
 use PBAR;
 
-fn glob_license_files(path: &Path) -> Result<Vec<String>, failure::Error> {
+fn glob_license_files(path: &Path) -> Result<Vec<String>> {
     let mut license_files: Vec<String> = Vec::new();
     let path_string = match path.join("LICENSE*").to_str() {
         Some(path_string) => path_string.to_owned(),
         None => {
-            return Err(format_err!(
-                "Could not convert joined license path to String"
-            ));
+            return Err(anyhow!("Could not convert joined license path to String"));
         }
     };
 
@@ -24,11 +22,11 @@ fn glob_license_files(path: &Path) -> Result<Vec<String>, failure::Error> {
             Ok(globed_path) => {
                 let file_name = match globed_path.file_name() {
                     Some(file_name) => file_name,
-                    None => return Err(format_err!("Could not get file name from path")),
+                    None => return Err(anyhow!("Could not get file name from path")),
                 };
                 let file_name_string = match file_name.to_str() {
                     Some(file_name_string) => file_name_string.to_owned(),
-                    None => return Err(format_err!("Could not convert filename to String")),
+                    None => return Err(anyhow!("Could not convert filename to String")),
                 };
                 license_files.push(file_name_string);
             }
@@ -39,11 +37,7 @@ fn glob_license_files(path: &Path) -> Result<Vec<String>, failure::Error> {
 }
 
 /// Copy the crate's license into the `pkg` directory.
-pub fn copy_from_crate(
-    crate_data: &CrateData,
-    path: &Path,
-    out_dir: &Path,
-) -> Result<(), failure::Error> {
+pub fn copy_from_crate(crate_data: &CrateData, path: &Path, out_dir: &Path) -> Result<()> {
     assert!(
         fs::metadata(path).ok().map_or(false, |m| m.is_dir()),
         "crate directory should exist"
diff --git a/src/lockfile.rs b/src/lockfile.rs
index 3edd6cf..18ab37e 100644
--- a/src/lockfile.rs
+++ b/src/lockfile.rs
@@ -5,8 +5,8 @@
 use std::fs;
 use std::path::PathBuf;
 
+use anyhow::{anyhow, bail, Context, Result};
 use console::style;
-use failure::{Error, ResultExt};
 use manifest::CrateData;
 use toml;
 
@@ -25,12 +25,12 @@ struct Package {
 
 impl Lockfile {
     /// Read the `Cargo.lock` file for the crate at the given path.
-    pub fn new(crate_data: &CrateData) -> Result<Lockfile, Error> {
+    pub fn new(crate_data: &CrateData) -> Result<Lockfile> {
         let lock_path = get_lockfile_path(crate_data)?;
         let lockfile = fs::read_to_string(&lock_path)
-            .with_context(|_| format!("failed to read: {}", lock_path.display()))?;
+            .with_context(|| anyhow!("failed to read: {}", lock_path.display()))?;
         let lockfile = toml::from_str(&lockfile)
-            .with_context(|_| format!("failed to parse: {}", lock_path.display()))?;
+            .with_context(|| anyhow!("failed to parse: {}", lock_path.display()))?;
         Ok(lockfile)
     }
 
@@ -41,9 +41,9 @@ impl Lockfile {
 
     /// Like `wasm_bindgen_version`, except it returns an error instead of
     /// `None`.
-    pub fn require_wasm_bindgen(&self) -> Result<&str, Error> {
+    pub fn require_wasm_bindgen(&self) -> Result<&str> {
         self.wasm_bindgen_version().ok_or_else(|| {
-            format_err!(
+            anyhow!(
                 "Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
                  [dependencies]\n\
                  wasm-bindgen = \"0.2\"",
@@ -67,7 +67,7 @@ impl Lockfile {
 
 /// Given the path to the crate that we are buliding, return a `PathBuf`
 /// containing the location of the lock file, by finding the workspace root.
-fn get_lockfile_path(crate_data: &CrateData) -> Result<PathBuf, Error> {
+fn get_lockfile_path(crate_data: &CrateData) -> Result<PathBuf> {
     // Check that a lock file can be found in the directory. Return an error
     // if it cannot, otherwise return the path buffer.
     let lockfile_path = crate_data.workspace_root().join("Cargo.lock");
diff --git a/src/main.rs b/src/main.rs
index 8f313d8..c77f845 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,15 +1,15 @@
 #![allow(clippy::redundant_closure, clippy::redundant_pattern_matching)]
 
+extern crate anyhow;
 extern crate atty;
 extern crate env_logger;
-#[macro_use]
-extern crate failure;
 extern crate human_panic;
 extern crate log;
 extern crate structopt;
 extern crate wasm_pack;
 extern crate which;
 
+use anyhow::Result;
 use std::env;
 use std::panic;
 use std::sync::mpsc;
@@ -23,7 +23,7 @@ use wasm_pack::{
 
 mod installer;
 
-fn background_check_for_updates() -> mpsc::Receiver<Result<WasmPackVersion, failure::Error>> {
+fn background_check_for_updates() -> mpsc::Receiver<Result<WasmPackVersion>> {
     let (sender, receiver) = mpsc::channel();
 
     let _detached_thread = thread::spawn(move || {
@@ -51,14 +51,14 @@ fn main() {
 
     if let Err(e) = run() {
         eprintln!("Error: {}", e);
-        for cause in e.iter_causes() {
+        for cause in e.chain() {
             eprintln!("Caused by: {}", cause);
         }
         ::std::process::exit(1);
     }
 }
 
-fn run() -> Result<(), failure::Error> {
+fn run() -> Result<()> {
     let wasm_pack_version = background_check_for_updates();
 
     // Deprecate `init`
diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs
index 6a48352..4da1f31 100644
--- a/src/manifest/mod.rs
+++ b/src/manifest/mod.rs
@@ -6,6 +6,7 @@
     clippy::redundant_closure
 )]
 
+use anyhow::{anyhow, bail, Context, Result};
 mod npm;
 
 use std::path::Path;
@@ -19,7 +20,6 @@ use chrono::offset;
 use chrono::DateTime;
 use command::build::{BuildProfile, Target};
 use curl::easy;
-use failure::{Error, ResultExt};
 use serde::{self, Deserialize};
 use serde_json;
 use std::collections::BTreeSet;
@@ -149,7 +149,7 @@ struct CrateInformation {
 
 impl Crate {
     /// Returns latest wasm-pack version
-    pub fn return_wasm_pack_latest_version() -> Result<Option<String>, failure::Error> {
+    pub fn return_wasm_pack_latest_version() -> Result<Option<String>> {
         let current_time = chrono::offset::Local::now();
         let old_metadata_file = Self::return_wasm_pack_file();
 
@@ -172,9 +172,7 @@ impl Crate {
         }
     }
 
-    fn return_api_call_result(
-        current_time: DateTime<offset::Local>,
-    ) -> Result<String, failure::Error> {
+    fn return_api_call_result(current_time: DateTime<offset::Local>) -> Result<String> {
         let version = Self::return_latest_wasm_pack_version();
 
         // We always override the stamp file with the current time because we don't
@@ -192,7 +190,7 @@ impl Crate {
     fn override_stamp_file(
         current_time: DateTime<offset::Local>,
         version: Option<&str>,
-    ) -> Result<(), failure::Error> {
+    ) -> Result<()> {
         let path = env::current_exe()?;
 
         let mut file = fs::OpenOptions::new()
@@ -224,7 +222,7 @@ impl Crate {
     }
 
     /// Returns wasm-pack latest version (if it's received) by executing check_wasm_pack_latest_version function.
-    fn return_latest_wasm_pack_version() -> Result<String, failure::Error> {
+    fn return_latest_wasm_pack_version() -> Result<String> {
         Self::check_wasm_pack_latest_version().map(|crt| crt.crt.max_version)
     }
 
@@ -239,7 +237,7 @@ impl Crate {
     }
 
     /// Call to the crates.io api and return the latest version of `wasm-pack`
-    fn check_wasm_pack_latest_version() -> Result<Crate, Error> {
+    fn check_wasm_pack_latest_version() -> Result<Crate> {
         let url = "https://crates.io/api/v1/crates/wasm-pack";
 
         let mut easy = easy::Easy2::new(Collector(Vec::new()));
@@ -403,7 +401,7 @@ pub struct ManifestAndUnsedKeys {
 impl CrateData {
     /// Reads all metadata for the crate whose manifest is inside the directory
     /// specified by `path`.
-    pub fn new(crate_path: &Path, out_name: Option<String>) -> Result<CrateData, Error> {
+    pub fn new(crate_path: &Path, out_name: Option<String>) -> Result<CrateData> {
         let manifest_path = crate_path.join("Cargo.toml");
         if !manifest_path.is_file() {
             bail!(
@@ -428,7 +426,7 @@ impl CrateData {
                 pkg.name == manifest.package.name
                     && CrateData::is_same_path(&pkg.manifest_path, &manifest_path)
             })
-            .ok_or_else(|| format_err!("failed to find package in metadata"))?;
+            .ok_or_else(|| anyhow!("failed to find package in metadata"))?;
 
         Ok(CrateData {
             data,
@@ -454,9 +452,9 @@ impl CrateData {
     /// # Errors
     /// Will return Err if the file (manifest_path) couldn't be read or
     /// if deserialize to `CargoManifest` fails.
-    pub fn parse_crate_data(manifest_path: &Path) -> Result<ManifestAndUnsedKeys, Error> {
+    pub fn parse_crate_data(manifest_path: &Path) -> Result<ManifestAndUnsedKeys> {
         let manifest = fs::read_to_string(&manifest_path)
-            .with_context(|_| format!("failed to read: {}", manifest_path.display()))?;
+            .with_context(|| anyhow!("failed to read: {}", manifest_path.display()))?;
         let manifest = &mut toml::Deserializer::new(&manifest);
 
         let mut unused_keys = BTreeSet::new();
@@ -472,7 +470,7 @@ impl CrateData {
                 unused_keys.insert(path_string);
             }
         })
-        .with_context(|_| format!("failed to parse manifest: {}", manifest_path.display()))?;
+        .with_context(|| anyhow!("failed to parse manifest: {}", manifest_path.display()))?;
 
         Ok(ManifestAndUnsedKeys {
             manifest,
@@ -501,12 +499,12 @@ impl CrateData {
     }
 
     /// Check that the crate the given path is properly configured.
-    pub fn check_crate_config(&self) -> Result<(), Error> {
+    pub fn check_crate_config(&self) -> Result<()> {
         self.check_crate_type()?;
         Ok(())
     }
 
-    fn check_crate_type(&self) -> Result<(), Error> {
+    fn check_crate_type(&self) -> Result<()> {
         let pkg = &self.data.packages[self.current_idx];
         let any_cdylib = pkg
             .targets
@@ -573,7 +571,7 @@ impl CrateData {
         scope: &Option<String>,
         disable_dts: bool,
         target: Target,
-    ) -> Result<(), Error> {
+    ) -> Result<()> {
         let pkg_file_path = out_dir.join("package.json");
         // Check if a `package.json` was already generated by wasm-bindgen, if so
         // we merge the NPM dependencies already specified in it.
@@ -597,7 +595,7 @@ impl CrateData {
         let npm_json = serde_json::to_string_pretty(&npm_data)?;
 
         fs::write(&pkg_file_path, npm_json)
-            .with_context(|_| format!("failed to write: {}", pkg_file_path.display()))?;
+            .with_context(|| anyhow!("failed to write: {}", pkg_file_path.display()))?;
         Ok(())
     }
 
diff --git a/src/npm.rs b/src/npm.rs
index 015b416..48a768f 100644
--- a/src/npm.rs
+++ b/src/npm.rs
@@ -1,15 +1,15 @@
 //! Functionality related to publishing to npm.
 
+use anyhow::{bail, Context, Result};
 use child;
 use command::publish::access::Access;
-use failure::{self, ResultExt};
 use log::info;
 
 /// The default npm registry used when we aren't working with a custom registry.
 pub const DEFAULT_NPM_REGISTRY: &str = "https://registry.npmjs.org/";
 
 /// Run the `npm pack` command.
-pub fn npm_pack(path: &str) -> Result<(), failure::Error> {
+pub fn npm_pack(path: &str) -> Result<()> {
     let mut cmd = child::new_command("npm");
     cmd.current_dir(path).arg("pack");
     child::run(cmd, "npm pack").context("Packaging up your code failed")?;
@@ -17,11 +17,7 @@ pub fn npm_pack(path: &str) -> Result<(), failure::Error> {
 }
 
 /// Run the `npm publish` command.
-pub fn npm_publish(
-    path: &str,
-    access: Option<Access>,
-    tag: Option<String>,
-) -> Result<(), failure::Error> {
+pub fn npm_publish(path: &str, access: Option<Access>, tag: Option<String>) -> Result<()> {
     let mut cmd = child::new_command("npm");
     match access {
         Some(a) => cmd.current_dir(path).arg("publish").arg(&a.to_string()),
@@ -41,7 +37,7 @@ pub fn npm_login(
     scope: &Option<String>,
     always_auth: bool,
     auth_type: &Option<String>,
-) -> Result<(), failure::Error> {
+) -> Result<()> {
     let mut args = vec!["login".to_string(), format!("--registry={}", registry)];
 
     if let Some(scope) = scope {
diff --git a/src/progressbar.rs b/src/progressbar.rs
index 1fa2590..c4a96e4 100644
--- a/src/progressbar.rs
+++ b/src/progressbar.rs
@@ -1,5 +1,6 @@
 //! Fancy progress bar functionality.
 
+use anyhow::{bail, Error, Result};
 use console::style;
 use emoji;
 use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
@@ -19,8 +20,8 @@ pub enum LogLevel {
 }
 
 impl std::str::FromStr for LogLevel {
-    type Err = failure::Error;
-    fn from_str(s: &str) -> Result<Self, failure::Error> {
+    type Err = Error;
+    fn from_str(s: &str) -> Result<Self> {
         match s {
             "error" => Ok(LogLevel::Error),
             "warn" => Ok(LogLevel::Warn),
diff --git a/src/readme.rs b/src/readme.rs
index 6e1c57f..b8d5e8e 100644
--- a/src/readme.rs
+++ b/src/readme.rs
@@ -1,13 +1,13 @@
 //! Generating `README` files for the packaged wasm.
 
-use failure::{self, ResultExt};
+use anyhow::{Context, Result};
 use std::fs;
 use std::path::Path;
 
 use PBAR;
 
 /// Copy the crate's README into the `pkg` directory.
-pub fn copy_from_crate(path: &Path, out_dir: &Path) -> Result<(), failure::Error> {
+pub fn copy_from_crate(path: &Path, out_dir: &Path) -> Result<()> {
     assert!(
         fs::metadata(path).ok().map_or(false, |m| m.is_dir()),
         "crate directory should exist"
diff --git a/src/stamps.rs b/src/stamps.rs
index 62cd2e1..694b086 100644
--- a/src/stamps.rs
+++ b/src/stamps.rs
@@ -1,33 +1,25 @@
 //! Key-value store in `*.stamps` file.
 
-use failure::{self, ResultExt};
+use anyhow::{anyhow, Context, Result};
 use std::{env, fs, path::PathBuf};
 
 /// Get a value corresponding to the key from the JSON value.
 ///
 /// You should use return value of function `read_stamps_file_to_json()` as `json` argument.
-pub fn get_stamp_value(
-    key: impl AsRef<str>,
-    json: &serde_json::Value,
-) -> Result<String, failure::Error> {
+pub fn get_stamp_value(key: impl AsRef<str>, json: &serde_json::Value) -> Result<String> {
     json.get(key.as_ref())
         .and_then(|value| value.as_str().map(ToOwned::to_owned))
-        .ok_or_else(|| {
-            failure::err_msg(format!("cannot get stamp value for key '{}'", key.as_ref()))
-        })
+        .ok_or_else(|| anyhow!("cannot get stamp value for key '{}'", key.as_ref()))
 }
 
 /// Save the key-value pair to the store.
-pub fn save_stamp_value(
-    key: impl Into<String>,
-    value: impl AsRef<str>,
-) -> Result<(), failure::Error> {
+pub fn save_stamp_value(key: impl Into<String>, value: impl AsRef<str>) -> Result<()> {
     let mut json = read_stamps_file_to_json().unwrap_or_else(|_| serde_json::Map::new().into());
 
     {
         let stamps = json
             .as_object_mut()
-            .ok_or_else(|| failure::err_msg("stamps file doesn't contain JSON object"))?;
+            .ok_or_else(|| anyhow!("stamps file doesn't contain JSON object"))?;
         stamps.insert(key.into(), value.as_ref().into());
     }
 
@@ -35,7 +27,7 @@ pub fn save_stamp_value(
 }
 
 /// Get the path of the `*.stamps` file that is used as the store.
-pub fn get_stamps_file_path() -> Result<PathBuf, failure::Error> {
+pub fn get_stamps_file_path() -> Result<PathBuf> {
     let path = env::current_exe()
         .map(|path| path.with_extension("stamps"))
         .context("cannot get stamps file path")?;
@@ -43,7 +35,7 @@ pub fn get_stamps_file_path() -> Result<PathBuf, failure::Error> {
 }
 
 /// Read `*.stamps` file and convert its content to the JSON value.
-pub fn read_stamps_file_to_json() -> Result<serde_json::Value, failure::Error> {
+pub fn read_stamps_file_to_json() -> Result<serde_json::Value> {
     let stamps_file_path = get_stamps_file_path()?;
     let stamps_file_content =
         fs::read_to_string(stamps_file_path).context("cannot find or read stamps file")?;
@@ -52,7 +44,7 @@ pub fn read_stamps_file_to_json() -> Result<serde_json::Value, failure::Error> {
     Ok(json)
 }
 
-fn write_to_stamps_file(json: serde_json::Value) -> Result<(), failure::Error> {
+fn write_to_stamps_file(json: serde_json::Value) -> Result<()> {
     let stamps_file_path = get_stamps_file_path()?;
     let pretty_json = serde_json::to_string_pretty(&json).context("JSON serialization failed")?;
     fs::write(stamps_file_path, pretty_json).context("cannot write to stamps file")?;
diff --git a/src/test/mod.rs b/src/test/mod.rs
index 513e8fa..05ba4fc 100644
--- a/src/test/mod.rs
+++ b/src/test/mod.rs
@@ -3,8 +3,8 @@
 pub mod webdriver;
 
 use crate::PBAR;
+use anyhow::{Context, Result};
 use child;
-use failure::{self, ResultExt};
 use std::ffi::OsStr;
 use std::path::Path;
 use std::process::Command;
@@ -16,7 +16,7 @@ pub fn cargo_test_wasm<I, K, V>(
     release: bool,
     envs: I,
     extra_options: &[String],
-) -> Result<(), failure::Error>
+) -> Result<()>
 where
     I: IntoIterator<Item = (K, V)>,
     K: AsRef<OsStr>,
diff --git a/src/test/webdriver.rs b/src/test/webdriver.rs
index 93de546..3b9ece9 100644
--- a/src/test/webdriver.rs
+++ b/src/test/webdriver.rs
@@ -4,8 +4,8 @@ mod chromedriver;
 mod geckodriver;
 mod safaridriver;
 
+use anyhow::Result;
 use binary_install::Cache;
-use failure;
 use std::path::PathBuf;
 use PBAR;
 
@@ -22,7 +22,7 @@ fn get_and_notify(
     installation_allowed: bool,
     name: &str,
     url: &str,
-) -> Result<Option<PathBuf>, failure::Error> {
+) -> Result<Option<PathBuf>> {
     if let Some(dl) = cache.download(false, name, &[name], url)? {
         return Ok(Some(dl.binary(name)?));
     }
diff --git a/src/test/webdriver/chromedriver.rs b/src/test/webdriver/chromedriver.rs
index 6fb9301..67e1928 100644
--- a/src/test/webdriver/chromedriver.rs
+++ b/src/test/webdriver/chromedriver.rs
@@ -1,7 +1,7 @@
 use super::{get_and_notify, Collector};
+use anyhow::{bail, Context, Result};
 use binary_install::Cache;
 use chrono::DateTime;
-use failure::{self, ResultExt};
 use install::InstallMode;
 use stamps;
 use std::path::PathBuf;
@@ -16,10 +16,7 @@ const CHROMEDRIVER_VERSION_STAMP: &str = "chromedriver_version";
 
 /// Get the path to an existing `chromedriver`, or install it if no existing
 /// binary is found or if there is a new binary version.
-pub fn get_or_install_chromedriver(
-    cache: &Cache,
-    mode: InstallMode,
-) -> Result<PathBuf, failure::Error> {
+pub fn get_or_install_chromedriver(cache: &Cache, mode: InstallMode) -> Result<PathBuf> {
     if let Ok(path) = which::which("chromedriver") {
         return Ok(path);
     }
@@ -27,10 +24,7 @@ pub fn get_or_install_chromedriver(
 }
 
 /// Download and install a pre-built `chromedriver` binary.
-pub fn install_chromedriver(
-    cache: &Cache,
-    installation_allowed: bool,
-) -> Result<PathBuf, failure::Error> {
+pub fn install_chromedriver(cache: &Cache, installation_allowed: bool) -> Result<PathBuf> {
     let target = if target::LINUX && target::x86_64 {
         "linux64"
     } else if target::MACOS && target::x86_64 {
@@ -99,7 +93,7 @@ fn get_chromedriver_url(target: &str) -> String {
 
 // ------ `get_chromedriver_url` helpers ------
 
-fn save_chromedriver_version(version: String) -> Result<String, failure::Error> {
+fn save_chromedriver_version(version: String) -> Result<String> {
     stamps::save_stamp_value(CHROMEDRIVER_VERSION_STAMP, &version)?;
 
     let current_time = chrono::offset::Local::now().to_rfc3339();
@@ -122,7 +116,7 @@ fn should_load_chromedriver_version_from_stamp(json: &serde_json::Value) -> bool
     }
 }
 
-fn fetch_chromedriver_version() -> Result<String, failure::Error> {
+fn fetch_chromedriver_version() -> Result<String> {
     let mut handle = curl::easy::Easy2::new(Collector(Vec::new()));
     handle
         .url("https://chromedriver.storage.googleapis.com/LATEST_RELEASE")
diff --git a/src/test/webdriver/geckodriver.rs b/src/test/webdriver/geckodriver.rs
index eaf25b3..1a8ee80 100644
--- a/src/test/webdriver/geckodriver.rs
+++ b/src/test/webdriver/geckodriver.rs
@@ -1,7 +1,7 @@
 use super::{get_and_notify, Collector};
+use anyhow::{anyhow, bail, Context, Result};
 use binary_install::Cache;
 use chrono::DateTime;
-use failure::{self, ResultExt};
 use install::InstallMode;
 use stamps;
 use std::path::PathBuf;
@@ -17,10 +17,7 @@ const GECKODRIVER_VERSION_STAMP: &str = "geckodriver_version";
 
 /// Get the path to an existing `geckodriver`, or install it if no existing
 /// binary is found or if there is a new binary version.
-pub fn get_or_install_geckodriver(
-    cache: &Cache,
-    mode: InstallMode,
-) -> Result<PathBuf, failure::Error> {
+pub fn get_or_install_geckodriver(cache: &Cache, mode: InstallMode) -> Result<PathBuf> {
     // geckodriver Windows binaries >v0.24.0 have an additional
     // runtime dependency that we cannot be sure is present on the
     // user's machine
@@ -38,10 +35,7 @@ pub fn get_or_install_geckodriver(
 }
 
 /// Download and install a pre-built `geckodriver` binary.
-pub fn install_geckodriver(
-    cache: &Cache,
-    installation_allowed: bool,
-) -> Result<PathBuf, failure::Error> {
+pub fn install_geckodriver(cache: &Cache, installation_allowed: bool) -> Result<PathBuf> {
     let (target, ext) = if target::LINUX && target::x86 {
         ("linux32", "tar.gz")
     } else if target::LINUX && target::x86_64 {
@@ -124,7 +118,7 @@ fn get_geckodriver_url(target: &str, ext: &str) -> String {
 
 // ------ `get_geckodriver_url` helpers  ------
 
-fn save_geckodriver_version(version: String) -> Result<String, failure::Error> {
+fn save_geckodriver_version(version: String) -> Result<String> {
     stamps::save_stamp_value(GECKODRIVER_VERSION_STAMP, &version)?;
 
     let current_time = chrono::offset::Local::now().to_rfc3339();
@@ -147,7 +141,7 @@ fn should_load_geckodriver_version_from_stamp(json: &serde_json::Value) -> bool
     }
 }
 
-fn fetch_latest_geckodriver_tag_json() -> Result<String, failure::Error> {
+fn fetch_latest_geckodriver_tag_json() -> Result<String> {
     let mut headers = curl::easy::List::new();
     headers
         .append("Accept: application/json")
@@ -176,14 +170,12 @@ fn fetch_latest_geckodriver_tag_json() -> Result<String, failure::Error> {
 }
 
 /// JSON example: `{"id":15227534,"tag_name":"v0.24.0","update_url":"/mozzila...`
-fn get_version_from_json(json: impl AsRef<str>) -> Result<String, failure::Error> {
+fn get_version_from_json(json: impl AsRef<str>) -> Result<String> {
     let json: serde_json::Value = serde_json::from_str(json.as_ref())
         .context("geckodriver's latest release data is not valid JSON")?;
     json.get("tag_name")
         .and_then(|tag_name| tag_name.as_str().map(ToOwned::to_owned))
-        .ok_or_else(|| {
-            failure::err_msg("cannot get `tag_name` from geckodriver's latest release data")
-        })
+        .ok_or_else(|| anyhow!("cannot get `tag_name` from geckodriver's latest release data"))
 }
 
 fn assemble_geckodriver_url(tag: &str, target: &str, ext: &str) -> String {
diff --git a/src/test/webdriver/safaridriver.rs b/src/test/webdriver/safaridriver.rs
index 867a14d..6869d2e 100644
--- a/src/test/webdriver/safaridriver.rs
+++ b/src/test/webdriver/safaridriver.rs
@@ -1,3 +1,4 @@
+use anyhow::{bail, Result};
 use std::path::PathBuf;
 
 /// Get the path to an existing `safaridriver`.
@@ -5,7 +6,7 @@ use std::path::PathBuf;
 /// We can't install `safaridriver` if an existing one is not found because
 /// Apple does not provide pre-built binaries. However, `safaridriver` *should*
 /// be present by default.
-pub fn get_safaridriver() -> Result<PathBuf, failure::Error> {
+pub fn get_safaridriver() -> Result<PathBuf> {
     match which::which("safaridriver") {
         Ok(p) => Ok(p),
         Err(_) => bail!("could not find `safaridriver` on the `$PATH`"),
diff --git a/src/wasm_opt.rs b/src/wasm_opt.rs
index cd8944e..7e354e3 100644
--- a/src/wasm_opt.rs
+++ b/src/wasm_opt.rs
@@ -3,18 +3,14 @@
 use crate::child;
 use crate::install::{self, Tool};
 use crate::PBAR;
+use anyhow::Result;
 use binary_install::{Cache, Download};
 use std::path::Path;
 use std::process::Command;
 
 /// Execute `wasm-opt` over wasm binaries found in `out_dir`, downloading if
 /// necessary into `cache`. Passes `args` to each invocation of `wasm-opt`.
-pub fn run(
-    cache: &Cache,
-    out_dir: &Path,
-    args: &[String],
-    install_permitted: bool,
-) -> Result<(), failure::Error> {
+pub fn run(cache: &Cache, out_dir: &Path, args: &[String], install_permitted: bool) -> Result<()> {
     let wasm_opt = match find_wasm_opt(cache, install_permitted)? {
         install::Status::Found(path) => path,
         install::Status::CannotInstall => {
@@ -55,10 +51,7 @@ pub fn run(
 /// Returns `None` if a binary wasn't found in `PATH` and this platform doesn't
 /// have precompiled binaries. Returns an error if we failed to download the
 /// binary.
-pub fn find_wasm_opt(
-    cache: &Cache,
-    install_permitted: bool,
-) -> Result<install::Status, failure::Error> {
+pub fn find_wasm_opt(cache: &Cache, install_permitted: bool) -> Result<install::Status> {
     // First attempt to look up in PATH. If found assume it works.
     if let Ok(path) = which::which("wasm-opt") {
         PBAR.info(&format!("found wasm-opt at {:?}", path));
diff --git a/tests/all/download.rs b/tests/all/download.rs
index f19ba1e..7d00bb8 100644
--- a/tests/all/download.rs
+++ b/tests/all/download.rs
@@ -35,10 +35,8 @@ fn downloading_prebuilt_wasm_bindgen_handles_http_errors() {
     assert!(result.is_err());
     let error = result.err().unwrap();
 
-    assert!(error.iter_chain().any(|e| e.to_string().contains("404")));
-    assert!(error
-        .iter_chain()
-        .any(|e| e.to_string().contains(bad_version)));
+    assert!(error.chain().any(|e| e.to_string().contains("404")));
+    assert!(error.chain().any(|e| e.to_string().contains(bad_version)));
 }
 
 #[test]
diff --git a/tests/all/license.rs b/tests/all/license.rs
index cffa799..8869db8 100644
--- a/tests/all/license.rs
+++ b/tests/all/license.rs
@@ -1,4 +1,4 @@
-extern crate failure;
+extern crate anyhow;
 extern crate wasm_pack;
 
 use std::fs;
diff --git a/tests/all/main.rs b/tests/all/main.rs
index 20a25ae..c99a871 100644
--- a/tests/all/main.rs
+++ b/tests/all/main.rs
@@ -1,8 +1,7 @@
+extern crate anyhow;
 extern crate assert_cmd;
-extern crate failure;
-extern crate predicates;
-#[macro_use]
 extern crate lazy_static;
+extern crate predicates;
 #[macro_use]
 extern crate serde_derive;
 extern crate binary_install;
diff --git a/tests/all/readme.rs b/tests/all/readme.rs
index 8576f33..a621631 100644
--- a/tests/all/readme.rs
+++ b/tests/all/readme.rs
@@ -1,4 +1,4 @@
-extern crate failure;
+extern crate anyhow;
 extern crate wasm_pack;
 
 use std::fs;
diff --git a/tests/all/test.rs b/tests/all/test.rs
index bc95e8d..0113f76 100644
--- a/tests/all/test.rs
+++ b/tests/all/test.rs
@@ -33,6 +33,7 @@ fn it_can_run_tests_with_different_wbg_test_and_wbg_versions() {
 #[cfg(any(
     all(target_os = "linux", target_arch = "x86_64"),
     all(target_os = "macos", target_arch = "x86_64"),
+    all(target_os = "macos", target_arch = "aarch64"),
     all(target_os = "windows", target_arch = "x86"),
     all(target_os = "windows", target_arch = "x86_64")
 ))]
@@ -44,6 +45,7 @@ fn it_can_run_browser_tests() {
         all(target_os = "linux", target_arch = "x86"),
         all(target_os = "linux", target_arch = "x86_64"),
         all(target_os = "macos", target_arch = "x86_64"),
+        all(target_os = "macos", target_arch = "aarch64"),
         all(target_os = "windows", target_arch = "x86"),
         all(target_os = "windows", target_arch = "x86_64")
     ));
@@ -104,6 +106,7 @@ fn it_can_run_failing_tests() {
     all(target_os = "linux", target_arch = "x86"),
     all(target_os = "linux", target_arch = "x86_64"),
     all(target_os = "macos", target_arch = "x86_64"),
+    all(target_os = "macos", target_arch = "aarch64"),
     all(target_os = "windows", target_arch = "x86"),
     all(target_os = "windows", target_arch = "x86_64")
 ))]
diff --git a/tests/all/utils/file.rs b/tests/all/utils/file.rs
index cf7f23f..e154808 100644
--- a/tests/all/utils/file.rs
+++ b/tests/all/utils/file.rs
@@ -2,9 +2,9 @@ use std::fs::File;
 use std::io::Read;
 use std::path::Path;
 
-use failure::Error;
+use anyhow::Result;
 
-pub fn read_file(path: &Path) -> Result<String, Error> {
+pub fn read_file(path: &Path) -> Result<String> {
     let mut file = File::open(path)?;
     let mut contents = String::new();
     file.read_to_string(&mut contents)?;
diff --git a/tests/all/utils/manifest.rs b/tests/all/utils/manifest.rs
index eeeb4e6..3a788de 100644
--- a/tests/all/utils/manifest.rs
+++ b/tests/all/utils/manifest.rs
@@ -2,7 +2,7 @@ use std::io::prelude::*;
 use std::path::Path;
 use std::{collections::HashMap, fs::File};
 
-use failure::Error;
+use anyhow::Result;
 use serde_json;
 
 #[derive(Deserialize)]
@@ -43,7 +43,7 @@ pub struct Repository {
     pub url: String,
 }
 
-pub fn read_package_json(path: &Path, out_dir: &Path) -> Result<NpmPackage, Error> {
+pub fn read_package_json(path: &Path, out_dir: &Path) -> Result<NpmPackage> {
     let manifest_path = path.join(out_dir).join("package.json");
     let mut pkg_file = File::open(manifest_path)?;
     let mut pkg_contents = String::new();
@@ -52,7 +52,7 @@ pub fn read_package_json(path: &Path, out_dir: &Path) -> Result<NpmPackage, Erro
     Ok(serde_json::from_str(&pkg_contents)?)
 }
 
-pub fn create_wbg_package_json(out_dir: &Path, contents: &str) -> Result<(), Error> {
+pub fn create_wbg_package_json(out_dir: &Path, contents: &str) -> Result<()> {
     let manifest_path = out_dir.join("package.json");
     Ok(std::fs::write(manifest_path, contents)?)
 }
diff --git a/tests/all/webdriver.rs b/tests/all/webdriver.rs
index 6223290..cf081e7 100644
--- a/tests/all/webdriver.rs
+++ b/tests/all/webdriver.rs
@@ -20,6 +20,7 @@ fn can_install_chromedriver() {
     all(target_os = "linux", target_arch = "x86"),
     all(target_os = "linux", target_arch = "x86_64"),
     all(target_os = "macos", target_arch = "x86_64"),
+    all(target_os = "macos", target_arch = "aarch64"),
     all(target_os = "windows", target_arch = "x86"),
     all(target_os = "windows", target_arch = "x86_64")
 ))]