Excalidraw file and clipboard format
Understand Excalidraw scene files, image data, clipboard payloads, and element timestamps.
This reference explains the plaintext JSON used for local .excalidraw scenes and the related clipboard payload. Use it when you persist scenes, inspect imported data, or build integrations that copy elements between applications.
Scene file structure
An Excalidraw file is plaintext JSON with scene elements, editor state, and image data. The top-level shape is:
| Field | Type | Meaning |
|---|---|---|
type | "excalidraw" | Identifies the Excalidraw schema. |
version | number | Schema version. |
source | string | Source application URL, documented as https://excalidraw.com. |
elements | ExcalidrawElement[] | Drawable objects on the canvas. |
appState | object | Editor state and canvas configuration. |
files | object | Image data keyed by file ID. |
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [],
"appState": {
"gridSize": 20,
"viewBackgroundColor": "#ffffff"
},
"files": {}
}The schema version identifies the serialized format; it is not a package version. Preserve the fields you do not own when reading and writing a scene, and use the package's load and restore utilities to normalize data instead of hand-editing element properties.
Image data
The files object uses file IDs as keys. Each image-data value can include a MIME type, ID, data URL, and timestamps.
{
"files": {
"file-123": {
"mimeType": "image/png",
"id": "file-123",
"dataURL": "data:image/png;base64,REDACTED_EXAMPLE",
"created": 1690295874454,
"lastRetrieved": 1690295874454
}
}
}Treat data URLs as binary content, not as a place for secrets or personal data. When exporting a scene containing images, pass the files map so the export utility can resolve the image elements.
Element creation timestamps
Every normalized element has a created field with type number | null. A number is the client's wall-clock creation time in epoch milliseconds; null means the creation time is unknown.
| Operation | Result for created |
|---|---|
| Construct a new element | Current time unless explicitly supplied, including null. |
| Duplicate, paste, or insert from a library | New time for the new instance. |
| Convert a skeleton with ID regeneration | New time for each resulting instance. |
| Restore, open, or import an existing scene | Preserve the carried value; missing values become null. |
| Edit, capture, undo, or redo while retaining the ID | Preserve the value. |
Do not use created as a server-authoritative audit timestamp. It is generated on the client and can be unknown in older data.
Clipboard payloads
Clipboard JSON is similar to the scene format but represents copied elements and their associated files rather than a complete saved scene. The editor also reads and writes text, HTML, image, PNG, SVG, and plain-text clipboard paths depending on the browser event and available APIs.
The diagram is a compact model of the parser: structured JSON becomes elements and files; other content follows the browser's text, HTML, or image handling path.
parseClipboard attempts to parse JSON and checks whether it contains elements. For a plain paste, it can also expose the serialized elements as text. If structured parsing fails, it returns the parsed text instead. copyToClipboard serializes non-deleted elements and optional files into Excalidraw clipboard JSON and writes it to the system clipboard.
Load and restore safely
Use loadFromBlob for a saved scene blob, then restore imported elements before applying them to an existing scene. Use restoreElements with repairBindings when imported binding relationships may be stale, and normalizeIndices when data may contain old or overly long fractional indices. See Export and restore utilities reference for signatures and defaults.
Troubleshooting
The file opens but an image is missing
Cause: the files object is absent or does not contain the image's file ID. Fix: preserve the complete files map when serializing and loading, then verify the image element's file ID matches a key in files.
Pasting inserts text instead of elements
Cause: the clipboard data did not contain valid Excalidraw element JSON, or the browser exposed only plain text. Fix: copy with the editor's structured clipboard path, check browser clipboard permission, and retry. If structured data is unavailable, handle the returned text path explicitly.
Clipboard copy fails
Cause: browser permissions or unsupported clipboard APIs. Fix: catch the copyToClipboard rejection and offer a .excalidraw download or image export as a fallback. The user-facing failure can appear as “Couldn't copy to clipboard.”
Timestamps change after importing a scene
Cause: the data was converted into new elements with ID regeneration rather than restored as existing elements. Fix: use the restore path for existing data and verify that created is preserved or remains null when it was unknown.
An imported arrow no longer binds to its text
Cause: the imported scene has stale or missing binding references. Fix: restore with repairBindings: true, then verify both the container and bound-text references before updating the scene.
Next step
To create or inspect the elements inside these structures, see Element data and creation reference. To export or restore the complete scene, see Export and restore utilities reference.