Data & Holons — The Universal Data Model
Holons are OASIS' universal data objects — structured records that replicate across multiple storage providers automatically. Store game state, user content, app config and large files without locking yourself into a single database.
What you'll learn
- What Holons are and how they differ from traditional database records
- Save, load, update and delete Holons via the Data API
- Query Holons by metadata, type and custom fields
- Store and retrieve large files with HyperDrive
- Search across all OASIS data
- Understand multi-provider replication and auto-failover
What is a Holon?
A Holon is OASIS' fundamental data unit — a self-describing, self-contained record that knows its own context. Think of it as a document (like MongoDB) with some extra superpowers:
- Provider-agnostic — the same Holon can be stored in MongoDB, Neo4j, Holochain, IPFS or any OASIS provider. Your app doesn't care which.
- Auto-replicated — configure multiple providers and OASIS writes to all of them. If one goes down, reads fall over to the next automatically.
- Avatar-linked — every Holon has an
avatarIdthat ties it to its creator, enabling per-user data isolation out of the box. - Versioned — Holons track creation and modification dates, and some providers support full history.
A raw Holon is a generic key-value data bag. The OASIS platform also defines typed subtypes — Avatar, Quest, Mission, CelestialBody, InventoryItem — all of which extend Holon. In Module 7 we'll use the typed STAR Holons for game worlds. For your own app data, the generic Holon API is what you want.
Saving a Holon
import { oasis } from './oasis.js'; const { avatarId } = oasis.auth.getSession(); // Save any JSON-serialisable object as a Holon const { result: holon } = await oasis.data.saveHolon({ name: 'PlayerGameState', description: 'Saved game state for Ada in Campaign Mode', avatarId, metaData: { // Any key-value pairs — fully flexible level: 12, currentZone: 'Elven Forest', checkpointId: 'elf-forest-cp3', inventory: ['sword-of-light', 'health-potion-sm'], lastSaved: new Date().toISOString() } }); console.log('Saved Holon ID:', holon.id); // GUID — store this for later
Loading a Holon
// Load by GUID const { result: holon } = await oasis.data.loadHolon({ id: holonId }); console.log(holon.name); // 'PlayerGameState' console.log(holon.metaData.level); // 12 console.log(holon.metaData.currentZone); // 'Elven Forest' console.log(holon.createdDate); // ISO timestamp console.log(holon.modifiedDate); // ISO timestamp
Querying Holons
Load all Holons for an avatar, or filter by metadata values to find specific records:
// All Holons belonging to the logged-in avatar const { result: myHolons } = await oasis.data.loadAllHolonsForAvatar({ avatarId }); // Filter by name const gameStates = myHolons.filter(h => h.name === 'PlayerGameState'); // Load Holons matching specific metadata (server-side filter) const { result: checkpoint3 } = await oasis.data.loadHolonsByMetaData({ metaData: { checkpointId: 'elf-forest-cp3' } }); // Load all Holons of a specific type across all avatars const { result: allStates } = await oasis.data.loadAllHolons({ holonType: 'PlayerGameState' });
Updating a Holon
const { result: updated } = await oasis.data.saveHolon({ id: holonId, // include the ID to UPDATE (omit to INSERT) name: 'PlayerGameState', avatarId, metaData: { level: 13, // bumped up currentZone: 'Dark Tower', checkpointId: 'dark-tower-cp1', lastSaved: new Date().toISOString() } });
The saveHolon method handles both. Pass id to update an existing record; omit it (or pass a zero/empty GUID) to create a new one. The OASIS API detects which operation is needed automatically.
Deleting a Holon
const result = await oasis.data.deleteHolon({ id: holonId }); if (!result.isError) console.log('Holon deleted.');
HyperDrive — Large File Storage
HyperDrive is OASIS' distributed file system layer — built on top of Holochain's Hyperdrive and IPFS — for storing large files (3D assets, videos, audio, game bundles) that don't belong in a document store.
// Upload a file to HyperDrive const { result: drive } = await oasis.hyperDrive.uploadFile({ fileName: 'sword-of-light.glb', fileContent: fileBuffer, // Buffer or Uint8Array mimeType: 'model/gltf-binary', avatarId }); console.log('HyperDrive URI:', drive.uri); // hyper://... or ipfs://... console.log('CDN URL:', drive.cdnUrl); // https:// accessible URL // Download a file const { result: file } = await oasis.hyperDrive.downloadFile({ uri: drive.uri }); // List all files for an avatar const { result: files } = await oasis.hyperDrive.listFiles({ avatarId }); files.forEach(f => console.log(f.fileName, f.size, f.uri));
Searching Across All Data
The OASIS Search API spans all data types — Holons, Avatars, OApps, NFTs and map content — from a single endpoint:
const { result: hits } = await oasis.search.search({ searchQuery: 'sword', searchParams: { searchAvatars: false, searchHolons: true, searchOAPPs: true, searchNFTs: true, searchMapPoints: false, maxResults: 20 } }); hits.forEach(hit => { console.log(`[${hit.type}] ${hit.name} — score: ${hit.relevanceScore}`); });
A mobile game stores each player's save state as a Holon. When the player switches from iOS to Android (or to the PC version), their save loads instantly — no account linking, no platform-specific cloud APIs. The same avatar ID fetches the same Holon from whichever provider is fastest geographically. This is also fully offline-capable: providers can sync when connectivity returns.
Choosing a Storage Provider
You can override the default provider per-request to control where a Holon is stored:
// Store this Holon specifically on MongoDB const result = await oasis.data.saveHolon({ name: 'HighScores', metaData: { score: 99999 }, providerType: 'MongoDBOASIS', // override global default setGlobally: false // only for this request }); // Available providerType values: // 'MongoDBOASIS', 'HoloOASIS', 'IPFSOASIS', 'Neo4jOASIS', // 'SQLLiteDBOASIS', 'SolanaOASIS', 'EthereumOASIS', 'ThreeFoldOASIS'
Data API Quick Reference
- oasis.data.saveHolon({id?, name, metaData, avatarId, ...})Create or update a Holon
- oasis.data.loadHolon({id})Load a single Holon by GUID
- oasis.data.loadAllHolons({holonType?})Load all Holons, optionally filtered by type
- oasis.data.loadAllHolonsForAvatar({avatarId})Load all Holons for a specific avatar
- oasis.data.loadHolonsByMetaData({metaData})Filter Holons by metadata key-values
- oasis.data.deleteHolon({id})Delete a Holon
- oasis.hyperDrive.uploadFile({fileName, fileContent, mimeType, avatarId})Upload a file to distributed storage
- oasis.hyperDrive.downloadFile({uri})Download a file by its HyperDrive URI
- oasis.hyperDrive.listFiles({avatarId})List all files for an avatar
- oasis.search.search({searchQuery, searchParams})Full-text search across all data types