Imagine building a real-time application where users can register with biometrics, publish secure data, share editing rights, and visualize geolocation on a map — all without deploying a backend server.In this tutorial, we are going to build dProp, a decentralized real estate marketplace. We will use GenosDB, a P2P database that runs entirely in the browser, to handle authentication, data storage, and real-time synchronization.By the end of this guide, you will have a single-file HTML application with:- Real-time updates (Reactive UI).- Biometric Authentication (WebAuthn).- Granular Access Control (ACLs) for collaborative editing.- Dark Mode support.
The Stack
- Frontend: Vanilla JS + HTML5.- Styling: TailwindCSS (via CDN).- Maps: Leaflet.js.- DB: GenosDB (P2P, Client-side).
Step 1: The Setup
We start with a basic HTML5 structure. Because GenosDB is modular and efficient, we can build this entire app in a single file using ES modules.HTML
import { gdb } from "https://cdn.jsdelivr.net/npm/genosdb@latest/dist/index.min.js"; // Application logic will go here
We add a simple Dark Mode toggle script that checks localStorage or system preferences to apply the .dark class to the HTML tag.
Step 2: Initializing the P2P Database
To make our app “Real-time” and “Secure,” we need to initialize GenosDB with specific modules enabled.JavaScript
const APP_ROLES = { admin: { can: ["deleteAny"], inherits: ["user"] }, user: { can: ["write", "link"], inherits: ["guest"] }, guest: { can: ["read"] }};async function initApp() { // Initialize GenosDB db = await gdb("dprop-v2", { rtc: true, // Enables WebRTC for P2P sync sm: { superAdmins: ["0x..."], // Required for boot customRoles: APP_ROLES, acls: true // Enables Node-Level Permissions } }); // Reactive Auth Listener db.sm.setSecurityStateChangeCallback(updateAuthUI);}
What’s happening here?- rtc: true: Activates the P2P layer so browsers can exchange data directly.- sm** (Security Manager): Activates the cryptographic identity system. Users are identified by Ethereum addresses, not database IDs.- **acls: true: This is crucial. It enables Access Control Lists, allowing us to define exactly who can edit a specific property.
Step 3: Biometric Authentication (No Passwords!)
Forget storing hashed passwords. We use GenosDB’s built-in Identity Management to generate a cryptographic wallet and protect it with WebAuthn (FaceID, TouchID).JavaScript
// 1. Generate a new Identity (Mnemonic based)window.generateIdentity = async () => { const id = await db.sm.startNewUserRegistration(); // Display id.mnemonic to the user securely};// 2. Protect it with Biometricswindow.protectIdentity = async () => { await db.sm.protectCurrentIdentityWithWebAuthn(); // The private key is now encrypted with the device's hardware security module};// 3. Loginwindow.loginWebAuthn = async () => { await db.sm.loginCurrentUserWithWebAuthn();};
When a user logs in, db.sm signs every database operation they perform. This guarantees data authenticity without a server verifying sessions.
Step 4: Publishing Secure Data with ACLs
When a user publishes a house, we don’t just dump JSON into the DB. We use ACLs (Access Control Lists) to ensure only the owner can edit it later.JavaScript
const propertyData = { type: 'Property', title: 'Luxury Villa', price: 500000, owner: currentUserAddress, // Stored for UI logic status: 'available'};// Save with ACL protectionawait db.sm.acls.set(propertyData);
By using db.sm.acls.set, the node is created, and the creator is automatically assigned Owner privileges (Read, Write, Delete). Any attempt by another peer to modify this node will be rejected by the P2P validation middleware.
Step 5: The “Magic” Real-Time Stream
This is the heart of dProp. We want the UI to update instantly when anyone changes a property status or adds a listing. We use db.map() in realtime mode.JavaScript
async function performSearch() { // 1. Define Query const query = { type: 'Property', status: { $ne: 'deleted' } };// 2. Subscribe to changes const { unsubscribe } = await db.map({ query: query, realtime: true, // { // This callback fires on 'initial', 'added', 'updated', or 'removed' handleRealtimeUpdate(id, value, action); });}
How it works:- realtime: true: Keeps the connection open.- action: Tells us if a node was added, updated, or removed.- Cursor Pagination: We can use $after to implement "Load More" functionality without re-fetching the whole list.
Step 6: Collaborative Editing (Sharing Access)
A unique feature of dProp is allowing owners to share write access with other users (e.g., a real estate agent).JavaScript
window.confirmShare = async () => { const propertyId = document.getElementById('share-node-id').value; const collaboratorAddress = document.getElementById('share-address').value;// Grant 'write' permission to the specific address await db.sm.acls.grant(propertyId, collaboratorAddress, 'write'); // Update metadata so the UI knows this person is a collaborator const { result: node } = await db.get(propertyId); node.value.collaborators[collaboratorAddress] = 'write'; await db.sm.acls.set(node.value, propertyId);};
Now, the collaborator’s browser will validate that they have permission to edit the property, and the network will accept their signed updates.
Step 7: Atomic UI Updates
To ensure the app feels like a native 60fps experience, we don’t reload the page. We perform surgical DOM updates in our callback.JavaScript
function handleRealtimeUpdate(id, value, action) { const existingCard = document.getElementById(`card-${id}`); const newCard = createCardHTML({ id, ...value }); // Generate HTML string if (action === 'removed') { existingCard?.remove(); } else if (existingCard) { // Atomic Replacement: Update status/price instantly existingCard.replaceWith(newCard); } else { // Append new item grid.appendChild(newCard); } // Update Map Marker concurrently updateMapMarker({ id, ...value });}
This logic handles everything: initial load, price changes, status updates (Available -> Sold), and deletion.
What You Built
We just built a Full-Stack application using only frontend code.- Database? Local & P2P (GenosDB).- Auth? Cryptographic & Biometric (Security Manager).- API? None (Direct Peer Sync).This architecture drastically reduces infrastructure costs and increases data resilience. dProp isn’t just a demo; it’s a glimpse into the future of serverless, decentralized web applications.
Resources
- GenosDB Documentation- Live Demo- Full Source Code (GitHub)
This article is part of the official documentation of GenosDB (GDB).
GenosDB is a distributed, modular, peer-to-peer graph database built with a Zero-Trust Security Model, created by Esteban Fuster Pozzi (estebanrfp).
📄 Whitepaper | overview of GenosDB design and architecture
🛠 Roadmap | planned features and future updates
💡 Examples | code snippets and usage demos
📖 Documentation | full reference guide
🔍 API Reference | detailed API methods
📚 Wiki | additional notes and guides
💬 GitHub Discussions | community questions and feedback
🗂 Repository | Minified production-ready files
📦 Install via npm | quick setup instructions
Top comments (0)