What converts, and into what
From .canvas to .excalidraw: each text card becomes a rounded rectangle with the card's text bound inside it, at the same position and size. File cards become dashed placeholder cards labelled with the vault path they point at, and link cards become cards that carry the URL as an Excalidraw link. Groups become Excalidraw frames, and any card that sits fully inside a group is placed in that frame. Each connection becomes an arrow bound to both cards, leaving and arriving on the sides the canvas recorded, with its label and arrowheads kept.
From .excalidraw to .canvas: rectangles, ellipses and diamonds become text cards holding whatever text is bound inside them. Free-standing text becomes a text card sized around it. Frames become groups with the frame's name as the label. Arrows bound to two shapes become edges, and the fromSide and toSide values are worked out from where the arrow actually meets each shape, so the connection enters the card from the side you drew it on. Labels on arrows become edge labels.
Colours map both ways. The six JSON Canvas preset colours (red, orange, yellow, green, cyan, purple) become the matching pairs from Excalidraw's palette, and a colour that matches one of those pairs becomes the preset again on the way back. Any other colour is kept as a hex value, which the JSON Canvas spec allows.
What can't make the trip
The two formats don't model the same things, so some things are left out and the converter lists them rather than dropping them without a word. JSON Canvas has no freehand strokes, images, standalone lines or rotation, so going to .canvas those are counted and reported instead of converted. Arrows that aren't connected to two shapes are counted too, though an arrow whose end lands on a shape without being bound to it is attached to that shape. Ellipses and diamonds become rectangular cards, because every JSON Canvas card is a rectangle.
Going to .excalidraw, the losses are smaller. Text cards keep their Markdown as plain text, since Excalidraw doesn't render Markdown. File cards keep only the path: the note itself lives in your vault, not in the .canvas file, so there is nothing else to convert. Excalidraw frames can't sit inside other frames and arrows can't attach to frames, so nested groups become separate frames and a connection that ends on a group is left unattached at that end. You get a warning when either of these happens.
Round trips without losing structure
When this tool converts a .canvas file, it writes the original node ids, file paths, URLs, colours and edge sides into each Excalidraw element's customData. Excalidraw keeps that data when you edit and save the drawing. If you later convert the drawing back to .canvas, the original file cards, link cards, group labels and connection sides come back, not a generic approximation of them.
That makes a workable loop: sketch around an Obsidian canvas in Excalidraw, then bring it back into your vault as a .canvas file. Elements you add in Excalidraw convert the ordinary way, and the ones that came from the canvas keep their identity.
Using the converted file
To open a converted .excalidraw file, drag it onto excalidraw.com or use Open in its main menu. The community Excalidraw plugin for Obsidian saves drawings as .excalidraw.md Markdown files by default. Those wrap the scene in Markdown, so this tool doesn't read them directly: use the plugin's export to save a plain .excalidraw file first.
To use a converted .canvas file, put it anywhere in your Obsidian vault and it opens as a canvas. Because JSON Canvas is an open, MIT-licensed format, other apps that support the spec can open it as well. If you only want to look at a canvas rather than convert it, the JSON Canvas viewer draws it in the browser, and the Excalidraw viewer does the same for .excalidraw files.