There are two ways to author 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.Building Outside the Workspace
The same manifest-based pipeline is available through the Application MCP Server. That is the path for external tools — VS Code, local scripts, CI-style checks — that already have source files and want CharmIQ to build them.The MCP build surface returns a runnable artifact. It does not create a folder, write documents, place an Application container, or publish anything. The caller decides what to do with the output: write it to disk for preview, pass it into an iframe srcdoc, or persist it through another CharmIQ API.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.
- Use MCP when the source lives elsewhere. If the files are already in your editor or another tool, call the Application MCP Server and treat the result as a build artifact.
- 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.→ Application MCP Server — Build Applications from external tools and receive a runnable artifact.