███████████ ██████████ ███████████ ██░░░░░░███ ██░░░░░███ ██░░░░░░░███ ██ ███ ██ ███ ██ ███ ██ ███ ██ ███ ██ ███ ██ ███ ██ ███ ██ ███ ███████████ ██████████ ███████████ ░░░░░░░░░░ ░░░░░░░░░ ░░░░░░░░░░░
web3 database · ipfs native · encrypted · self-hosted
one command. detects your OS, installs Node 20+, Kubo IPFS, PM2, and the ZDB server.
curl -fsSL https://zdb.zexvro.in/install.sh | bash
works on Linux, macOS, and Termux (Android). idempotent — safe to re-run for updates.
~/zdbzdb CLI to ~/.local/bin/| command | description |
|---|---|
zdb up | start IPFS + ZDB daemons |
zdb up --info | start and show system info |
zdb down | stop all services |
zdb status | check daemon status |
zdb info | traffic, storage, memory, peers |
zdb logs | tail daemon logs |
zdb install | install or update ZDB |
ZDB runs on http://localhost:8899 by default. all endpoints return JSON. records are addressed by an explicit id you supply per insert.
databases are created up-front, and you pick their storage kind at creation (see modes).
POST /v1/databases
Content-Type: application/json
{
"name": "users",
"tech": "kv",
"storage": "local" // local | mirror | ipfs (default mirror)
}
// response — note the storage field is persisted on this db
{
"name": "users",
"storage": "local",
"apiKey": "zdb_..."
}
POST /v1/db/users/insert
Content-Type: application/json
x-zdb-token: <base64 {uid}>
{
"id": "a1b2c3d4",
"value": { "name": "zexvro", "role": "admin" },
"metadata": { "kind": "user" }
}
// response (HTTP 201)
// inserting the same id again OVERWRITES that record (this is the "update")
// get one by id POST /v1/db/users/get { "id": "a1b2c3d4" } // query by metadata filter POST /v1/db/users/query { "filter": { "kind": "user" }, "limit": 100, "desc": true } // delete (writes a tombstone) POST /v1/db/users/delete { "id": "a1b2c3d4" }
subscribe to a database's inserts / deletes / seals and stream them live. use it to build realtime apps (chat, kanban, etc.).
// client (EventSource can't send our auth header, so use fetch + ReadableStream, // or a small fetch-stream helper that sets x-zdb-token) GET /v1/db/users/watch Accept: text/event-stream x-zdb-token: <base64 {uid}> // streamed frames event: change data: { "type": "put", "id": "a1b2c3d4", "ts": 1730000000000 }
| route | description |
|---|---|
GET /health | server health, version, storage, ipfs status |
GET /v1/databases | list databases |
POST /v1/db/:name/search | vector search (vector DBs) |
POST /v1/db/:name/seal | seal current head into a shard (immutable snapshot) |
POST /v1/db/:name/chain | read the CID chain (ipfs/mirror) |
POST /v1/db/:name/replicate | push a shard to IPFS (mirror/ipfs) |
POST /v1/db/:name/rules | set per-db access rules |
every database has a storage kind chosen at creation (or via the ZDB_STORAGE env default). the kind decides where shards live and how durable they are. it's per-database, so one server can mix modes.
| mode | quorum | data goes to | IPFS needed? | use for |
|---|---|---|---|---|
local | 1 | local disk only | no | fast plain CRUD, no web3 needed |
mirror | 1 + copy | local disk, then replicated to IPFS | yes | fast reads with IPFS durability backup |
ipfs | IPFS | IPFS (encrypted); local copy removed | yes | content-addressed, tamper-proof, distributed |
ZDB_STORAGE, then mirror. create with storage:"local" to run fully without IPFS.
the simplest mode — behaves like a normal self-hosted key-value database. writes go straight to local disk; reads come straight back. zero IPFS involvement, so it works even with IPFS down or not installed.
insert overwrites by id, delete tombstoneswrites local first (so reads are instant), then replicates each sealed shard to IPFS as a durability copy. best of both worlds: fast app reads + a content-addressed backup.
the full web3 story. every shard is AES-256-GCM encrypted and uploaded to IPFS; the local plaintext copy is removed. CIDs chain — each seal references the previous one, so history is immutable and verifiable.
there are two very different mental models depending on your storage mode — understand this before you build.
these modes are mutable: inserting the same id overwrites the record in place, and delete removes it. this is the classic database model — exactly what you'd expect from Firebase, Redis, or Postgres.
insert same id → overwrite (an "update")delete id → record removed (tombstoned)ipfs mode is append-only. each seal snapshots the head and links it via the previous CID, forming an immutable chain. you get:
local (or mirror) for mutable, realtime app data; pick ipfs when you want tamper-proof append-only history and may not even need a live local copy.
all data is AES-256-GCM encrypted before uploading to IPFS. encryption is on by default.
data/settings.json as encryptKeyZDB_ENCRYPT=0 environment variableIPFS is one of three storage modes (see section 4). in mirror and ipfs modes, ZDB integrates with IPFS for content-addressed, durable, tamper-proof storage. local mode needs no IPFS at all.
Qm, bafy, bafk, zdb1IPFS_API_URL env varlocal mode skips IPFS entirely (fast, plain CRUD)| variable | default | description |
|---|---|---|
PORT | 8899 | server port |
ZDB_STORAGE | mirror | default storage kind: local | mirror | ipfs |
IPFS_API_URL | http://localhost:5001 | Kubo API endpoint |
ZDB_ENCRYPT | 1 | enable AES-256-GCM encryption |
ZDB_IPFS_ONLY | 0 | read data exclusively from IPFS |
ADMIN_KEY | — | admin API authentication key |
ZDB is designed as a lean, self-contained daemon. phone = storage/compute/IPFS. laptop = frontend/API.
zero npm dependencies. entire server fits in a single directory.
ZDB runs natively on Android via Termux. no root required.
pkg install nodejs then run the installerZDB is a web3-native database. it stores data on IPFS with end-to-end encryption. self-hosted, zero dependencies, runs anywhere Node.js runs.
content-addressed storage means your data is tamper-proof by design. every write gets a CID — a cryptographic fingerprint of the data. no central authority, no vendor lock-in.
yes. the server uses only Node.js built-ins. no npm install needed for the server itself.
ZDB is designed for self-hosted, personal, and small-team use. for high-traffic production, consider running multiple IPFS nodes for redundancy.