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? Replace it:
/plugin uninstall magic-reports@entrinsik-plugins
/plugin install informer@entrinsik-plugins
What Claude Sets Up
The bootstrap creates a standard Vite project plus the Informer plugin and scaffolding. After it finishes you'll have:
my-app/
├── .env # Connection settings (not committed)
├── .env.example # Template for connection settings
├── informer.yaml # App configuration (dependencies, roles, agents, widgets)
├── package.json # Project metadata + informer section
├── vite.config.js # Vite config with informer() plugin
├── public/
│ └── favicon.svg # App icon (512x512, duotone recommended)
├── index.html # Main HTML file
├── main.js # Entry point
├── styles.css # Styles
├── server/ # Server-side route handlers (optional)
│ └── index.js # Example: GET / handler
└── migrations/ # SQL migration files (optional)
└── 001-create-table.sql
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 (auto-generated and saved after first deploy) |
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'
}
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 deploy command saves the app UUID to package.json (informer.id) after the first deployment. This ensures subsequent deploys update the same app.
App Icon
Place a favicon.svg in your public/ directory. It will be 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.