floorianmb117 downloadsRender sandboxed, theme-aware interactive charts, diagrams and dashboards from viz code blocks, designed to be written by AI agents.
Interactive charts, diagrams, dashboards and formulas right inside your notes.
Offline, in your vault's theme, safely sandboxed – and built so Claude Code and Codex can render, check and fix what they write.
Now as a community plugin! Here: https://community.obsidian.md/plugins/prism-viz
Install · Quickstart · With AI agents · Features · Privacy · Example vault
A dashboard built from a plain Markdown table in the same note. Edit the table and the charts follow.
![]() No-code charts: a YAML spec pointing at a table |
![]() Explorable explanations: a slider in one block drives a chart in another |
![]() Scenes: prism.canvas + prism.animate, paused off screen |
![]() Your vault as data: prism.notes() over frontmatter |
![]() Mermaid: [[links]] in nodes open the note |
![]() Formulas: KaTeX, offline, with mhchem |
![]() Scrollytelling: the chart follows the section you are reading |
![]() Tasks across the vault: prism.notes({ include: ["tasks"] }) |
![]() Live API data (opt-in): prism.http.json, sent by Obsidian, no CORS |
![]() Charts from web APIs: cached in prism.state, every loading state handled |
![]() Web pages (opt-in): ```viz web as a desktop webview, works for sites that refuse framing |
![]() …or as an iframe: mode: iframe, also on mobile |
All of these are in the example vault, together with variants, a link graph, the page monitor, a Bases chart and an HTML widget. Screenshots are real renders in Obsidian's default dark theme.
```viz block, renders the note from the command line and gets back errors with note line numbers plus a PNG snapshot. It fixes the block until the render is clean, with no copy-pasting screenshots back and forth. A ready-made skill teaches Claude Code and Codex how to do it.From the community plugins (recommended)
With BRAT (for beta versions)
floorianmb/prism-viz.Manually
main.js, manifest.json and styles.css from the latest release.<your vault>/.obsidian/plugins/prism-viz/.Just looking? Open the examples/ folder as a vault. It has a note for every feature.
Put a table in a note and add a chart below it. No code needed:
| Month | Notes | Tasks done |
| ----- | ----: | ---------: |
| Jan | 34 | 21 |
| Feb | 41 | 29 |
| Mar | 57 | 38 |
^stats
```viz chart title="My vault in Q1"
type: bar
source: ^stats
x: Month
```
Change a number in the table and the chart updates. Want more? A ```viz block takes any HTML, SVG and JavaScript, with the bundled libraries and a prism API for your notes:
```viz chart title="Notes by type"
<canvas id="c"></canvas>
<script>
prism.notes().then(notes => {
const counts = {};
for (const n of notes) { const t = n.frontmatter.type ?? "(none)"; counts[t] = (counts[t] || 0) + 1; }
new Chart(c, { type: "bar", data: { labels: Object.keys(counts), datasets: [{ data: Object.values(counts) }] },
options: { plugins: { legend: { display: false } } } });
});
</script>
```
Or start from a template: Prism: Insert starter (dashboard, architecture diagram, timeline, chart from frontmatter, chart from a table, formula).
Install the skill. Prism opens a page with the install command for your vault after you install or update it; open it again any time with Prism: Install agent skill. On macOS/Linux the command is:
d="$(mktemp -d)" && git clone --depth 1 https://github.com/floorianmb/prism-viz.git "$d" && node "$d/scripts/install-skill.mjs" --vault '/path/to/your/vault' && rm -rf "$d"
It copies skill/ to ~/.claude/skills/prism and ~/.codex/skills/prism (wherever those folders exist) and puts the render script into the vault's plugin folder (the community plugin download only contains main.js, manifest.json and styles.css). From a clone: npm run install-skill -- --vault '/path/to/your/vault'.
For other agents, run Prism: Generate agent rules as well. It writes PRISM.md and a snippet for your CLAUDE.md / AGENTS.md.
Ask for a visualization, e.g. "Add a dashboard of my reading list to Books.md".
The agent closes the loop on its own:
node .obsidian/plugins/prism-viz/scripts/prism-render.mjs "Books.md"
The note renders invisibly in the running Obsidian app. The command prints JSON with every error (note line, origin, message) and the paths of the PNG snapshots, and exits with 0 = ok, 1 = block errors, 2 = render failed, 3 = Obsidian not reachable. The agent fixes the block, looks at the snapshot and renders again until the result is clean.
If something breaks while you are reading, use Copy prompt for agent in the block's menu or error panel. It copies the location, the errors, the source and the render command, ready to paste.
viz code blocks (Live Preview and Reading view): HTML fragment or full document, rendered in an iframe via srcdoc. Info line: library keywords chart, d3, mermaid, three, plus height=N, title="…", id=name, raw, eager, notoolbar, source. All libraries are bundled into main.js.```viz chart block may contain a YAML spec instead of HTML (type, source: ^table-id | table:<heading> | file.csv, x, y, series, filter, sort, stacked …).```viz table renders a searchable, sortable table with locale number formats, source links and confidence badges.```viz math renders LaTeX with KaTeX (offline, fonts inlined, mhchem).A["[[Note]]"] labels open the note on click..base files (Obsidian 1.10+): group by a property, count or aggregate a value, split into series, stacked, sorted.![[file.html]] embeds use the same renderer, and .html files open in a Prism view. Options via <meta name="prism" content="chart height=400">, <!-- prism: … --> or ![[file.html|height=400]].```viz monitor shows RAM and CPU of the page it is on.prism.note() returns the block's own note: frontmatter, headings, links, backlinks, tasks and typed Markdown tables (German number formats, units, – as empty). prism.onNoteChange follows edits.prism.notes({ folder, tag, limit, sort, order, include }) queries the vault (read-only path, title, tags, frontmatter, mtime). include: ["links", "backlinks", "headings", "tasks"] adds those per note, and tasks carry Tasks-plugin dates and priorities. prism.onNotesChange fires on changes.prism.data("folder/file.csv") reads CSV/TSV (row objects, column-wise typed), JSON/GeoJSON, YAML and TXT. Access is read-only and limited to the folders listed under Data folders in the settings (empty = off; notes and hidden files are never readable). prism.dataFiles(folder?) lists them, prism.onDataChange(cb) follows changes, and prism.parseCsv(text) parses inline CSV.prism.shared is state shared by all blocks of a note. prism.state.bind / prism.shared.bind two-way bind form controls, so a slider in one block can drive charts in others.prism.onSection(cb) reports the heading the reader is at while scrolling.prism.variants shows alternative views of the same content with a persisted switcher.prism.canvas (crisp canvas that follows its element), prism.animate (frame loop with real elapsed time that pauses off screen and respects reduced motion), prism.segmented (persisted segmented control) and the classes .toolbar, .stage, .hud, .chip, .icon-button, .caption.prism.state.get/set/delete is stored in the plugin data, and localStorage is shimmed onto it.obsidian://prism?render=<note path>[&id=…&snapshot=0&width=720&timeout=60] renders every viz block of a note (or an HTML file) invisibly in the running app and writes .prism/renders/<id>.json and latest.json (status, errors with note lines, snapshot paths). The CLI scripts/prism-render.mjs wraps it. --all [folder] renders every note with viz blocks and prints a summary. On macOS Obsidian stays in the background.window.onerror, unhandled rejections, console.error, CSP violations, Mermaid errors and timeouts show up as a badge and are written to <vault>/.prism/errors.json with note path and line numbers. Optional PNG snapshots go to .prism/snapshots/.skill/): SKILL.md with the plan → write → render → fix workflow, design.md with the quality bar, and reference.md with the full API. Prism: Install agent skill shows the install command for your vault..card, .grid, .row, .kpi, …) are included; opt out with raw. Chart.js and Mermaid follow the theme automatically.ResizeObserver, cached per block so re-renders do not jump.docs/pinch-zoom.md.prism.hoverNote for canvas/SVG hit areas). Blocks know about fullscreen via prism.displayMode..html, copy source / errors and Copy prompt for agent.sandbox="allow-scripts" (no same-origin, top navigation, popups, forms or modals) and the CSP default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data: blob:; font-src data:; plus base-uri/form-action 'none'. Messages are accepted only from the block's own frame with a per-render token, and navigation away from the srcdoc is detected and reverted.prism.http, requests wait for a click by default) and Web pages (```viz web blocks, iframes). Turning either on shows the consequences and asks for confirmation.The complete API is documented in skill/reference.md.
Default height, maximum auto height, theme sync, lazy rendering, error log, snapshots, data folders, network allowlist and online access.
Prism works offline and does not connect to the internet unless you turn that on yourself.
main.js. Nothing is downloaded at runtime, and the plugin never installs or updates code on its own.prism.http through Obsidian's requestUrl, to show live data. By default nothing is sent until you click Run requests below the block.```viz web blocks and <iframe>s may show web pages inside a note.```viz block runs the HTML and JavaScript written in the note, in a sandboxed iframe (scripts only, strict CSP, no direct access to Obsidian or your vault, and no network beyond what you allow above). Only use blocks from sources you trust, as with any code you run..prism/ (error log, render results, snapshots), plus files you create on purpose (exports, PRISM.md from Generate agent rules). Only the install script for the agent skill (scripts/install-skill.mjs) writes outside a vault (~/.claude/skills, ~/.codex/skills), and only when you run it yourself in a terminal; the plugin just shows the command.prism.notes() (names, tags, frontmatter, links, tasks), to list data files and to find blocks for the gallery and command-line renders, Prism goes through the file list of your vault. That metadata only goes to blocks in your own notes and never leaves Obsidian.data.json.npm install
npm run build # type-check, bundle the libraries and main.js, generate skill/reference.md
npm run dev # watch mode
The runtime files are manifest.json, main.js and styles.css. Pushing a tag that matches the manifest version (e.g. 0.3.0) builds them and publishes a GitHub release.
main.ts plugin: code block processor, commands, notes query, exports, snapshots
src/frame.ts one rendered block: iframe lifecycle, message bridge, toolbar, errors, watchdogs
src/document.ts srcdoc builder (CSP, theme, base CSS, libraries) and line map
src/runtime/prelude.ts iframe runtime (window.prism), bundled to a string at build time
src/runtime/chartSpec.ts declarative chart spec → Chart.js config
src/runtime/table.ts interactive table for ```viz table / prism.table
src/noteInfo.ts note tables, headings and tasks for prism.note() / prism.notes({ include })
src/basesView.ts "Prism chart" view for Obsidian Bases
src/loopGuard.ts infinite-loop instrumentation (acorn)
src/theme.ts Obsidian theme → CSS variables
src/errorLog.ts .prism/errors.json
src/htmlFile.ts .html view and embeds
src/data.ts data file path resolution and allowlist
src/perf/ page monitor: block stats, Electron process metrics
src/online/ opt-in network access: settings + consent, prism.http, ```viz web blocks
scripts/prism-render.mjs CLI for agents (render a note, print JSON)
scripts/build-skill.mjs skill/reference.md from src/agentRules.ts (part of npm run build)
scripts/install-skill.mjs installs skill/ for Codex and Claude Code (+ prism-render.mjs into --vault)
examples/ example vault with a note per feature
docs/pinch-zoom.md how pinch zoom works (host transform, gesture messages, clamping)
errors.json reflects the last render, either when a block was visible in Obsidian or via obsidian://prism?render=…. The render command needs the desktop app (it launches Obsidian if it is not running).![[file.html]] embeds use Obsidian's internal embed registry. If it is unavailable, embeds fall back to Reading view only.preserveDrawingBuffer: true, and export needs the block to be visible.MIT, see LICENSE. Third-party licenses: THIRD_PARTY_LICENSES.txt.