Try it live
The @tumaet/apollon package running in your browser. The snippet beside it is the code that mounts it — switch frameworks in the tabs.
- React
- Angular
- Vanilla JS
import { Apollon } from "@tumaet/apollon"
import type { UMLModel } from "@tumaet/apollon"
import "@tumaet/apollon/style.css"
export function Diagram({ initialModel }: { initialModel?: UMLModel }) {
return (
<Apollon
style={{ height: 600 }}
defaultModel={initialModel}
onMount={(editor) => {
const id = editor.subscribeToModelChange((model) => {
localStorage.setItem("diagram", JSON.stringify(model))
})
return () => editor.unsubscribe(id)
}}
/>
)
}
import {
Component,
DestroyRef,
ElementRef,
afterNextRender,
inject,
input,
viewChild,
} from "@angular/core"
import { ApollonEditor, type UMLModel } from "@tumaet/apollon"
import "@tumaet/apollon/style.css"
@Component({
selector: "app-diagram",
template: `<div #host style="height: 600px"></div>`,
})
export class DiagramComponent {
readonly initialModel = input<UMLModel>()
private host = viewChild.required<ElementRef<HTMLDivElement>>("host")
constructor() {
const destroyRef = inject(DestroyRef)
afterNextRender(() => {
const editor = new ApollonEditor(this.host().nativeElement, {
model: this.initialModel(),
})
const subId = editor.subscribeToModelChange((model) => {
localStorage.setItem("diagram", JSON.stringify(model))
})
destroyRef.onDestroy(() => {
editor.unsubscribe(subId)
editor.destroy()
})
})
}
}
<link
rel="stylesheet"
href="https://esm.sh/@tumaet/apollon@5.2.0/style.css"
/>
<div id="apollon" style="width: 100%; height: 600px"></div>
<script type="module">
// esm.sh resolves and serves Apollon's required peers (react, react-dom,
// @xyflow/react, yjs, y-protocols) automatically.
import { ApollonEditor } from "https://esm.sh/@tumaet/apollon@5.2.0"
const saved = localStorage.getItem("diagram")
const editor = new ApollonEditor(document.getElementById("apollon"), {
model: saved ? JSON.parse(saved) : undefined,
})
editor.subscribeToModelChange((model) => {
localStorage.setItem("diagram", JSON.stringify(model))
})
// editor.destroy() when you're done.
</script>
Edits stay local — refresh to reset.
Four ways to use Apollon
Same editor, same diagram format — only the delivery differs.
Embed it
One @tumaet/apollon package on npm, mounted in React, Angular, or plain JavaScript. Your app shares a handful of peer dependencies with the editor — the embedding guide lists them.
Host the web app
A full diagram editor with sharing and real-time collaboration. Use the hosted instance or run your own with Docker.
User guide →iPhone & iPadModel on the go
A touch-friendly, local-first editor for iOS and iPadOS. Work offline, then export or share only when you choose.
View on the App Store →VS CodeEdit next to your code
The Apollon extension stores diagrams as .apollon files in your repository — versioned and reviewed alongside the code.
What you get
13 diagram types
Class, Object, Activity, Use Case, Communication, Component, Deployment, Petri Net, Reachability Graph, Syntax Tree, Flowchart, BPMN, and SFC.
Export anywhere
SVG, PNG, PDF, and JSON — from a mounted editor or a headless model; the web app adds PPTX slides. Round-trips through JSON without loss.
Real-time, opt-in
Multi-user editing via Yjs over any transport you already run — WebSocket, WebRTC, or BroadcastChannel.
Where to next
Library
Embed @tumaet/apollon in your product. API reference, quickstart, and per-framework guides.
Read the Library docs →User Guide
Draw diagrams on iPhone and iPad, in the hosted app, the VS Code extension, or a self-hosted instance.
Open the User Guide →Contributor
Build Apollon from source, run the monorepo locally, and contribute changes back.
Start contributing →