Data Storage
This page explains how CoCube stores your data, how sync and collaboration work, and how CoCube protects your privacy. CoCube is built from the ground up as a local-first application. Your data lives on your device by default and only leaves when you choose to share it.
Why Local-First?
Most web applications store your data on someone else's server and send it to you when you need it. If the service goes down, gets acquired, changes pricing, or shuts down, your data goes with it.
CoCube takes a different approach. Your data is stored on your device first. The application works with or without an internet connection. Syncing to a server is optional and happens on your terms. You can keep private work private while collaborating where needed.
| CoCube | Traditional cloud-based tools | |
|---|---|---|
| Default storage | On your device | On the company's servers |
| Account required | No (for local work) | Yes, always |
| Offline support | Full read and write | Limited or no offline editing |
| Data sharing | Opt-in | All data on their servers by default |
| Collaboration | Opt-in | Always server-mediated |
| Data portability | Data is already on your machine | Requires export tooling |
This model also means CoCube has a fundamentally different relationship with your data compared to typical software-as-a-service products. CoCube does not need to read your data to serve you ads or train models on your content. Your data is yours.
If CoCube's servers go offline, your local data and the tools you have created are unaffected. You keep working. When the servers come back online, your changes will sync automatically. Even if CoCube ceased to exist, your data would still be on your machine in an open format (Loro). You would never lose your work.
What Is a Datum?
A datum is the fundamental unit of storage in CoCube. Every datum stores a single typed value (text, a number, a color, an array, a map, or a full component definition) and has a unique identifier (UUID) that distinguishes it from every other datum in the system.
Datums are reactive. When you update a datum, every expression that references it updates immediately. A single change can propagate through many components at once, updating colors, text, layouts, and behavior across your entire workspace.
Datums are also the unit of collaboration. When you share a datum, collaborators receive and contribute changes to that exact datum, and those changes flow reactively through any component that uses it.
When datums are updated
Datums are updated when you interact with a component (clicking a button, typing text, dragging a slider), when a collaborator edits a shared datum, or when changes sync from another device.
When a datum is updated, the change is applied in memory, persisted to the local SQLite database, and (if synced) sent to CoCube's servers for forwarding to collaborators. Every expression referencing the datum is re-evaluated, and the UI updates. The in-memory and UI updates happen almost instantly. Persistence happens in the background. Network sync depends on connectivity.
Datums as a reactive database
Think of CoCube as a local-first, reactive database. Each datum is like a row, but instead of being locked behind SQL queries, datums are live. Any component can reference any datum, and when the datum changes, the component's cells that reference that datum will immediately update. Change a color datum, and every component using that color updates. Update a text datum, and every place that text appears reflects the new content.
Components are datums
Components themselves are datums. When you create a component, it is stored as a datum with a Component type. The component's cells, layout, colors, subcomponents, event handlers, and all other properties are part of that datum's data.
This means everything that applies to datums also applies to components. Components are persisted locally, can be synced to the server, shared with collaborators, and made public. A workspace, which is a collection of components, is itself a datum composed of references to other datums. Datums referencing other datums are how CoCube builds up complex, interconnected visual tools from simple building blocks.
How components update datums
Components are not just passive displays of data. They can create, read, modify, and delete datums through event handlers. For example, a text editor writes its content to a text datum. A to-do list modifies an array datum when you check off an item.
This bidirectional flow (datums feed into components, components modify datums) is what allows you to build complex tools. Because datums are reactive, modifications made by one component immediately update every other component referencing the same datum, whether the modification comes from your own interaction, a collaborator's edit, or a sync from another device.
Browser Storage
CoCube stores your datums locally in a SQLite database inside your browser. This database uses the browser's Origin Private File System (OPFS), a modern web standard that gives web applications a private, persistent storage area scoped to the browser's origin. OPFS is not accessible to other websites, browser profiles, or applications on your machine.
The SQLite database runs in a Web Worker (a background thread), so reads and writes never block the user interface. Each datum is stored as a row containing the datum's UUID and its data, encoded as a binary Loro blob.
CoCube maintains datums in two layers: all active datums are kept in memory for fast reads, and changes are also persisted to the SQLite database for durability. When you open CoCube, datums are loaded from the database into memory. From that point on, the in-memory copies are the primary working copies, and the database acts as a durable backup kept in sync with every change.
When OPFS is available, the database is fully persisted across browser sessions. If OPFS is not available (some older browsers), CoCube falls back to a transient in-memory database. This should not happen with any modern browsers.
Technical detail: The local database file is stored at within the OPFS virtual file system. CoCube uses a WebAssembly-compiled SQLite that runs directly in the browser. Database operations run in a Web Worker separate from the main UI thread.
Accessing local data without an account
CoCube does not require an account for local work. You can create datums, build components, and use them without ever signing in. All users on the same browser profile can access and modify all local datums, which lets you use CoCube without creating an account.
If you sign in and sync a datum to the server, you establish yourself as its owner. From that point on, only you can share that datum with collaborators, though local copies remain accessible on any device where they were previously stored. On shared devices, consider using a separate browser profile to isolate your data.
Local vs Synced Datums
Datums in CoCube exist in one of three states.
Local datums
A local datum exists only on your device, stored in the browser's local SQLite database and never sent to CoCube's servers. Local datums do not require an account or internet connection, cannot be accessed from other devices, and cannot be collaborated on. Most datums start as local. You can work with them indefinitely without syncing.
Synced datums
A synced datum is stored locally and also synced with CoCube's servers, enabling multi-device access and collaboration. Synced datums have an owner (the user who first synced them) and require a paid plan.
When you sync a datum, changes you make locally are sent to the server, and changes from the server (from your other devices or collaborators) are sent to your local copy. This happens in real time when online and catches up automatically when you reconnect. Syncing uses Loro's CRDT protocol, so changes merge correctly even when multiple people edit simultaneously or someone goes offline for extended periods.
Syncing does not remove your local copy. A synced datum is always stored locally as well. The server copy enables multi-device access and collaboration, but if you lose internet, you still have full access locally.
On the server side, your datum is stored in PostgreSQL as a binary Loro blob, along with metadata about ownership, access, visibility, and creation date.
Public datums
A public datum is a synced datum marked as publicly accessible. Anyone with the datum's URL can view and use it without a CoCube account. Public datums are read-only for viewers who are not the owner or a collaborator.
Making a datum public simply adds a flag telling CoCube's servers to serve it to anyone who requests it. Only the owner can toggle this. Because components are datums, making a component public is as simple as toggling the flag. Viewers interact with the component just as they would on your workspace, except they cannot modify its definition.
Transitioning between states
- Local to Synced: Sign in, then change the datum's status to synced. You become the owner.
- Synced to Public: Use the datum menu to mark the synced datum as public.
- Public to Synced (private): Toggle the public flag off. Existing collaborators retain access, but anonymous viewers can no longer access it.
You cannot move a synced datum back to local-only. Once synced, the server connection is maintained because collaborators may depend on it.
How to tell a datum's state
In the database explorer, each datumn shows indicators next to its name:
- S means the datum is synced with CoCube's Server
- L means the datum is persisted Locally
A datum can show both S and L, just L, or just S (synced but not yet persisted locally, which can happen briefly during initial sync from another device).
Datum Ownership
When a datum is synced to CoCube's servers, it has an owner: the user who first synced it. Ownership is claimed first-come, first-served. If another user has a local copy and tries to sync it, their request is denied because the datum already has an owner.
The owner has full control: they can modify the datum, add or remove collaborators, toggle public visibility, and delete the datum from the server.
Ownership is a server-side concept. Locally, all datums are accessible to anyone using the same browser profile regardless of server ownership. This distinction exists because CoCube's local-first model prioritizes availability. Server-side ownership is enforced when you interact with CoCube's servers (syncing, sharing, publishing), not when you access datums locally.
When the owner deletes a synced datum it is removed from CoCubes servers (only the datums unique id is kept, as it is considered "used"), and removed from the local database.
Adding and Removing Collaborators
Collaborators are other users with read and write access to your synced datum.
Adding a collaborator
To add a collaborator, open a synced datum and use the top menu to add them by email. Only the owner can add collaborators. When you add a collaborator, the server records their access. The next time they sign in, the datum appears in their datums explorer, syncs to their device, and from then on changes sync in real time.
Changes merge using Loro's CRDT merging algorithm. Multiple collaborators can edit simultaneously without conflicts, and offline changes merge correctly on reconnect.
Currently, each datum supports a maximum of two total collaborators: the owner plus one editor. This limit may increase in future updates. Collaboration features require a paid plan.
Collaborator permissions
Collaborators can read and write to the datum. They cannot add or remove other collaborators, change visibility, delete the datum, or transfer ownership.
When a collaborator joins, they receive a full copy of the datum. All copies (owner's device, each collaborator's device, and the server) converge to the same state through Loro's sync protocol. Every change is preserved regardless of who made it or when.
Removing a collaborator
Removing collaborators is not yet implemented. This feature is planned for a future update.
How Datum Sync Works
Sync mechanism
CoCube uses Loro, a conflict-free replicated data type (CRDT) library. When you edit a synced datum, Loro tracks the change as a small incremental update sent to CoCube's servers over an encrypted WebSocket connection. The server stores the merged datum and forwards the update to connected collaborators.
When two people edit simultaneously, Loro guarantees both changes are preserved and all devices converge to the same result. There is no "last write wins" that silently discards changes.
Unlike operational transformation (OT), which requires a central server to coordinate the order of operations, CRDTs do not need a central coordinator. Each device independently applies and merges changes. The server is a convenience for routing messages, not a required authority. This is why offline editing works fully: your device does not need the server's permission to merge changes.
Sync architecture
- Local edit: You modify a datum. The change is applied to the in-memory Loro datum and persisted to the local SQLite database.
- Sync message: Loro generates a compact sync message.
- Transport: The message is sent to CoCube's server over WebSocket.
- Server merge: The server applies the message to its copy and persists to PostgreSQL.
- Broadcast: The server sends the message to all other connected collaborators.
- Remote apply: Each collaborator's client applies the message and persists the result.
This process happens in milliseconds when all parties are online.
Datum history
Loro preserves the complete history of every change made to a datum. While CoCube does not currently expose a full version history UI, the change history is preserved in the Loro binary blob stored in both the local and server databases.
Data Security
CoCube's local-first architecture is itself a security measure. Data that never leaves your device cannot be intercepted, leaked, or misused.
Local datums are stored in OPFS, which is scoped to CoCube's origin, isolated per browser profile, and not accessible to other applications. The primary risk is someone gaining access to your browser profile. Standard device security practices (screen lock, separate user accounts) protect against this.
For synced datums:
- Encrypted transport: All communication uses HTTPS/WSS (TLS). Data cannot be intercepted in transit.
- Access control: The server verifies ownership and collaborator permissions for every request.
- Soft-delete: Deleted datums are not immediately purged, preserving an audit trail.
- Session security: Secure, SameSite-strict cookies prevent cross-site request forgery.
Current limitations
CoCube does not yet implement encryption at rest for synced datums. Datums on CoCube's servers are stored as binary Loro blobs without an additional encryption layer. End-to-end encryption is on the roadmap. When implemented, even CoCube's servers will not be able to read your datum contents. In the meantime, keep highly sensitive data in local-only datums.
Privacy is not an afterthought in CoCube. It is the foundation of the architecture. The local-first model means privacy is the default. Sharing is the exception, and it is always your choice.
Summary
- Datums are persisted, typed, reactive values. They are the building blocks of everything in CoCube. Components are datums.
- Local datums live on your device and never touch CoCube's servers. No account needed.
- Synced datums are stored locally and on CoCube's servers, enabling multi-device access and collaboration.
- Public datums are synced datums visible to anyone with the link.
- Browser storage uses SQLite in the browser's OPFS for efficient, persistent, private local storage.
- Collaboration gives real-time read and write access. Changes merge automatically through CRDTs.
- Sync uses Loro CRDTs, providing conflict-free merging even after offline edits.
- Privacy is the default. CoCube is local-first. Your data is yours.