` standing in for a menu is rejected — it loses the shared keyboard model, anchoring, and accessibility.
## App chrome
[Section titled “App chrome”](#app-chrome)
The app theme stylesheet owns the header. Put this skeleton in every app and don’t re-declare its CSS:
```tsx
```
The header is a fixed-height glass bar with platform-correct padding (macOS traffic lights, Windows controls) applied for you. Put `app-header__title` on your title element — don’t build your own title face. The overflow `⋯` menu, when you have one, is always the **last** element in `app-header__right`.
## Internationalization
[Section titled “Internationalization”](#internationalization)
Every user-visible string wraps in a translation call. Apps use the lightweight `createT` from `@brainstorm/sdk/i18n` (which does `{name}` interpolation only — no ICU). For plurals, use the shared `plural(t, count, "key.one", "key.other")` helper rather than a `count === 1 ?` branch in component code. Add new string ids to your app’s catalog; never put bare text in JSX.
## Next
[Section titled “Next”](#next)
* [Working with data](/build/working-with-data/) — the `entities`, `storage`, `intents`, and document APIs in practice.
* [Recipes & anti-patterns](/build/recipes/) — the conventions that keep an app consistent with the platform.
# Working with data
> Read and write objects, sync collaborative documents, store app-private state, and integrate with other apps through intents.
An app’s real work is data: reading and writing [objects](/concepts/objects/), syncing the documents behind them, keeping a little private state, and handing work to other apps. Brainstorm gives you four distinct stores, each for a different job — using the right one is most of getting data handling right.
| Use | For |
| ------------------- | ------------------------------------------------------------------------------- |
| **Entities** | Shared, typed, synced objects — your app’s real content. |
| **Documents (Yjs)** | The collaborative body of an object — rich text, structured fields edited live. |
| **Storage** | App-private key/value state and uploaded files. |
| **Settings** | Per-device UI state that should *not* sync (last-opened tab, panel widths). |
## Objects: the entities service
[Section titled “Objects: the entities service”](#objects-the-entities-service)
Objects are typed records in the vault. Create, read, update, delete, and query them through `services.entities`:
```ts
const bs = window.brainstorm;
// create — returns the new object
const note = await bs.services.entities.create(
"io.brainstorm.notes/Note/v1",
{ title: "Untitled", body: "", createdAt: Date.now(), updatedAt: Date.now() },
);
// read / update / delete by id
const fetched = await bs.services.entities.get(note.id);
await bs.services.entities.update(note.id, { title: "Renamed" });
await bs.services.entities.delete(note.id);
// query — by type, predicate, text, with a limit
const recent = await bs.services.entities.query({
type: "io.brainstorm.notes/Note/v1",
limit: 50,
});
```
Each of these is gated by the matching [capability](/build/capabilities/): `entities.read:
` to read, `entities.write:` to create, update, or delete.
For anything that renders a list, prefer the **live** hook over one-shot `query` — it subscribes so the UI updates when objects change anywhere:
```tsx
import { useVaultEntities } from "@brainstorm/react-yjs";
const { entities } = useVaultEntities(window.brainstorm.services.vaultEntities);
const notes = entities.filter((e) => e.type === "io.brainstorm.notes/Note/v1");
```
## Documents: collaborative bodies
[Section titled “Documents: collaborative bodies”](#documents-collaborative-bodies)
An object’s *body* — rich text, or any field edited live and synced across devices and collaborators — lives in a Yjs document. Read and edit it through `@brainstorm/react-yjs` rather than the low-level sync calls:
```tsx
import { useYDoc, useYMap, useYText } from "@brainstorm/react-yjs";
const doc = useYDoc(noteId); // the object's collaborative doc
const props = useYMap(doc, "properties"); // structured fields
const body = useYText(doc, "body"); // rich-text body
```
Edits made here merge cleanly with edits from other devices and users — that’s the CRDT layer doing its job. You mutate the shared types; the changes propagate. (The runtime exposes lower-level `entities.loadDoc` / `applyDoc` for advanced cases, but most apps never touch them.)
## App-private storage
[Section titled “App-private storage”](#app-private-storage)
For state that’s yours alone — caches, drafts, app preferences that *should* travel with the vault — use `services.storage`, gated by the default-granted `storage.kv`:
```ts
await bs.services.storage.put("draft:" + id, text);
const draft = await bs.services.storage.get("draft:" + id);
const keys = await bs.services.storage.list("draft:");
await bs.services.storage.delete("draft:" + id);
```
To bring a file into the vault’s content-addressed store and get a URL back:
```ts
const { url } = await bs.services.storage.uploadFile(name, bytes, mime);
```
## Per-device settings
[Section titled “Per-device settings”](#per-device-settings)
State that should **not** sync — which tab was open, a panel’s width on this screen — goes in `services.settings`, not storage:
```ts
await bs.services.settings.put("sidebar.width", 280);
const width = await bs.services.settings.get("sidebar.width");
```
The distinction matters: put device-local view state in `settings` and it won’t fight across machines; put real content there and it won’t follow the user. When unsure, ask “should this be the same on my laptop and my phone?” — yes means an entity or storage, no means settings.
## Files
[Section titled “Files”](#files)
Your app never sees filesystem paths. It asks the user to pick a file (or a save target), gets an opaque handle, and reads or writes through it:
```ts
const handle = await bs.services.files.requestOpen({ mime: ["text/plain"] });
const bytes = await bs.services.files.read(handle);
// …
await bs.services.files.write(handle, newBytes);
```
Picking requires a user gesture; writing requires `files.write`. When your app is launched *as an opener* for a file (via a manifest [opener](/build/the-manifest/#registrations--plugging-into-the-shell)), the file arrives in your `launch` context.
## Talking to other apps
[Section titled “Talking to other apps”](#talking-to-other-apps)
Apps compose through **intents** — structured requests dispatched by verb, handled by whichever app registered for it. Your app dispatches without knowing or naming the handler:
```ts
await bs.services.intents.dispatch({
verb: "open",
payload: { entityId: someId },
source: bs.app.id,
});
```
Dispatching `open` is default-granted; other verbs are gated by `intents.dispatch:`. To *receive* intents, register a handler in your [manifest](/build/the-manifest/#registrations--plugging-into-the-shell) and listen:
```ts
bs.on("intent", (intent) => {
if (intent.verb === "open") openObject(intent.payload.entityId);
});
```
This is how the whole workspace stays connected: a note links to a task, clicking it dispatches `open`, and Tasks handles it — no app hard-codes another.
## Next
[Section titled “Next”](#next)
* [Recipes & anti-patterns](/build/recipes/) — patterns to copy and mistakes to avoid.
* [SDK & runtime](/build/the-sdk/) — the full service surface and component library.
# Your first app
> Scaffold a Brainstorm app, run it in the shell, and see a live list of your own objects.
This walkthrough scaffolds a working app, runs it in the shell, and shows it rendering a live list of objects from your vault. It takes about ten minutes.
Note
Apps are currently built inside the Brainstorm shell source tree — the same place the first-party apps live. A standalone SDK package and a third-party publishing flow are on the roadmap; until then, “building an app” means working in the shell repo. The app model and SDK shown here are stable and carry forward unchanged.
## Scaffold
[Section titled “Scaffold”](#scaffold)
From the shell repo, the scaffold generates a complete, compliant React app:
```sh
bun run new-app field-notes "Field Notes"
```
The first argument is the app id (kebab-case); the second is the display name. You get:
```plaintext
apps/field-notes/
├── manifest.json # the app declaration
├── package.json # deps: @brainstorm/sdk, @brainstorm/react-yjs, react
├── tsconfig.json
├── vite.config.ts
├── icon.svg # generated from the app's initials
└── src/
├── index.html # entry document (ships a strict Content-Security-Policy)
├── main.tsx # React root mount
├── app.tsx # your root component — a live entity list
├── runtime.ts # type-safe accessor for window.brainstorm
└── styles.css # app styles, themed from the SDK
```
The scaffold is deliberately not a blank page — it mounts a real `useVaultEntities` list and the standard header chrome, so you start from a compliant app rather than retrofitting the conventions later.
## What the scaffold gives you
[Section titled “What the scaffold gives you”](#what-the-scaffold-gives-you)
**`manifest.json`** declares the app and the one object type it owns:
```json
{
"id": "io.brainstorm.field-notes",
"name": "Field Notes",
"version": "0.1.0",
"sdk": "1",
"entry": "dist/index.html",
"icon": "icon.svg",
"capabilities": [
"storage.kv",
"entities.read:*",
"entities.write:io.brainstorm.field-notes/Item/v1"
],
"registrations": {
"entityTypes": [
{
"id": "io.brainstorm.field-notes/Item/v1",
"schema": {
"type": "object",
"required": ["id", "title", "createdAt", "updatedAt"]
}
}
]
}
}
```
See [The manifest](/build/the-manifest/) for every field and [Capabilities](/build/capabilities/) for what those capability strings mean.
**`src/main.tsx`** mounts React. Two imports are mandatory and come first — the app-theme stylesheet (which carries the shared `.app-header` chrome and theme tokens) and the menu host:
```tsx
import "@brainstorm/sdk/app-theme.css";
import { mountMenuHost } from "@brainstorm/sdk/menus";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { FieldNotesApp } from "./app";
import "./styles.css";
const root = document.getElementById("root");
if (!root) throw new Error("field-notes: #root not found");
mountMenuHost();
createRoot(root).render(
,
);
```
**`src/app.tsx`** is your UI. The scaffold renders a live, reactive list of your own object type:
```tsx
import { useVaultEntities } from "@brainstorm/react-yjs";
import { useMemo } from "react";
import { getBrainstorm } from "./runtime";
const APP_TYPE = "io.brainstorm.field-notes/Item/v1";
export function FieldNotesApp() {
const service = getBrainstorm()?.services?.vaultEntities ?? null;
const { entities } = useVaultEntities(service);
const items = useMemo(
() => entities.filter((e) => e.type === APP_TYPE),
[entities],
);
return (
{items.length === 0 ? (
Nothing here yet.
) : (
{items.map((item) => (
- {String(item.properties.title ?? item.id)}
))}
)}
);
}
```
The list is **live**: `useVaultEntities` subscribes to the vault, so when an object of this type is created or changed — by your app, another app, or another device — the list re-renders. You never write a manual `onChange → setState` loop; that’s [the reactivity rule](/build/recipes/#use-the-reactivity-layer).
## Register and run
[Section titled “Register and run”](#register-and-run)
A new app is registered with the shell so the dev seeder installs it on launch (add it to the first-party app list, per the repo’s contributor guide). Then:
```sh
bun run dev
```
The shell rebuilds and reinstalls first-party apps on boot, so a **full shell restart** is what deploys your changes — reloading a window serves the previous build. You’ll see your app in the launcher; open it and it renders the (empty) list.
Tip
Each app logs `[app:] build ` in its own DevTools console and the shell logs `[shell] launch … build `. If you think a change didn’t take, check those shas match — a stale sha means the shell wasn’t restarted.
## Make it do something
[Section titled “Make it do something”](#make-it-do-something)
Create an object of your type from the app, and watch the list update itself:
```tsx
const bs = getBrainstorm();
await bs.services.entities.create(APP_TYPE, {
title: "First field note",
createdAt: Date.now(),
updatedAt: Date.now(),
});
```
No refresh, no refetch — the live query already subscribed to this type re-renders. From here:
* [Working with data](/build/working-with-data/) — querying, editing, rich text, and app-private storage.
* [SDK & runtime](/build/the-sdk/) — the components and services you build the rest of the UI from.
* [Recipes & anti-patterns](/build/recipes/) — the conventions that keep an app consistent with the platform.
# Apps & permissions
> Every app runs sandboxed behind a capability ledger and can only touch what you explicitly allow.
Brainstorm is built entirely out of **apps**, and every app runs **sandboxed**. An app can’t reach your data, your network, or another app on its own — it can only do what you’ve granted it through the **capability ledger**.
## The capability model
[Section titled “The capability model”](#the-capability-model)
A capability is a specific, narrow permission: *read notes*, *write files*, *reach this one network host*, *show a notification*. Apps declare the capabilities they need; you grant or deny them.
Two principles make this trustworthy:
* **Nothing is ambient.** There is no “just let the app do anything.” Every sensitive action maps to a capability that was granted for a reason.
* **It fails closed.** If a permission check can’t be satisfied — or anything goes wrong evaluating it — the action is denied, never silently allowed.
Because access is explicit and revocable, it’s safe to run third-party apps, and later autonomous AI agents, over even your most important data.
## Granting and revoking
[Section titled “Granting and revoking”](#granting-and-revoking)
When an app first needs a capability, Brainstorm asks. You can:
* **Grant** it, optionally scoped (for example, to a single kind of object).
* **Deny** it — the app keeps working, minus that ability.
* **Revoke** it later from the vault’s permission settings.
Grants are recorded per vault, so an app you trust in your work vault has no standing in your personal vault.
## Isolation between apps
[Section titled “Isolation between apps”](#isolation-between-apps)
Apps are isolated from each other as well as from the system. One app can’t read another app’s private state or reach into its window. When apps do share data, it’s through the common object layer you can see and control — not through back channels. See [Objects](/concepts/objects/).
## Agents are apps too
[Section titled “Agents are apps too”](#agents-are-apps-too)
AI agents in Brainstorm sit behind the same ledger. An agent operates under a ceiling of capabilities you set; it can never grant itself more access than you’ve allowed. The permission model that keeps apps honest is the same one that governs automation.
## Next steps
[Section titled “Next steps”](#next-steps)
* [Objects](/concepts/objects/) — the shared data apps read and write
* [Your data & security](/concepts/your-data-and-security/) — the guarantees underneath
# Local-first & sync
> Brainstorm works fully offline on your own disk, and syncs across devices with end-to-end encryption through a relay that can't read your data.
Brainstorm is **local-first**: your vault is on your disk, the app reads and writes it directly, and nothing about your own content requires a server. Sync is an option you turn on — not a dependency you depend on.
## Local-first, in practice
[Section titled “Local-first, in practice”](#local-first-in-practice)
* **Instant.** Opening a vault and editing objects is local disk speed — no round-trips.
* **Offline by default.** Everything works with no network at all. You’re never blocked by a server being down or unreachable.
* **Durable.** Your data is plain files you own. If you stopped using Brainstorm tomorrow, your vault is still right there on disk.
## Conflict-free editing with CRDTs
[Section titled “Conflict-free editing with CRDTs”](#conflict-free-editing-with-crdts)
Brainstorm stores editable content as **CRDTs** (via [Yjs](https://yjs.dev)). A CRDT lets two devices — or two people — edit the same object at the same time and merge the results automatically, with no “which version wins?” dialog. This is what makes offline edits and real-time collaboration both work without losing changes.
## Sync that can’t read your data
[Section titled “Sync that can’t read your data”](#sync-that-cant-read-your-data)
When you enable sync, Brainstorm connects your devices through a **relay** — but the relay is *blind*:
* Your changes are **end-to-end encrypted** on your device before they’re sent.
* The relay only stores and forwards encrypted CRDT traffic. It never holds your keys and cannot read your content.
* The sync server is **self-hostable** if you’d rather run your own.
So you get multi-device sync and collaboration without handing your knowledge to a third party.
## Restoring a device
[Section titled “Restoring a device”](#restoring-a-device)
Because the encrypted history lives on the relay (or your own server), setting up a new device restores your vault from sync — you authenticate, and your objects rebuild locally from the encrypted stream.
## Next steps
[Section titled “Next steps”](#next-steps)
* [Your data & security](/concepts/your-data-and-security/) — keys, identity, and the threat model
* [Vaults](/concepts/vaults/) — the thing being synced
# Objects
> Everything in a vault is an object with typed properties, shared across every app rather than locked inside one.
Everything you create in Brainstorm is an **object**: a note, a task, a contact, a file, a calendar event. Objects are the shared substance of a vault — apps are just different ways of looking at them.
## One object, many views
[Section titled “One object, many views”](#one-object-many-views)
An object isn’t trapped in the app that made it. A task you create in a database can show up on the calendar, appear as a node in the graph, and be linked from a note — because all of those apps read and write the **same** object layer.
This is what makes Brainstorm feel connected rather than like a folder of disconnected tools: there’s one shared space of objects, and apps are lenses over it.
## Typed properties
[Section titled “Typed properties”](#typed-properties)
Objects carry **properties** — typed fields like text, number, date, checkbox, link, or a value drawn from a defined set. Properties are defined at the vault level, so the meaning of “Status” or “Due date” is consistent across every app that touches an object. Anything about an object that isn’t its main body is a property, edited through a real, shared property system rather than ad-hoc fields per app.
## Links and relationships
[Section titled “Links and relationships”](#links-and-relationships)
Objects relate to each other:
* **Mentions** — type `@` in rich text to link to any object. The link is real and bidirectional, so you can see everything that references a given object.
* **Collections** — group objects into typed sets (a reading list, a project’s tasks) without copying them.
The [Graph](/apps/graph/) app visualizes these relationships directly.
## Built on Block Protocol
[Section titled “Built on Block Protocol”](#built-on-block-protocol)
Under the hood, objects follow the **Block Protocol** — an open standard for typed, interoperable data. That keeps your content structured and portable rather than locked to a proprietary format, and it’s why blocks and data can move cleanly between apps.
## Next steps
[Section titled “Next steps”](#next-steps)
* [Apps](/apps/) — the lenses you use to work with objects
* [Local-first & sync](/concepts/local-first-and-sync/) — how objects stay consistent across devices
# Vaults
> A vault is the on-disk home for your knowledge — a folder of files you own, protected by a key only you hold.
A **vault** is where your knowledge lives. It’s a folder on your own disk — not a row in someone else’s database — and it’s the unit Brainstorm opens, protects, and (optionally) syncs.
## What’s in a vault
[Section titled “What’s in a vault”](#whats-in-a-vault)
A vault holds everything for one body of work:
* **Your objects** — notes, database rows, files, tasks, and anything else your apps create.
* **The apps you’ve installed** into that vault and the **permissions** you’ve granted them.
* **Your identity** for that vault — a cryptographic key that signs your changes, so collaborators can verify who wrote what.
Different bodies of work can live in different vaults — for example, a personal vault and a work vault — each with its own apps, permissions, and sync settings.
## How a vault is protected
[Section titled “How a vault is protected”](#how-a-vault-is-protected)
When you create a vault you choose how its key is stored:
* **System keychain** — the master key lives in your operating system’s secure keychain and the vault unlocks when you log in.
* **Passphrase** — you supply a passphrase to derive the key. Without it, the vault can’t be opened.
The master key never leaves your machine in plaintext and is held in memory only while the vault is open. See [Your data & security](/concepts/your-data-and-security/).
## Opening and closing
[Section titled “Opening and closing”](#opening-and-closing)
Only one vault is “active” at a time. Opening a vault loads its data and makes its apps available; closing it releases the key from memory. Switching vaults is instant and never mixes data between them — cross-vault isolation is a hard boundary.
## Next steps
[Section titled “Next steps”](#next-steps)
* [Apps & permissions](/concepts/apps-and-permissions/) — how apps get scoped access to a vault
* [Local-first & sync](/concepts/local-first-and-sync/) — putting one vault on many devices
# Your data & security
> How Brainstorm protects your vault — encryption, a key only you hold, a signed identity, and a sandbox that fails closed.
Brainstorm’s security model exists so you can run apps and agents over your most important knowledge without giving anything ambient access to it.
## A key only you hold
[Section titled “A key only you hold”](#a-key-only-you-hold)
Each vault is protected by a **master key** that never leaves your machine in plaintext. You choose where it’s stored:
* in your **operating system keychain**, or
* derived from a **passphrase** you supply.
The key is held in memory only while the vault is open and is wiped when you close it. There’s no Brainstorm account that can unlock your vault for you — and equally, no one else can.
## Your identity
[Section titled “Your identity”](#your-identity)
Each vault carries a cryptographic **identity** — a keypair that signs the changes you make. Collaborators can verify that an edit genuinely came from you, and your private signing key never crosses an app boundary or leaves the device.
## The sandbox and the ledger
[Section titled “The sandbox and the ledger”](#the-sandbox-and-the-ledger)
Apps are sandboxed and isolated from each other and the system. Everything sensitive an app can do is mediated by the [capability ledger](/concepts/apps-and-permissions/), which **fails closed**: if a permission can’t be confirmed, the action is denied. There’s no path by which an app quietly gains access you didn’t grant.
## Encryption at rest and in transit
[Section titled “Encryption at rest and in transit”](#encryption-at-rest-and-in-transit)
* **In transit:** when you sync, content is end-to-end encrypted before leaving your device; the relay can’t read it. See [Local-first & sync](/concepts/local-first-and-sync/).
* **At rest:** your vault is stored locally under your control, protected by your master key.
## What Brainstorm does *not* do
[Section titled “What Brainstorm does not do”](#what-brainstorm-does-not-do)
* It does not phone your content home. There is no server that holds your vault.
* It does not give apps blanket access “to be convenient.”
* It does not lock your data in a proprietary format — your knowledge is structured, portable, and yours.
## Next steps
[Section titled “Next steps”](#next-steps)
* [Apps & permissions](/concepts/apps-and-permissions/) — the capability model in detail
* [Vaults](/concepts/vaults/) — how a vault is created and protected
# Install
> How to get Brainstorm running on macOS, Windows, and Linux.
Brainstorm is a desktop application for **macOS, Windows, and Linux**.
Private beta
Brainstorm is in private beta ahead of its public release. Downloads are gated to waitlist members. [Join the waitlist at getbrainstorm.online](https://getbrainstorm.online) — you’ll get a download link and a short setup walkthrough when your invite lands.
## System requirements
[Section titled “System requirements”](#system-requirements)
* **macOS** 12 (Monterey) or later — Apple Silicon and Intel.
* **Windows** 10 or later (64-bit).
* **Linux** — a recent 64-bit distribution (AppImage / `.deb`).
* \~400 MB of disk for the app, plus whatever your vaults hold.
## Installing
[Section titled “Installing”](#installing)
Once you have a download link:
1. **macOS** — open the `.dmg` and drag Brainstorm to Applications. On first launch, right-click → Open to clear Gatekeeper.
2. **Windows** — run the installer and follow the prompts.
3. **Linux** — mark the AppImage executable (`chmod +x`) and run it, or install the `.deb` with your package manager.
## First launch
[Section titled “First launch”](#first-launch)
On first launch Brainstorm asks you to **create a vault** — the on-disk home for your knowledge. Pick a folder, choose how to protect it (system keychain or a passphrase), and you’re in. The full walkthrough is in the [Quickstart](/start-here/quickstart/).
## Updating
[Section titled “Updating”](#updating)
Apps inside Brainstorm update independently of the shell. The shell itself checks for updates on launch and applies them in the background; your vaults are never touched by an update.
## Next steps
[Section titled “Next steps”](#next-steps)
* [Quickstart](/start-here/quickstart/) — your first vault and app
* [Vaults](/concepts/vaults/) — what a vault is and how it’s protected
# Quickstart
> Create a vault, open your first app, and capture your first note in Brainstorm.
This walkthrough takes about five minutes. It assumes Brainstorm is [installed](/start-here/install/).
## 1. Create a vault
[Section titled “1. Create a vault”](#1-create-a-vault)
On first launch, Brainstorm asks where your knowledge should live.
1. Click **Create vault**.
2. Choose an empty folder on your disk.
3. Choose how to protect it:
* **System keychain** (recommended) — Brainstorm stores the key in your OS keychain; the vault unlocks automatically when you log in.
* **Passphrase** — you type a passphrase to unlock. Nothing else can open the vault.
4. Give the vault a name and confirm.
Your vault is now a folder of files you fully own. See [Vaults](/concepts/vaults/) for what’s inside.
## 2. Open an app
[Section titled “2. Open an app”](#2-open-an-app)
Brainstorm opens to a dashboard. Everything you do happens inside an **app**.
1. Open the launcher.
2. Pick **Notes**.
3. The app opens in its own window, sandboxed and scoped to only the data it’s allowed to touch.
The first time an app needs a new capability (for example, reading a different kind of object), Brainstorm asks you to grant it. You can review and revoke these grants any time — see [Apps & permissions](/concepts/apps-and-permissions/).
## 3. Capture something
[Section titled “3. Capture something”](#3-capture-something)
In Notes:
* Start typing to create a note.
* Use rich text — headings, lists, checkboxes, code.
* Type `@` to link to another object in your vault, or `/` for a command menu.
Everything you write is saved to your vault on disk, immediately and offline.
## 4. Connect your knowledge
[Section titled “4. Connect your knowledge”](#4-connect-your-knowledge)
Brainstorm’s value comes from objects relating to each other:
* Open **Database** to make a structured table — tasks, contacts, reading list — with typed properties.
* Open **Graph** to see how your notes and objects link together.
* Open **Files** to bring existing documents into the vault.
The same object can appear in many apps; they’re all views over one shared data layer. See [Objects](/concepts/objects/).
## 5. (Optional) Sync across devices
[Section titled “5. (Optional) Sync across devices”](#5-optional-sync-across-devices)
If you want your vault on more than one machine, enable sync. Your data is end-to-end encrypted before it leaves your device, and the relay that forwards it can’t read it. See [Local-first & sync](/concepts/local-first-and-sync/).
## Where to go next
[Section titled “Where to go next”](#where-to-go-next)
* [Concepts](/concepts/vaults/) — the model behind everything you just did
* [Apps](/apps/) — what each built-in app does
# What is Brainstorm?
> Brainstorm is a local-first, AI-native operating system for knowledge work — a desktop shell that hosts sandboxed apps over your own data.
Brainstorm is a **local-first, AI-native operating system for knowledge work**. It looks and behaves like a desktop OS — a shell that hosts small, focused apps — except the “computer” is your knowledge, and everything runs on your own machine.
Three ideas define it:
## Apps, not features
[Section titled “Apps, not features”](#apps-not-features)
The shell itself does almost nothing. It hosts **apps**: Notes, Database, Files, Graph, a calendar, a code editor, and more. You add the ones you want and ignore the rest. Each app is sandboxed and updates on its own, so the product grows without turning into a single sprawling monolith.
## Your data, your disk
[Section titled “Your data, your disk”](#your-data-your-disk)
Your knowledge lives in a **vault** — a folder of files on your own disk, not a row in someone else’s database. Brainstorm is local-first: it works fully offline, opens instantly, and never requires a server to read or write your own content. When you choose to sync across devices, traffic is end-to-end encrypted and the relay never sees your data. See [Local-first & sync](/concepts/local-first-and-sync/).
## Permissions you grant
[Section titled “Permissions you grant”](#permissions-you-grant)
Every app and every AI agent runs behind a **capability ledger**. An app can only touch the data and services you have explicitly allowed — reading a note, saving a file, reaching the network. Nothing is ambient. This is what makes it safe to run third-party apps and autonomous agents over your most important data. See [Apps & permissions](/concepts/apps-and-permissions/).
## Built on open foundations
[Section titled “Built on open foundations”](#built-on-open-foundations)
Brainstorm is built on open building blocks rather than a proprietary format:
* **Block Protocol** for interoperable, typed data.
* **Yjs** (CRDTs) for conflict-free, real-time collaboration and offline editing.
* **Lexical** for rich text.
That means your content is structured, portable, and not locked to one vendor.
Note
Brainstorm is in active development ahead of its public beta. Some features described in these docs are still rolling out. [Join the waitlist](https://getbrainstorm.online) to get early access.
## Next steps
[Section titled “Next steps”](#next-steps)
* [Install Brainstorm](/start-here/install/)
* [Quickstart](/start-here/quickstart/) — create a vault and open your first app
* [Concepts](/concepts/vaults/) — the model behind the product