# Build a Serverless, P2P Real Estate Application in One File with GenosDB

---
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 serverless, client-side 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 client-side 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'        ({ id, value, action }) => 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](https://github.com/estebanrfp/gdb)- [Live Demo](https://estebanrfp.github.io/dProp/)- [Full Source Code (GitHub)](https://github.com/estebanrfp/dProp)
---

>

---

> **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](https://github.com/estebanrfp))**.

📄 [Whitepaper](https://github.com/estebanrfp/gdb/blob/main/WHITEPAPER.md) | overview of GenosDB design and architecture

🛠 [Roadmap](https://github.com/estebanrfp/gdb/blob/main/ROADMAP.md) | planned features and future updates

💡 [Examples](https://github.com/estebanrfp/gdb/blob/main/docs/genosdb-examples.md) | code snippets and usage demos

📖 [Documentation](https://github.com/estebanrfp/gdb/blob/main/docs/index.md) | full reference guide

🔍 [API Reference](https://github.com/estebanrfp/gdb/blob/main/docs/genosdb-api-reference.md) | detailed API methods

📚 [Wiki](https://github.com/estebanrfp/gdb/wiki) | additional notes and guides

💬 [GitHub Discussions](https://github.com/estebanrfp/gdb/discussions) | community questions and feedback

🗂 [Repository](https://github.com/estebanrfp/gdb) | Minified production-ready files

📦 [Install via npm](https://www.npmjs.com/package/genosdb) | quick setup instructions

🌐 [Website](https://estebanrfp.com/) | [GitHub](https://github.com/estebanrfp) | [LinkedIn](https://www.linkedin.com/in/estebanrfp/)
