Getting Started
This guide walks you through setting up your local development environment and deploying your first Magic App.
Quick Start
Three steps. Claude does the rest.
# 1. Make a directory for your app and cd into it
mkdir my-app && cd my-app
# 2. Open Claude Code in this directory
claude
- Tell Claude what you want to build — for example:
"I want to build a Magic App that shows our top customers by revenue."
Claude will load the magic-apps skill, ask any clarifying questions (app name, which datasets/queries to use, AI features needed), and run the bootstrap sequence for you (scaffold Vite, install @entrinsik/vite-plugin-informer, run npx informer-init, draft informer.yaml with the right dependencies: slots). You don't have to remember the commands.
If the informer plugin isn't installed yet, add it once:
# Inside Claude Code
/plugin marketplace add entrinsik-org/claude-plugins
/plugin install informer@entrinsik-plugins
This installs the magic-apps skill (invoked as /informer:magic-apps), which Claude auto-loads whenever you mention Magic Apps, Informer, or related concepts. You don't need to re-install per project.
Already have the older magic-reports plugin? The marketplace no longer lists it, so the command-line uninstall fails with a marketplace lookup error. Run /plugin, open the Installed tab, and uninstall it there, then install informer as above.
What Claude Sets Up
The bootstrap creates a standard Vite project plus the Informer plugin and scaffolding. With the default React template, after it finishes you'll have:
my-app/
├── .env # Connection settings (git-ignored)
├── .env.example # Template for connection settings
├── informer.yaml # App configuration (dependencies, roles, agents, widgets)
├── package.json # informer section (name, id) + deploy and workspace:* scripts
├── vite.config.js # Vite config with the informer() plugin
├── index.html # App shell
├── public/
│ └── favicon.svg # Vite's logo; replace it with the App's icon (see below)
└── src/
├── main.jsx # Entry point
├── App.jsx # Root component
└── index.css # Styles
server/ (route handlers) and migrations/ (the App's database) are not created by the bootstrap. Add them when the App needs them; Claude does this when you ask for a server route or for the App to store its own data.
App Configuration (informer.yaml)
The informer.yaml file declares the data your app depends on, custom roles, agents, and dashboard widgets. Without dependencies: or access:, all API access is blocked when the app runs in Informer.
# informer.yaml
# Typed slots — installer binds these at first deploy (or the
# manifest's defaultBinding does it automatically). Slot names
# are referenced from handler code as `context.<slot>.<method>()`.
dependencies:
sales:
target: dataset
defaultBinding: 7d5a9b1e-0c83-4bde-9e2a-3a4b5c6d7e8f
monthly_summary:
target: query
defaultBinding: 9a8b7c6d-5e4f-3a2b-1c0d-fedcba987654
roles:
- id: viewer
name: Viewer
description: Read-only access to dashboards
- id: approver
name: Approver
description: Can approve submitted items
defaultBinding UUIDsdefaultBinding accepts UUIDs only. Find them via the resource's list endpoint — e.g. GET /api/datasets-list returns each dataset's UUID and configId. The deploy validator rejects non-UUID values with a clear error.
See the informer.yaml Reference for the full format, including row-level security, credential injection, the legacy access: block, and the one-shot route to modernize older access:-only apps.
Configure Connection
Edit .env with your Informer instance URL and credentials:
# Informer connection settings
INFORMER_URL=http://localhost:3000
# Option 1: API Key (recommended)
INFORMER_API_KEY=your-api-key
# Option 2: Basic auth
# INFORMER_USER=admin
# INFORMER_PASS=yourpassword
The Vite plugin uses these settings to proxy /api/* requests during local development.
Package.json Configuration
The informer section in package.json controls deployment metadata:
{
"name": "my-app",
"informer": {
"name": "My App",
"description": "A custom Magic App",
"id": "a1b2c3d4-5678-90ab-cdef-123456789abc"
}
}
| Field | Description |
|---|---|
name | Display name in Informer (falls back to package name) |
description | App description |
id | App UUID. informer-init generates it at scaffold time and npm run deploy creates or addresses the App with it. Don't set it by hand. |
icon | Material icon name for the app (e.g., "bar_chart") |
Your First Prompt
Now that your environment is set up, you can ask Claude Code to build your first app. Open Claude Code and try this:
Prompt:
"Build me a simple sales dashboard. Query the admin:sales-data dataset and show total revenue, order count, and average order value as metric cards. Add the dataset as a
dependencies:slot in informer.yaml. Use React with clean, modern styling."
Claude will:
- Create the HTML structure with metric card layout
- Write JavaScript to call the typed dep proxy (e.g.
context.sales.search(...)) - Add styling with theme support (light/dark)
- Add a
dependencies:slot for the dataset ininformer.yaml(resolvingdefaultBindingviaGET /api/datasets-list) - Set
window.informerReady = truewhen data loads (for PDF export)
React is the default. You can ask for a different framework or styling:
- "Use TypeScript" (Claude uses the
react-tstemplate) - "Build it with Vue 3 and Tailwind CSS"
- "Use Svelte"
- "Keep it vanilla JS with ECharts for charts"
The code examples in this guide show what Claude generates when you prompt it. You don't need to copy-paste — just describe what you want and let Claude build it.
Local Development
Start the development server:
npm install
npm run dev
This launches Vite with:
- Hot reload for instant feedback
- API proxy to your Informer server (with automatic auth)
window.__INFORMER__context mock (app ID, theme, etc.)- Server route middleware (files in
server/are executed locally)
Your app will be available at http://localhost:5173 (or the next available port).
Iterating with Claude
Don't like something? Just tell Claude:
- "The chart colors don't match our brand — use #4f46e5 for primary"
- "Add a date range filter above the metrics"
- "Make the layout responsive for mobile"
- "Change the font to Inter"
Claude will update the code based on your feedback.
Theme Support
The Vite plugin injects a mock window.__INFORMER__ object during development:
window.__INFORMER__ = {
report: { id: 'dev-local', name: 'Local Development' },
theme: 'light',
roles: [],
platform: { version: 'dev', capabilities: { serverRoutes: true, storage: true, embeddings: false, /* … */ } }
}
platform is what the real server injects too (the build version and the
app type's capability flags), so an app feature-detects the same way in
both places: window.__INFORMER__.platform?.capabilities?.embeddings. The
dev mirror reports embeddings: false because the pump needs a real
Informer; override any flag with informer({ mock: { platform: { capabilities: { embeddings: true } } } }).
To test dark mode, override in vite.config.js:
import informer from '@entrinsik/vite-plugin-informer';
export default {
plugins: [informer({ mock: { theme: 'dark' } })]
};
In your code, respond to the theme:
const theme = window.__INFORMER__?.theme || 'light';
document.documentElement.setAttribute('data-theme', theme);
:root { --bg: #ffffff; --text: #1a1a1a; }
[data-theme="dark"] { --bg: #1e1e1e; --text: #e0e0e0; }
body { background: var(--bg); color: var(--text); }
Deploy to Informer
Build and deploy your app:
npm run deploy
This builds your project and uploads it to Informer. See Deployment for the full pipeline details.
Your app will be available at:
https://your-instance.entrinsik.com/api/apps/{owner}:{slug}/view
The first deploy creates the App under the id informer-init wrote to package.json (informer.id); every later deploy updates that same App.
App Icon
Vite's template ships its own logo as public/favicon.svg. Replace it with the App's icon: the file is deployed to the App's library root and used as:
- App gallery icon - Shown in desktop and mobile app galleries
- Browser tab favicon - Shown when the app is viewed in a browser
Icon Guidelines
- 512x512 viewBox, square (1:1 aspect ratio)
- Duotone style - One hue with full opacity for primary shapes, ~35% for secondary
- Self-contained background - Bake the background color into the SVG with rounded corners (
rx="96") - Bold, simple shapes - Recognizable at 70px (mobile icon size)
Example duotone icon:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<!-- Background with rounded corners -->
<rect width="512" height="512" rx="96" fill="#064e3b"/>
<!-- Secondary elements at 35% opacity -->
<rect x="96" y="240" width="64" height="152" rx="10" fill="#6ee7b7" opacity="0.35"/>
<!-- Primary elements at full opacity -->
<rect x="176" y="160" width="64" height="232" rx="10" fill="#6ee7b7"/>
</svg>
Next Steps
Now that you have a working development environment, continue to KPI Dashboard to build your first data-driven app.