Build on the OS for the age of AI
Write a Space.
Ship an app with an AI inside it.
A Space is a small Vue 3 plugin. Publishing one gives you an app with a built-in Operator, a typed data layer, identity, billing, and a Space Store to reach users — none of which you have to build. You write the part that's yours; the OS provides the rest.
The leverage
Six things you don't have to build.
An Operator, built in
Every action you declare becomes a tool the Operator can call. You write a function; users get an agent that can run it. No model wiring, no tool plumbing.
A typed data layer
defineModel + useGraph give you a multi-tenant, access-controlled database with zero backend code. Schemas are per-Space and isolated by org.
Identity & auth, solved
Your Space inherits the signed-in user and their org. No login screens, no token handling, no OAuth dance to build.
Billing & metering
Operator usage is metered and billed by the platform. Paid Spaces earn through the Space Store revenue share.
Three surfaces, one build
The same Space runs in the desktop app, the web portal, and alongside the mobile companion. Build once.
Distribution
Publish to the public Space Store, privately to your org, or scoped to one project — one command, three audiences.
The key idea
Your actions are the Operator's tools.
Declare an action in your Space and two things happen at once: your UI can call it, and the Operator can call it too — with descriptions, typed params, and your access rules. You write a function; your users get an agent that knows how to use it.
// src/actions.ts — auto-registered, callable by UI and Operator alike
export const actions = {
create_note: {
description: 'Create a note for the signed-in user',
params: { content: { type: 'string', required: true } },
async run({ content }, ctx) {
return ctx.graph.create(Note, { content })
},
},
}The data layer
Define a model. You have a backend.
defineModel() declares fields and access rules; useGraph() gives you typed CRUD against a multi-tenant, org-isolated store. No migrations to hand-write, no server to deploy, no auth to bolt on — the Graph (Construct's backend for Spaces, the @construct-space/graph SDK) runs it.
import { defineModel, field, access } from '@construct-space/graph'
export const Note = defineModel('Note', {
content: field.text(),
pinned: field.boolean(),
access: access.owner(),
})
// in a component / composable
const { find, create } = useGraph(Note)Anatomy
What's in a Space.
The loop
Scaffold → dev → build → publish.
Scaffold
construct scaffold my-space — manifest, pages, models, actions, all wired.
Develop
construct dev — live in the real OS, with real identity and a real Operator. Not a sandbox lie.
Build
construct build — bundled as an IIFE Space, ready to install anywhere Construct runs.
Publish
construct publish — to the public Space Store, your org, or a single project.
$ construct scaffold my-space
$ construct dev
$ construct build
$ construct publish # public · org · or project-scopedThe proof
We build Spaces with a Space.
SpaceKit — the tool we use to scaffold, edit, preview, and publish every Space, including itself — runs on the same SDK you'd use, the same Operator, the same OS. If it's good enough to ship the platform, it's good enough to ship your workflow.