Skip to main content

Quickstart

Build and run your first Lumio extension in 5 minutes.

0. Apply as a developer

Before using the CLI, you need an approved developer profile. If you have not applied yet, follow the steps in Becoming a Developer to submit your application and wait for approval. The lumio init command requires an approved developer profile to create extensions.

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.

AI-Assisted Development

Building with an AI coding assistant? Feed it the full Lumio documentation in one go:

  • llms.txt — structured index of all documentation pages
  • llms-full.txt — complete documentation in a single file

Paste the URL or content into your assistant's context for accurate Lumio extension help. For deeper integration, install the @zaflun/lumio-agent-skill package.

Next steps