There are two ways to build an Application in CharmIQ. Start with whichever matches the size of the problem.The Inline Application
The fastest path: write HTML, CSS, and JavaScript directly into the application. No file management, no build step, no manifest. The Application appears in your workspace immediately.This is the right approach for:- A focused tool with a single purpose
- Something you want to iterate on quickly
- A first pass before you know how complex it needs to be
The CharmIQ bridge — window.charmiq — is injected automatically. Your Application can read and write collaborative data in the document, connect to OAuth-protected APIs, call MCP servers, and communicate with other Applications in the same workspace. All of it is available from a single HTML file.A Charm can produce a complete inline Application in one pass. Describe what you need; it writes the HTML, styles it all within the Application container in your document.The Folder-Based Application
When the problem grows past what a single file handles cleanly, the right move is a folder-based Application. You create a folder in CharmIQ, put your source files in it as Source documents, and add a manifest.json that tells the build pipeline how to assemble them.This approach unlocks:- Multiple source files — TypeScript, SCSS, React components, utilities, each in its own document
- Proper import resolution — write
import { App } from './App' and the build system resolves it from your folder structure - External dependencies — React, D3, Lodash, or any CDN-hosted package via import maps
- Real directory organization — sub-folders for components, hooks, styles
The build pipeline takes your source files, runs them through esbuild (TypeScript → JavaScript, SCSS → CSS), resolves all imports, bundles everything, and produces a single self-contained HTML document that runs in your workspace. No deploy step. No CI pipeline. Edit a file, reload the Application, see the result.A Charm can build a folder-based Application entirely. That means: create the folder structure, write each source file, produce the manifest, and place the Application container referencing the folder. One prompt. A working, multi-file Application.Knowing When to Switch
Start inline. It's faster, the feedback loop is tighter, and for many tools it's all you need.Switch to folder-based when:- You're importing external libraries or splitting into components
- You want TypeScript or SCSS
- The inline file is getting hard to navigate
- You're building something you'll want to maintain over time
Promoting an inline Application to a folder-based one is a natural step, not a rewrite. The HTML template and core logic move over intact — you're just adding structure around them.In Practice
Inline: The Minimal Case
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; padding: 24px; }
.output { font-size: 1.25rem; margin-top: 16px; }
</style>
</head>
<body>
<div class="output" id="out">Loading...</div>
<script>
window.charmiq.appContent.onChange$().subscribe(change => {
document.getElementById('out').textContent = change.content || 'Nothing yet.';
});
</script>
</body>
</html>
window.charmiq is always available. No import, no setup — it's injected before your code runs.Folder-Based: The Manifest
The manifest is a JSON file (manifest.json) at the root of your Application folder. It tells the build system where to find your entry points and which external packages to load:{
"id": "my_app_v1",
"name": "My Application",
"bundle": {
"format": "esm",
"entry": {
"html": "/index.html",
"script": "/src/main.tsx",
"style": "/src/styles.scss"
},
"dependencies": {
"importMap": {
"react": "https://esm.sh/react@18.2.0",
"react-dom/client": "https://esm.sh/react-dom@18.2.0/client"
}
}
}
}
Everything else in the folder is discovered automatically. You don't need a files map unless you're pulling source from outside the folder.Folder Structure
My App (folder)
├── manifest.json
├── index.html
├── src/
│ ├── main.tsx
│ ├── App.tsx
│ └── styles.scss
└── components/
└── Header.tsx
Virtual paths match the document names in your folder. import { Header } from './components/Header' resolves to the Header.tsx Source document inside the components sub-folder.Patterns
- Describe it, don't build it. Tag your Charm and describe the tool you need. For inline Applications, it builds and places the container in one pass. For folder-based Applications, it creates the folder structure, writes each file and produces the manifest.
- Start inline, promote when it grows. Don't pre-architect. Build something that works then restructure if it earns complexity.
- The bridge is always there. Every Application — inline or folder-based — has
window.charmiq available from the first line of script. OAuth, MCP, app-content, app-state — all of it is accessible the same way regardless of how the Application was built.
Next Steps
→ Developer | App-Content and App-State — How Applications store data in the document.→ Developer | The Bridge API — The complete window.charmiq reference.→ Developer | The Build Pipeline — How the manifest, virtual file system, and esbuild work together.