diff --git a/book/.gitignore b/book/.gitignore
new file mode 100644
index 000000000..7585238ef
--- /dev/null
+++ b/book/.gitignore
@@ -0,0 +1 @@
+book
diff --git a/book/Makefile b/book/Makefile
new file mode 100644
index 000000000..acfdb4b2d
--- /dev/null
+++ b/book/Makefile
@@ -0,0 +1,9 @@
+init:
+ cargo install mdbook --version 0.4.34 --locked
+ cargo install mdbook-admonish --version 1.12.1 --locked
+
+build:
+ mdbook build
+
+serve:
+ mdbook serve
\ No newline at end of file
diff --git a/book/README.md b/book/README.md
new file mode 100644
index 000000000..0e2346e81
--- /dev/null
+++ b/book/README.md
@@ -0,0 +1,21 @@
+# Rust Nostr Book
+
+## Init
+
+On first usage you will need to run:
+
+```bash
+make init
+```
+
+## Build
+
+```bash
+make build
+```
+
+## Serve locally
+
+```bash
+make serve
+```
\ No newline at end of file
diff --git a/book/assets/css/mdbook-admonish.css b/book/assets/css/mdbook-admonish.css
new file mode 100644
index 000000000..c3e9869e5
--- /dev/null
+++ b/book/assets/css/mdbook-admonish.css
@@ -0,0 +1,353 @@
+@charset "UTF-8";
+:root {
+ --md-admonition-icon--note:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--abstract:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--info:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--tip:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--success:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--question:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--warning:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--failure:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--danger:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--bug:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--example:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-admonition-icon--quote:
+ url("data:image/svg+xml;charset=utf-8,");
+ --md-details-icon:
+ url("data:image/svg+xml;charset=utf-8,");
+}
+
+:is(.admonition) {
+ display: flow-root;
+ margin: 1.5625em 0;
+ padding: 0 1.2rem;
+ color: var(--fg);
+ page-break-inside: avoid;
+ background-color: var(--bg);
+ border: 0 solid black;
+ border-inline-start-width: 0.4rem;
+ border-radius: 0.2rem;
+ box-shadow: 0 0.2rem 1rem rgba(0, 0, 0, 0.05), 0 0 0.1rem rgba(0, 0, 0, 0.1);
+}
+@media print {
+ :is(.admonition) {
+ box-shadow: none;
+ }
+}
+:is(.admonition) > * {
+ box-sizing: border-box;
+}
+:is(.admonition) :is(.admonition) {
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+:is(.admonition) > .tabbed-set:only-child {
+ margin-top: 0;
+}
+html :is(.admonition) > :last-child {
+ margin-bottom: 1.2rem;
+}
+
+a.admonition-anchor-link {
+ display: none;
+ position: absolute;
+ left: -1.2rem;
+ padding-right: 1rem;
+}
+a.admonition-anchor-link:link, a.admonition-anchor-link:visited {
+ color: var(--fg);
+}
+a.admonition-anchor-link:link:hover, a.admonition-anchor-link:visited:hover {
+ text-decoration: none;
+}
+a.admonition-anchor-link::before {
+ content: "ยง";
+}
+
+:is(.admonition-title, summary.admonition-title) {
+ position: relative;
+ min-height: 4rem;
+ margin-block: 0;
+ margin-inline: -1.6rem -1.2rem;
+ padding-block: 0.8rem;
+ padding-inline: 4.4rem 1.2rem;
+ font-weight: 700;
+ background-color: rgba(68, 138, 255, 0.1);
+ display: flex;
+}
+:is(.admonition-title, summary.admonition-title) p {
+ margin: 0;
+}
+html :is(.admonition-title, summary.admonition-title):last-child {
+ margin-bottom: 0;
+}
+:is(.admonition-title, summary.admonition-title)::before {
+ position: absolute;
+ top: 0.625em;
+ inset-inline-start: 1.6rem;
+ width: 2rem;
+ height: 2rem;
+ background-color: #448aff;
+ mask-image: url('data:image/svg+xml;charset=utf-8,');
+ -webkit-mask-image: url('data:image/svg+xml;charset=utf-8,');
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-size: contain;
+ content: "";
+}
+:is(.admonition-title, summary.admonition-title):hover a.admonition-anchor-link {
+ display: initial;
+}
+
+details.admonition > summary.admonition-title::after {
+ position: absolute;
+ top: 0.625em;
+ inset-inline-end: 1.6rem;
+ height: 2rem;
+ width: 2rem;
+ background-color: currentcolor;
+ mask-image: var(--md-details-icon);
+ -webkit-mask-image: var(--md-details-icon);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-size: contain;
+ content: "";
+ transform: rotate(0deg);
+ transition: transform 0.25s;
+}
+details[open].admonition > summary.admonition-title::after {
+ transform: rotate(90deg);
+}
+
+:is(.admonition):is(.note) {
+ border-color: #448aff;
+}
+
+:is(.note) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(68, 138, 255, 0.1);
+}
+:is(.note) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #448aff;
+ mask-image: var(--md-admonition-icon--note);
+ -webkit-mask-image: var(--md-admonition-icon--note);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.abstract, .summary, .tldr) {
+ border-color: #00b0ff;
+}
+
+:is(.abstract, .summary, .tldr) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(0, 176, 255, 0.1);
+}
+:is(.abstract, .summary, .tldr) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #00b0ff;
+ mask-image: var(--md-admonition-icon--abstract);
+ -webkit-mask-image: var(--md-admonition-icon--abstract);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.info, .todo) {
+ border-color: #00b8d4;
+}
+
+:is(.info, .todo) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(0, 184, 212, 0.1);
+}
+:is(.info, .todo) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #00b8d4;
+ mask-image: var(--md-admonition-icon--info);
+ -webkit-mask-image: var(--md-admonition-icon--info);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.tip, .hint, .important) {
+ border-color: #00bfa5;
+}
+
+:is(.tip, .hint, .important) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(0, 191, 165, 0.1);
+}
+:is(.tip, .hint, .important) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #00bfa5;
+ mask-image: var(--md-admonition-icon--tip);
+ -webkit-mask-image: var(--md-admonition-icon--tip);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.success, .check, .done) {
+ border-color: #00c853;
+}
+
+:is(.success, .check, .done) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(0, 200, 83, 0.1);
+}
+:is(.success, .check, .done) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #00c853;
+ mask-image: var(--md-admonition-icon--success);
+ -webkit-mask-image: var(--md-admonition-icon--success);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.question, .help, .faq) {
+ border-color: #64dd17;
+}
+
+:is(.question, .help, .faq) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(100, 221, 23, 0.1);
+}
+:is(.question, .help, .faq) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #64dd17;
+ mask-image: var(--md-admonition-icon--question);
+ -webkit-mask-image: var(--md-admonition-icon--question);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.warning, .caution, .attention) {
+ border-color: #ff9100;
+}
+
+:is(.warning, .caution, .attention) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(255, 145, 0, 0.1);
+}
+:is(.warning, .caution, .attention) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #ff9100;
+ mask-image: var(--md-admonition-icon--warning);
+ -webkit-mask-image: var(--md-admonition-icon--warning);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.failure, .fail, .missing) {
+ border-color: #ff5252;
+}
+
+:is(.failure, .fail, .missing) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(255, 82, 82, 0.1);
+}
+:is(.failure, .fail, .missing) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #ff5252;
+ mask-image: var(--md-admonition-icon--failure);
+ -webkit-mask-image: var(--md-admonition-icon--failure);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.danger, .error) {
+ border-color: #ff1744;
+}
+
+:is(.danger, .error) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(255, 23, 68, 0.1);
+}
+:is(.danger, .error) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #ff1744;
+ mask-image: var(--md-admonition-icon--danger);
+ -webkit-mask-image: var(--md-admonition-icon--danger);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.bug) {
+ border-color: #f50057;
+}
+
+:is(.bug) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(245, 0, 87, 0.1);
+}
+:is(.bug) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #f50057;
+ mask-image: var(--md-admonition-icon--bug);
+ -webkit-mask-image: var(--md-admonition-icon--bug);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.example) {
+ border-color: #7c4dff;
+}
+
+:is(.example) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(124, 77, 255, 0.1);
+}
+:is(.example) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #7c4dff;
+ mask-image: var(--md-admonition-icon--example);
+ -webkit-mask-image: var(--md-admonition-icon--example);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+:is(.admonition):is(.quote, .cite) {
+ border-color: #9e9e9e;
+}
+
+:is(.quote, .cite) > :is(.admonition-title, summary.admonition-title) {
+ background-color: rgba(158, 158, 158, 0.1);
+}
+:is(.quote, .cite) > :is(.admonition-title, summary.admonition-title)::before {
+ background-color: #9e9e9e;
+ mask-image: var(--md-admonition-icon--quote);
+ -webkit-mask-image: var(--md-admonition-icon--quote);
+ mask-repeat: no-repeat;
+ -webkit-mask-repeat: no-repeat;
+ mask-size: contain;
+ -webkit-mask-repeat: no-repeat;
+}
+
+.navy :is(.admonition) {
+ background-color: var(--sidebar-bg);
+}
+
+.ayu :is(.admonition), .coal :is(.admonition) {
+ background-color: var(--theme-hover);
+}
+
+.rust :is(.admonition) {
+ background-color: var(--sidebar-bg);
+ color: var(--sidebar-fg);
+}
+.rust .admonition-anchor-link:link, .rust .admonition-anchor-link:visited {
+ color: var(--sidebar-fg);
+}
diff --git a/book/book.toml b/book/book.toml
new file mode 100644
index 000000000..8e5a2c9f8
--- /dev/null
+++ b/book/book.toml
@@ -0,0 +1,15 @@
+[book]
+title = "Rust Nostr Book"
+authors = ["Yuki Kishimoto "]
+language = "en"
+multilingual = false
+
+[output.html]
+git-repository-url = "https://github.com/rust-nostr/nostr"
+additional-css = ["./assets/css/mdbook-admonish.css"]
+
+[preprocessor]
+
+[preprocessor.admonish]
+command = "mdbook-admonish"
+assets_version = "2.0.2" # do not edit: managed by `mdbook-admonish install`
diff --git a/book/src/README.md b/book/src/README.md
new file mode 100644
index 000000000..e10b99d01
--- /dev/null
+++ b/book/src/README.md
@@ -0,0 +1 @@
+# Introduction
diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md
new file mode 100644
index 000000000..145962cc3
--- /dev/null
+++ b/book/src/SUMMARY.md
@@ -0,0 +1,12 @@
+# Summary
+
+[Introduction](README.md)
+
+# Libraries
+
+* [Nostr](./nostr/01-getting-started.md)
+ * [Installation](./nostr/02-installation.md)
+ * [Features](./nostr/03-features.md)
+* [Nostr SDK](./nostr-sdk/01-getting-started.md)
+ * [Installation](./nostr-sdk/02-installation.md)
+ * [Features](./nostr-sdk/03-features.md)
diff --git a/book/src/nostr-sdk/01-getting-started.md b/book/src/nostr-sdk/01-getting-started.md
new file mode 100644
index 000000000..d2dd973d4
--- /dev/null
+++ b/book/src/nostr-sdk/01-getting-started.md
@@ -0,0 +1 @@
+# Nostr SDK
diff --git a/book/src/nostr-sdk/02-installation.md b/book/src/nostr-sdk/02-installation.md
new file mode 100644
index 000000000..06dcaca11
--- /dev/null
+++ b/book/src/nostr-sdk/02-installation.md
@@ -0,0 +1,19 @@
+# Installing the library
+
+Add the `nostr-sdk` dependency in your `Cargo.toml` file:
+
+```toml
+[dependencies]
+nostr-sdk = "0.24"
+```
+
+Alternatively, you can add it directly from `git` source:
+
+```toml
+[dependencies]
+nostr-sdk = { git = "https://github.com/rust-nostr/nostr", tag = "vX.X.X" }
+```
+
+```admonish note
+To use a specific commit, use `rev` instead of `tag`.
+```
diff --git a/book/src/nostr-sdk/03-features.md b/book/src/nostr-sdk/03-features.md
new file mode 100644
index 000000000..ead022319
--- /dev/null
+++ b/book/src/nostr-sdk/03-features.md
@@ -0,0 +1 @@
+# Features
diff --git a/book/src/nostr/01-getting-started.md b/book/src/nostr/01-getting-started.md
new file mode 100644
index 000000000..2eabae603
--- /dev/null
+++ b/book/src/nostr/01-getting-started.md
@@ -0,0 +1,3 @@
+# Nostr
+
+This section include documentation for the `nostr` library (all supported languages).
\ No newline at end of file
diff --git a/book/src/nostr/02-installation.md b/book/src/nostr/02-installation.md
new file mode 100644
index 000000000..036920a5e
--- /dev/null
+++ b/book/src/nostr/02-installation.md
@@ -0,0 +1,90 @@
+# Installing the library
+
+TODO: add support to content tabs
+
+=== "Rust"
+
+Add the `nostr` dependency in your `Cargo.toml` file:
+
+```toml
+[dependencies]
+nostr = "0.24"
+```
+
+Alternatively, you can add it directly from `git` source:
+
+```toml
+[dependencies]
+nostr = { git = "https://github.com/rust-nostr/nostr", tag = "v0.24.0" }
+```
+
+```admonish note
+To use a specific commit, use `rev` instead of `tag`.
+```
+
+=== "Python"
+
+The `nostr-protocol` package is available on the public PyPI:
+
+```bash
+pip install nostr-protocol
+```
+
+=== "Kotlin"
+
+To use the Kotlin language bindings for `nostr` in your Android project add the following to your gradle dependencies:
+
+```kotlin
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation("io.github.rust-nostr:nostr:")
+}
+```
+
+## Known issues
+
+### JNA dependency
+
+Depending on the JVM version you use, you might not have the JNA dependency on your classpath. The exception thrown will be
+
+```bash
+class file for com.sun.jna.Pointer not found
+```
+
+The solution is to add JNA as a dependency like so:
+
+```kotlin
+dependencies {
+ // ...
+ implementation("net.java.dev.jna:jna:5.12.1")
+}
+```
+
+=== "Swift"
+
+### Xcode
+
+Via `File > Add Packages...`, add
+
+```
+https://github.com/rust-nostr/nostr-swift.git
+```
+
+as a package dependency in Xcode.
+
+### Swift Package
+
+Add the following to the dependencies array in your `Package.swift`:
+
+``` swift
+.package(url: "https://github.com/rust-nostr/nostr-swift.git", from: "0.0.4"),
+```
+
+=== "JavaScript"
+
+```bash
+npm i @rust-nostr/nostr
+```
\ No newline at end of file
diff --git a/book/src/nostr/03-features.md b/book/src/nostr/03-features.md
new file mode 100644
index 000000000..99a5481b3
--- /dev/null
+++ b/book/src/nostr/03-features.md
@@ -0,0 +1,2 @@
+# Features
+