███████████ ██████████   ███████████
 ██░░░░░░███ ██░░░░░███  ██░░░░░░░███
 ██     ███ ██     ███  ██       ███
 ██     ███ ██     ███  ██       ███
 ██     ███ ██     ███  ██       ███
 ███████████ ██████████   ███████████
 ░░░░░░░░░░  ░░░░░░░░░   ░░░░░░░░░░░

web3 database · ipfs native · encrypted · self-hosted

1. install

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.

what it installs

2. cli commands

commanddescription
zdb upstart IPFS + ZDB daemons
zdb up --infostart and show system info
zdb downstop all services
zdb statuscheck daemon status
zdb infotraffic, storage, memory, peers
zdb logstail daemon logs
zdb installinstall or update ZDB

3. api

ZDB runs on http://localhost:8899 by default. all endpoints return JSON. records are addressed by an explicit id you supply per insert.

create a database (choose its storage)

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_..."
}

insert (create or overwrite a record)

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 / query / delete

// 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" }

realtime (SSE change stream)

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 }

other endpoints

routedescription
GET /healthserver health, version, storage, ipfs status
GET /v1/databaseslist databases
POST /v1/db/:name/searchvector search (vector DBs)
POST /v1/db/:name/sealseal current head into a shard (immutable snapshot)
POST /v1/db/:name/chainread the CID chain (ipfs/mirror)
POST /v1/db/:name/replicatepush a shard to IPFS (mirror/ipfs)
POST /v1/db/:name/rulesset per-db access rules

4. storage modes — local / mirror / ipfs

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.

modequorumdata goes toIPFS needed?use for
local1local disk onlynofast plain CRUD, no web3 needed
mirror1 + copylocal disk, then replicated to IPFSyesfast reads with IPFS durability backup
ipfsIPFSIPFS (encrypted); local copy removedyescontent-addressed, tamper-proof, distributed
default: if a database has no storage kind, it falls back to ZDB_STORAGE, then mirror. create with storage:"local" to run fully without IPFS.

local mode (normal DB, no 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.

mirror mode

writes 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.

ipfs mode

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.

5. crud & immutability

there are two very different mental models depending on your storage mode — understand this before you build.

normal CRUD (local / mirror)

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.

immutable history (ipfs mode)

ipfs mode is append-only. each seal snapshots the head and links it via the previous CID, forming an immutable chain. you get:

rule of thumb: pick 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.

6. encryption

all data is AES-256-GCM encrypted before uploading to IPFS. encryption is on by default.

7. ipfs integration

IPFS 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.

environment variables

variabledefaultdescription
PORT8899server port
ZDB_STORAGEmirrordefault storage kind: local | mirror | ipfs
IPFS_API_URLhttp://localhost:5001Kubo API endpoint
ZDB_ENCRYPT1enable AES-256-GCM encryption
ZDB_IPFS_ONLY0read data exclusively from IPFS
ADMIN_KEY—admin API authentication key

8. architecture

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.

9. security

10. termux (android)

ZDB runs natively on Android via Termux. no root required.

tip: use Tailscale to connect your phone and laptop. the phone becomes your IPFS node and ZDB server, accessible from anywhere.

11. faq

what is ZDB?

ZDB is a web3-native database. it stores data on IPFS with end-to-end encryption. self-hosted, zero dependencies, runs anywhere Node.js runs.

why IPFS?

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.

is it really zero dependencies?

yes. the server uses only Node.js built-ins. no npm install needed for the server itself.

can i use it in production?

ZDB is designed for self-hosted, personal, and small-team use. for high-traffic production, consider running multiple IPFS nodes for redundancy.

12. links