A database should not ship what you did not ask for
In the fast-paced world of web development, most databases make you pay up front: one bundle, every feature, whether your app uses it or not. GenosDB takes the opposite stance. The core is a complete graph database — storage, queries, reactivity — and everything else is a capability you request at initialization, loaded lazily, or never loaded at all.
import { gdb } from "genosdb"
// A complete local-first graph database. Nothing else.
const db = await gdb("my-app")
// The same database, plus P2P sync and a zero-trust security layer.
const secure = await gdb("my-app", {
rtc: true,
sm: { superAdmins: ["0x1234..."] }
})
What belongs in the core — and what does not
The dividing line is deliberate. The query language is not modular: all operators — comparisons, $text, logical composition, the recursive $edge traversal, geospatial $near — live inside the engine and work in every installation, with the engine's own sorting and pagination. A query language split into optional pieces would mean the same query works on one peer and fails on another; in a P2P system, that is corruption waiting to happen.
Capabilities are modular: the P2P transport (GenosRTC) and the Security Manager are separate, lazily-imported files. A note-taking app that never syncs pays nothing for WebRTC; a local dashboard pays nothing for cryptographic identity.
Lazy loading, and what it buys you
Each module is a sibling file of the bundle, resolved at runtime relative to the engine itself:
const MODULES = {
sm: () => import(new URL("./sm.min.js", import.meta.url).href),
genosrtc: () => import(new URL("./genosrtc.min.js", import.meta.url).href),
}
Note the arrow functions: the table holds recipes, not imports. A dynamic import() only runs when it is called, so a module you never enable is never downloaded, never parsed and never executed — the browser does not even request the file.
The numbers make the benefit concrete. The core engine is ~29 KB gzipped. The Security Manager — real cryptography: signatures, WebAuthn, encryption — is another ~73 KB, and the P2P transport ~25 KB. A local-only app therefore starts life at 29 KB instead of ~130 KB: less to download on first visit, less JavaScript to parse on the main thread, and a faster time-to-interactive — on a slow connection or a modest phone, that difference is the difference between instant and noticeable. And it is not only startup cost: code that never loads is code that cannot break, be exploited, or hold memory.
When you do enable modules, the price is paid once and in the right place: the engine awaits the imports during gdb() initialization — modules load in parallel with each other — and calls each module's init(db). Whatever the module returns is merged into the public API; that is how db.room and db.sm appear. Modules extend the surface, they never patch core behavior. And loading is all-or-nothing: if a module fails to load, initialization rejects with the error in plain sight — you get the database you asked for, or a loud failure, never a silently degraded one.
Modules have modules
The Security Manager applies the same principle internally. Pass superAdmins alone and you get identity, signatures and RBAC. Add governanceRules and it fetches the governance engine — rule-based role promotion, where conditions are ordinary GenosDB queries. Add acls and it fetches node-level access control. Three tiers of pay-for-what-you-use, one flag each — and the deeper tiers are tiny (the governance engine travels in under one gzipped kilobyte):
const db = await gdb("my-app", {
rtc: true,
sm: {
superAdmins: ["0x1234..."],
acls: true, // node-level permissions
governanceRules: [ /* ... */ ] // rule-based role promotion
}
})
Zero dependencies, one folder
The npm package ships pre-built: every build-time library is inlined, so npm install genosdb adds zero transitive dependencies. The practical consequence of runtime module resolution is a single rule for bundlers: GenosDB resolves its modules relative to itself, so keep its dist/ folder intact in your build output (with Vite, optimizeDeps.exclude: ['genosdb'] for the dev server). The bundler configuration guide covers Vite, Webpack, Bun and CDN usage.
Why this matters in a P2P database
Modularity here is not a bundle-size vanity metric. In a distributed system, every byte of the engine runs on every peer, and every capability is attack surface on every peer. A lean core means less to audit, less to trust, and less to break — and capabilities loaded by explicit request mean each deployment carries exactly the risk it chose. That is the same philosophy behind GenosDB's zero-trust security model: nothing is granted by default, including code.
Top comments (0)