Sobamail in 5 Minutes¶
This page gives you the mental model behind Sobamail in about five minutes. Once it clicks, the Concepts page and the Instantiating Your First App tutorial will make a lot more sense.
The one big idea¶
Your mailbox is your database, and apps live inside it.
Sobamail is a normal email system (SMTP, IMAP, POP3, webmail) with an application platform built on top. Every Sobamail user has one mailbox, identified by their email address, and that mailbox is their one and only data store. The apps that run inside Sobamail keep their data in their own folders, alongside the user's email archive.
Five things that make Sobamail tick¶
-
Apps are reactive. A Sobamail app has no server you call. It only wakes up to handle an incoming event, and every event is ultimately an email message. Click a button in an app and you are really sending a barebones email to the backend.
-
State is a log of mutations. Apps don't edit rows in place. They append mutations (think "add this", "delete that") to a log, and the current state is what you get after replaying that log. Mutations are mostly
INSERTandDELETE; the rareUPDATEis limited to order-independent changes like adding to a counter. Under the hood it's SQLite. -
Everything replicates over email. Your mailbox has several replicas — one per device, plus the Sobamail servers. Apps stay in sync by shipping their mutations between replicas as ordinary (if specially formatted) emails. Come online and your replicas catch each other up automatically in the background.
-
An app is two pieces. A Mutator (the backend: a JavaScript module that reacts to events and changes state) and a UI (a regular HTML/CSS/JS frontend). The UI never touches the database directly — it talks to the Mutator over a small RPC interface.
-
Dev mode is frictionless; deployment freezes the app. While you build, your app runs as a single local instance with replication turned off. When you deploy, every component is hashed and frozen so that all replicas provably run the exact same code. Then you instantiate it to start using it for real. The instance id is the name of the folder where that instance's data lives, and an app can have as many instances as you like, either private to you or shared with other Sobamail users.
What a backend looks like¶
Every Mutator is a JavaScript class with a process() method — the single
entry point the runtime calls for each incoming event, much like main() in C:
import "soba://computer/R2"; // pick the runtime ("computer") version
export default class Mutator {
static id = "myapp.alice.user.app.example.com";
static name = "My First App";
static version = "1.0.0.0";
static objects = new Map([ /* events this app cares about */ ]);
constructor() {
// define your tables, run sanity checks
}
process(message, metadata) {
// react to the incoming event
}
}
That's the whole shape of a Sobamail backend: declare which events you care
about, set up your tables in the constructor, and handle events in process().
How a click flows through the system¶
- The UI encodes a small object and sends it to the Mutator.
- The Mutator's
process()runs, validates it, and appends a mutation (or not). - The mutation updates the local SQLite state...
- ...and replicates to your other devices as an email, where the same Mutator replays it to arrive at the same state.
Next steps¶
- Read Concepts for the full picture — instances, object keys, conflict handling, and how replication stays convergent.
- Build something with the Instantiating Your First App tutorial, then the collaborative counter.