Skip to content

How .slop files work

A .slop is one file: a small database that holds the app needed to open it and, once created as a writable document, everything that document saved. Send it by Mail or AirDrop, and it arrives whole.

slop.ts explicitly declares identity, window, theme, document shape, initial values, imported view/capture components and commands. It imports styles and images through Vite; filenames do not assign roles. Before mounting, the host applies theme defaults and document overrides as --slop-* CSS variables.

slop build compiles the app, evaluates the declaration in a restricted Rust runner, and packs the result into a template file:

My.slop
app catalog columns and one definition (descriptor, theme, commands),
and the format and runtime the app needs
assets ui.js, optional ui.css / commands.js, content-addressed media
artwork preview and, when declared, icon images
checkpoint initial values as a seed Loro snapshot

The authored bundle does not contain its own document engine. The installed app supplies the page shell, boot sequence, the native document engine and lifecycle. It calls the compiled app’s mount(ctx, target) with document, binding, theme, attachment, capture, and window services. The page shell is served to the WebView; it is never copied into the file.

Creating a document copies a template into a new file. As it is edited, the same file gains:

document the document's identity
checkpoint saved data and theme overrides
updates edits saved since the checkpoint
attachments imported files, by content

The Rust owner (on Loro), shared by the app and CLI, owns the live document and persists opaque checkpoints and updates; the page renders snapshots of it. Initial values are read only when a document is created, and the stored schema is a descriptor rather than JSON Schema. There is no editable document JSON projection.

One writer at a time owns a document: an OS lock the Rust owner keeps outside the file. CLI commands route to the live owner’s socket or take the lock and edit the document directly. Headless editing never starts a WebView. Named commands evaluate their stored program in a restricted child before the owner applies the returned intents.

Theme overrides live in Loro’s root theme map, outside the authored data tree. They merge per color and share the document’s sequence, undo and saving. The page receives the effective palette through its initial state and ordered publications. Replacing document data with JSON preserves the theme. See theme files and commands. Duplicate and Share a Copy preserve the saved content, attachments and overrides in a new file.

Registered templates and built-in starters remain immutable. Create makes a writable copy. Rebuilding or updating a template does not replace the app or schema in existing documents. An app update supplies a newer page shell and engine to those documents. Export renders a fresh read-only page from saved state. For an open document, the owner first saves and copies it; no second writer renders the original file.

Close before moving or renaming a document. Keep it on a local filesystem outside iCloud and other synced folders. Every file is checked when it opens: a damaged or oversized one is refused, never repaired. Migrations, schema evolution, and multiple writers on one document are not supported.