diff --git a/.gitignore b/.gitignore
index c2853f0db9..ad04663079 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
/target/
/book/html/
+/book/src/img/
+/book/src/tests.ok
**/*.rs.bk
.cargo
diff --git a/README.md b/README.md
index c5ce89d86f..c545461202 100644
--- a/README.md
+++ b/README.md
@@ -73,19 +73,19 @@ cargo install mdbook
Run any Rust tests in the markdown:
```bash
-mdbook test book
+make -C book test
```
Render markdown as HTML:
```bash
-mdbook build book
+make -C book build
```
Render and view the book:
```bash
-mdbook build --open book
+make -C book open
```
diff --git a/book/makefile b/book/makefile
new file mode 100644
index 0000000000..14a5aeac2d
--- /dev/null
+++ b/book/makefile
@@ -0,0 +1,33 @@
+BOB_SRCS=$(wildcard art/*.bob)
+MD_SRCS=$(wildcard src/*.md)
+
+SVG_IMGS=$(BOB_SRCS:art/%.bob=src/img/%.svg)
+
+all: html/index.html
+
+test: src/tests.ok
+
+open: all
+ mdbook build --open
+
+watch: $(SVG_IMGS)
+ mdbook watch
+
+src/img/%.svg: art/%.bob
+ @mkdir -p $(@D)
+ svgbob < $< > $@
+
+src/%.md: %.md
+ @mkdir -p $(@D)
+ @cp $< $@
+
+src/tests.ok: $(SVG_IMGS) $(MD_SRCS)
+ mdbook test
+ touch $@
+
+html/index.html: src/tests.ok
+ mdbook build
+
+clean:
+ rm -f $(SVG_IMGS) src/tests.ok
+ rm -rf html
diff --git a/book/src/img/fullnode.svg b/book/src/img/fullnode.svg
deleted file mode 100644
index 3777bb0462..0000000000
--- a/book/src/img/fullnode.svg
+++ /dev/null
@@ -1,385 +0,0 @@
-
diff --git a/book/src/img/leader-scheduler.svg b/book/src/img/leader-scheduler.svg
deleted file mode 100644
index 3d13d7549b..0000000000
--- a/book/src/img/leader-scheduler.svg
+++ /dev/null
@@ -1,330 +0,0 @@
-
diff --git a/book/src/img/runtime.svg b/book/src/img/runtime.svg
deleted file mode 100644
index 3e823946d9..0000000000
--- a/book/src/img/runtime.svg
+++ /dev/null
@@ -1,211 +0,0 @@
-
diff --git a/book/src/img/sdk-tools.svg b/book/src/img/sdk-tools.svg
deleted file mode 100644
index 629a3feaa3..0000000000
--- a/book/src/img/sdk-tools.svg
+++ /dev/null
@@ -1,237 +0,0 @@
-
diff --git a/book/src/img/tpu.svg b/book/src/img/tpu.svg
deleted file mode 100644
index 7a7406ce2f..0000000000
--- a/book/src/img/tpu.svg
+++ /dev/null
@@ -1,338 +0,0 @@
-
diff --git a/book/src/img/tvu.svg b/book/src/img/tvu.svg
deleted file mode 100644
index 7a7b94f988..0000000000
--- a/book/src/img/tvu.svg
+++ /dev/null
@@ -1,343 +0,0 @@
-
diff --git a/ci/publish-book.sh b/ci/publish-book.sh
index 85850c6bbf..a29fadff21 100755
--- a/ci/publish-book.sh
+++ b/ci/publish-book.sh
@@ -22,8 +22,7 @@ maybe_install() {
export PATH=$CARGO_HOME/bin:$PATH
maybe_install mdbook
-_ mdbook test book
-_ mdbook build book
+_ make -C book
echo --- create book repo
(
diff --git a/ci/test-stable.sh b/ci/test-stable.sh
index 4be3c91d59..c3affea17a 100755
--- a/ci/test-stable.sh
+++ b/ci/test-stable.sh
@@ -47,8 +47,7 @@ done
# Build the HTML
export PATH=$CARGO_HOME/bin:$PATH
maybe_install mdbook
-_ mdbook test book
-_ mdbook build book
+_ make -C book
echo --- ci/localnet-sanity.sh
(