Skip to main content

Quickstart

Build and run your first Lumio extension in 5 minutes.

1. Install the CLI

npm install -g @zaflun/lumio-cli

2. Log in to Lumio

lumio login

This opens your browser for PKCE OAuth authentication. After login, credentials are stored in ~/.lumio/credentials.

For CI/CD environments, use token-based auth:

lumio login --token lm_usr_your_api_key_here

3. Scaffold a new extension

lumio init my-first-extension

The interactive wizard asks:

? Extension name: My First Extension
? Description: A hello world extension
? Category: widget
? Targets: editor, layer
? Server functions: no

This creates the extension on Lumio (generating an Extension-ID), scaffolds the project, and writes lumio.config.json.

4. Set up AI assistant (optional)

If you use an AI coding assistant (Claude Code, Copilot, Cursor, Gemini, Windsurf, Codex), install the Lumio skill files so your assistant understands the SDK:

npx @zaflun/lumio-agent-skill add

This creates .lumio/skills/ with reference docs that teach your assistant about components, hooks, server functions, and CLI commands. See AI Assistant Integration for per-tool setup.

5. Start the dev server

cd my-first-extension
pnpm install
lumio dev

This starts a Vite dev server with hot-reload and a Lumio sandbox that simulates the host environment with mock events.

6. Edit the extension

Open src/editor.tsx:

import { Lumio, CompactView, TextField, Toggle, useExtensionStorage } from "@zaflun/lumio-sdk";

function Settings() {
const [storage, setStorage] = useExtensionStorage();
return (
<CompactView title="My First Extension">
<Toggle
label="Visible"
checked={storage.visible ?? false}
onChange={(checked) => setStorage({ ...storage, visible: checked })}
/>
<TextField
label="Message"
value={storage.text ?? ""}
onChange={(value) => setStorage({ ...storage, text: value })}
/>
</CompactView>
);
}

Lumio.render(<Settings />, { target: "editor" });

Open src/layer.tsx:

import { Lumio, Text, useExtensionStorage } from "@zaflun/lumio-sdk";

function Overlay() {
const [storage] = useExtensionStorage();
if (!storage.visible) return null;
return <Text content={storage.text ?? "Hello World"} variant="heading" />;
}

Lumio.render(<Overlay />, { target: "layer" });

Changes in the editor surface propagate to the layer in real time.

7. Build and deploy

lumio build
lumio deploy -v 1.0.0 -d "Initial release"

Your extension is now uploaded as a draft. Use the submission wizard in the dashboard to submit it for review.

Next steps