Skip to main content
Most people build widgets entirely through conversation with the Deepspace agent. But if you want to understand what’s actually happening — or take direct control — this section is for you.

What a Widget Actually Is

A widget is a self-contained React app bundled into a single HTML file and served inside an iframe on the canvas. Each widget gets:
  • Its own iframe — sandboxed, cross-origin from the canvas
  • A WebSocket connection — to a per-canvas storage backend (RecordRoom)
  • Access to the SDK@spaces/sdk provides hooks for storage, auth, theming, files, and more
  • API access — the mcapi client lets widgets call DeepSpace integrations (text generation, Google Calendar, web search, etc.)

The Stack

LayerTechnology
UIReact + Tailwind CSS
StorageCloudflare Durable Objects (SQLite) via WebSocket
File storageCloudflare R2
Buildesbuild (canvas widgets) / Vite (standalone sites)
HostingCloudflare Workers + R2
AuthClerk (standalone) / postMessage token relay (canvas)

Key Concepts

Canvas Mode vs Standalone Mode

Widgets run in two contexts:
  • Canvas mode — embedded in an iframe on the DeepSpace canvas. Auth tokens come from the parent frame via postMessage.
  • Standalone mode — deployed as an independent website (e.g., myapp.app.space). Full Clerk auth flow, its own URL, works outside DeepSpace.
The widget’s main.tsx detects which context it’s in and wires up the correct providers automatically. You write your app in App.tsx and it works in both contexts.

The SDK (@spaces/sdk)

Everything your widget needs is available through the SDK:
ImportWhat it gives you
@spaces/sdk/storageuseQuery, useMutations, useUser, useTeams, useMessages, useYjsText, useR2Files
@spaces/sdk/authisWidgetContext(), getWidgetAuthToken(), SpacesAuthProvider
@spaces/sdk/themeDeepSpaceThemeProvider, theme config types
@spaces/sdk/configgetApiUrl() (auto-detects dev/staging/prod)
@spaces/sdkmcapi client for API calls

Schemas

Every collection your widget uses is defined in schemas.ts. Schemas control:
  • What fields each record has
  • Who can read/write (role-based access)
  • What happens when a record is created (auto-injecting userId, timestamps, etc.)

This Section

Local Development

GitHub setup, local dev server, and push workflow

Storage

Where data lives and how the storage system works

Hooks Reference

Every hook in the SDK and how to use it

Integrations & APIs

Calling external services from your widget

Theming

How the theme system works and how to customize it