Your Infinite Canvas Is a Folder of Notes: How JSON Canvas Made the Whiteboard a Plain File
An infinite canvas does not have to be a database only one app can read. Since March 11, 2024 it can be a plain file, sitting next to your notes — a .canvas document holding two arrays, nodes and edges, in a JSON shape any conforming tool can parse. The name of the shape is JSON Canvas.
The spec's homepage states the thesis in ten words: "an open file format for infinite canvas data."1 It was created by the Obsidian team, released alongside the reference implementation, and open-sourced under the MIT license.23 The stated goal is the same page's second paragraph: "to provide longevity, readability, interoperability, and extensibility" and "give users ownership over their data."1 In practice, the whiteboard on your screen is no longer a rented view into a rented database. It is a text file you can cat, grep, diff, back up, and hand to a different renderer without asking anyone for permission.
What JSON Canvas actually is
JSON Canvas is an open file format, published at jsoncanvas.org, for the "infinite canvas" pattern — the digital-whiteboard interface popularised by apps like Obsidian Canvas, Muse, Scrintal, Heptabase, and tldraw. Its spec sits at version 1.0, dated 2024-03-11, and defines two top-level arrays: nodes and edges. That is the whole schema.4
Structurally, the format is one paragraph long. Everything else — the four node types (text, file, link, group), the coordinate fields (x, y, width, height), the connection fields (fromNode, fromSide, toNode, toSide) — is layered on top of those two arrays. The spec is short enough to read in one sitting, and small enough to hand-write in a text editor.
The design goal is stated explicitly on the spec homepage: "The format is designed to be easy to parse and give users ownership over their data."1 Ownership, in this context, is a technical claim: the file lives on your disk, in a public format, in bytes you can read. It does not require an account, a subscription, or a network round-trip to render — the schema is public, the artifact is text.
Why the spec exists at all
Obsidian shipped Canvas in December 2022 as a .canvas file inside your vault; the file was already open. Sixteen months later, on March 11, 2024, the team published the format as JSON Canvas — a spec any app can implement and any user can read. The announcement is direct about the motive.
"For the release of Obsidian Canvas we created the
.canvasformat with an open spec. We created this format because we felt it was essential to follow the principles that have guided us since the start. Your Obsidian data should always be stored locally, accessible offline, completely in your control, in open file formats that are easy to retrieve and read."2
That is the ally paragraph of this entire piece. Steph Ango, Obsidian's CEO, had argued the philosophy on his own site the year before, in a short essay called File over app. He put the whole discipline in two lines.
"File over app is a philosophy: if you want to create digital artifacts that last, they must be files you can control, in formats that are easy to retrieve and read."5
"In the fullness of time, the files you create are more important than the tools you use to create them. Apps are ephemeral, but your files have a chance to last."5
Read those two sentences carefully. They are the reason the whiteboard — the ultimate app-shaped artifact, the thing that only exists on a screen — got a plain-text spec. The philosophy said data must be a file you control; the canvas was the last non-file surface in the vault; JSON Canvas closes the gap. It is not marketing language. It is a debt the Obsidian team paid down. The spec's HN launch drew 841 points and 164 comments on 11 March 2024, and it resurfaced 130 / 38 on 30 March 2026, because ownership-minded readers keep circling back to it.6
The whole shape in one file
A .canvas file's shape fits in your head; the fastest way to see that is to look at a minimal one. Below is the smallest complete document the spec allows — two text boxes, one arrow — with every field the schema requires. Save it as hello.canvas and any conforming app can open it. Every other canvas is this shape, scaled up.
{
"nodes": [
{
"id": "a",
"type": "text",
"x": 0,
"y": 0,
"width": 240,
"height": 80,
"text": "The whole canvas is a plain file."
},
{
"id": "b",
"type": "text",
"x": 400,
"y": 0,
"width": 240,
"height": 80,
"text": "Nodes and edges. That is the schema."
}
],
"edges": [
{
"id": "a-b",
"fromNode": "a",
"fromSide": "right",
"toNode": "b",
"toSide": "left"
}
]
}
Figure: A minimal .canvas file. Two text nodes, one edge from the right side of node a to the left side of node b. Every canvas — no matter how large — is this shape scaled up.
The spec fills in the details. From the Nodes section: "Nodes are objects within the canvas. Nodes may be text, files, links, or groups."4 From the Edges section: "Edges are lines that connect one node to another."4 Four node types, one edge type, coordinates in pixels, IDs as strings — and you are done reading the schema.
The four node types, in one table
The node-type surface is small enough to fit in a single table. This is the shape a reader needs to keep in mind while walking a .canvas file. Each row is drawn from the Nodes section of the v1.0 spec, and every row shares the base positional fields — x, y, width, height, color, id — on top of the type-specific fields listed.4
type | What it holds | Extra fields | Example use |
|---|---|---|---|
text | A Markdown string, inline. | text | Sticky note; a heading; a paragraph you sketched on the canvas. |
file | A path to another file in the vault (typically .md or an image). | file, optional subpath | Embed an existing Markdown note as a box; embed an image. |
link | An external URL. | url | A pinned reference to a webpage. |
group | A background container for other nodes. | label, background, backgroundStyle | A labeled region — "backlog," "in progress," "done." |
Two takeaways sit inside that table. First, position is data — coordinates are just numbers you can read. Second, a file node is a reference to a .md in the same directory, not an inline copy of it. The canvas is not a snapshot of your notes; it is a spatial index that points into them.
How to walk through a canvas by hand
Once you know the shape, a five-minute drill proves to you that the whiteboard on your screen is text on your disk. The steps below use only standard Unix and git tools — no vendor tooling — and they work on any .canvas file. Do the drill once and the frame flips: the canvas UI is a view over a JSON document, and the document is the artifact you own.
1. Open the file in a text editor. Any editor that can read .json can read .canvas — the extension is just labeling. cat mycanvas.canvas | python3 -m json.tool pretty-prints it. You have just proved to yourself that your whiteboard is text.
2. Read the two arrays. Skim the nodes array; count how many are type: "text" versus type: "file". That number tells you how much of the canvas is original writing on the canvas versus pointers to notes that exist as their own files. The higher the second number, the more of your thinking is already living as plain Markdown, not as canvas payload.
3. Look up a file node. Pick one, follow the file path to the referenced .md, open it. You will find a normal Markdown note. The canvas did not eat it; the canvas just knows where it sits.
4. Diff two versions. Commit the .canvas file to a git repo, move a box in the app, save, and git diff. You will see the exact x and y coordinates change. A drawn diagram cannot do this; a text file can. Every whiteboard movement becomes a line-level diff you can review, revert, or annotate.
5. Change a node in a text editor and reopen. Edit a text node's text field, save the file, and re-open the canvas in your app. The change is there. The app read your text; there is no proprietary layer in the middle. That is what "open file format" means, mechanically.
Common mistakes people make about the format
Three misreadings show up whenever this topic comes up, and each is worth pinning down before it hardens into folklore. They are not opinions — each has a specific primary-source correction that the announcement, the spec, or the repository will resolve on inspection. The three are: "the spec is marketing," "cross-app portability is theoretical," and "this is just Excalidraw."
1. "JSON Canvas is Obsidian marketing." The spec lives on an independent domain, jsoncanvas.org, the reference repository is public at github.com/obsidianmd/jsoncanvas under the MIT license, and the announcement is explicit that the resources are "open source under the MIT license" and that JSON Canvas "can be implemented freely as an import, export, and storage format for any app or tool."2 The repository sits at 3,500+ stars on a codebase created in February 2024. That is a spec, released by its originator, in the same pattern as CommonMark, Mermaid, and Google's Open Knowledge Format.7
2. "Cross-app portability is theoretical — name three apps that read it." A fair pressure. The spec is two years old and Obsidian is the reference implementation; broad-ecosystem adoption is not the pitch. The pitch is more modest and more durable: even if only one app renders the file today, the file itself is a text you can read tomorrow, on any operating system, without that app. Interoperability is upside; ownership of the bytes is guaranteed.
3. "This is just Excalidraw's .excalidraw, which is also JSON." Both files are plain-text JSON. The distinction is scope: .excalidraw is Excalidraw's own schema — one app's format, made public. JSON Canvas is a cross-tool interoperability spec — multiple apps can implement the same shape. Both are honest "plain file" stories; JSON Canvas is the one with cross-tool ambition in the design. Neither is a "vendor blob."
How this works in MNMNOTE
MNMNOTE opens the folder your notes live in as plain Markdown. It does not render JSON Canvas natively today: a .canvas file that sits in that folder is treated as any other plain-text file in the directory — you can open it, read the JSON, edit coordinates by hand, and check it into version control alongside your .md notes.
What the directory shape gives you is the substrate. A folder of .md files with a .canvas sidecar is exactly the arrangement JSON Canvas was designed for — nodes of type: "file" point at Markdown notes in the same directory by relative path. The renderer is a nice-to-have. The folder is the guarantee.
Where the format ends — the honest limits
JSON Canvas is a small, careful spec, and Obsidian is transparent about what it does not try to do. The announcement puts the carve-out in one sentence.
"The current spec is relatively conservative, it does not support every feature that canvas apps may want to implement. However we think it is a useful starting point to build upon, and we plan to continue improving on it over time."2
Four limits fall out of that.
- It is a data format, not a rendering engine. Cross-app portability preserves your content — the nodes, their positions, the edges, the text inside — not per-app polish. Custom fonts, tag colors, and stylised node shapes are the drawing app's job; the file guarantees the picture can be reconstructed, not that it looks pixel-identical everywhere.
- Not every canvas app implements JSON Canvas. Excalidraw's
.excalidraw, tldraw's.tldr, and the vendor DBs behind Muse, Scrintal, Heptabase, and Miro are each their own thing. Portability across the whole category is not universal — but the option exists wherever an app reads the spec, and any of those files that is plain JSON is still a text you can read outside the app. - A
.canvasfile is a snapshot, not magic. The file lives on your disk. You still need to back up the directory it sits in, the same way you back up the rest of your notes — a plain file is only durable if you keep it. - Rendering the spec is engineering work. Two arrays are a tiny shape, but drawing an infinite-canvas UI with panning, zooming, and connection routing is real code. The format's promise is that your data outlives the app, not that any app instantly matches the polish of the best one.
Those four caveats are the reason the spec is worth caring about. It does not overclaim; it makes one guarantee — the file survives — and it makes it precisely.
What this pairs with
The text-diagrams half of this argument sits in The Flowchart You Can Diff: How to Keep Diagrams in Your Notes as Plain Text You Own. That piece argues Mermaid inside a fenced code block beats a drawn flowchart for the diagrams the writer can express in text — and it ceded the other axis explicitly: "for spatial maps, hand-drawn whiteboarding, or sketches where where-things-sit is the point, a freeform canvas still wins."8
This post is the completion of that pair. For the spatial canvas the flowchart post ceded, the ownership answer is not "avoid the canvas" — it is give the canvas a plain file too. Mermaid handles text-shaped diagrams; JSON Canvas handles the spatial ones. Two other cross-links matter. Google's Open Knowledge Format is the same shape at data-catalog scale — a directory of Markdown files where the links between files are the graph edges.7 And the general pattern of a small companion file next to .md notes is what we walked through in Sidecar Files Are How You Add Metadata You Own. JSON Canvas is one very well-designed sidecar.
Frequently Asked Questions
What is JSON Canvas?
JSON Canvas is an open file format for infinite-canvas data, published in March 2024 at jsoncanvas.org under the MIT license. The spec fits on one page and describes two top-level arrays — nodes and edges — that together represent a whiteboard as plain JSON. Files use the .canvas extension and can be read, diffed, and edited in any text editor.14
What file format does Obsidian Canvas use?
Obsidian Canvas stores each canvas as a .canvas file inside your vault, in the JSON Canvas format the Obsidian team created and open-sourced. It sits next to your .md notes in the same directory tree, is plain JSON on disk, and can be read by any conforming tool without Obsidian running. Obsidian is the reference implementation of the spec, not its owner.2
Can I move my canvas notes between whiteboard apps?
The source .canvas file is guaranteed portable — plain, readable JSON you can open in any text editor, back up, and check into version control regardless of which app drew it. Whether a destination app renders it depends on whether that app implements the JSON Canvas spec. Ownership of the bytes is guaranteed; broad-ecosystem rendering is upside.2
Is JSON Canvas the same as Excalidraw's file format?
No, though both are plain-text JSON. Excalidraw's .excalidraw is its own app's schema — public, readable, and specific to Excalidraw. JSON Canvas is a cross-tool interoperability spec designed for multiple canvas apps to implement, published under MIT by Obsidian. Both stories are honest "your file is text you can read"; only JSON Canvas is designed as the shared shape.2
Why not just export to PNG?
A PNG of your canvas is a flattened raster: you cannot search inside it, cannot diff it line by line, and cannot edit it in a text editor. A .canvas file keeps every node's text, every position, and every connection as data. The PNG is a dead artifact; the JSON is a living one — the same argument that applies to drawn versus text diagrams.8
Is JSON Canvas a rendering library I can drop into my app?
No. The spec is a data format, not code. There are open-source implementations (starting with Obsidian's under MIT), but rendering an infinite-canvas UI — panning, zooming, edge routing, hit testing — is engineering work you or an existing library does on top of the shape. The spec's contribution is the bytes: your data outlives the tool that drew it.24
What comes after Markdown?
An honest answer is not a new format, but more small, plain-text specs that live next to Markdown. JSON Canvas is one — the whiteboard as a .canvas file. Mermaid is another — the diagram as text inside a fenced code block. The pattern is a directory of Markdown notes with additional plain-text sidecars for the things Markdown itself does not model. The folder is the graph.48
The whiteboard was the last thing in a vault that lived inside a database. It does not have to be. It is a file, next to your notes, in a format anyone can read.
MNMNOTE lives in your browser. It opens a folder of your Markdown notes — the plain files that outlive whichever app drew them: mnmnote.com.
Footnotes
-
"JSON Canvas — An open file format for infinite canvas data," JSON Canvas, https://jsoncanvas.org/, retrieved 2026-07-02. ↩ ↩2 ↩3 ↩4
-
"Announcing JSON Canvas: an open file format for infinite canvas data," Obsidian blog, published March 11, 2024, https://obsidian.md/blog/json-canvas/, retrieved 2026-07-02. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
"obsidianmd/jsoncanvas," GitHub, MIT license, created 2024-02-28, https://github.com/obsidianmd/jsoncanvas, retrieved 2026-07-02. ↩
-
"JSON Canvas Spec, Version 1.0 — 2024-03-11," JSON Canvas, https://jsoncanvas.org/spec/1.0/, retrieved 2026-07-02. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
Steph Ango, "File over app," https://stephango.com/file-over-app, retrieved 2026-07-02. ↩ ↩2
-
"JSON Canvas – An open file format for infinite canvas data" (Hacker News story 39670922, 2024-03-11, 841 points / 164 comments) and "JSON Canvas Spec (2024)" (story 47572288, 2026-03-30, 130 points / 38 comments), via https://hn.algolia.com/api/v1/search?query=jsoncanvas&tags=story, retrieved 2026-07-02. ↩
-
"Open Knowledge Format: When a Folder of Markdown Is the Whole Graph," MNMNOTE blog, https://blog.mnmnote.com/posts/open-knowledge-format-markdown, retrieved 2026-07-02. ↩ ↩2
-
"The Flowchart You Can Diff: How to Keep Diagrams in Your Notes as Plain Text You Own," MNMNOTE blog, https://blog.mnmnote.com/posts/diagrams-that-live-in-your-notes-as-text, retrieved 2026-07-02. ↩ ↩2 ↩3