Polotno

JSON FORMAT

JSON import and export

Polotno stores every design as an open, human-readable JSON document. Export, modify, and re-import designs programmatically — built for templates, data-driven generation, and LLM-driven workflows.

Every Polotno design is a single JSON document — open, human-readable, and stable across SDK versions. Export a design with one call, modify it programmatically, feed it to an LLM, or build one from scratch and re-import. The same format covers everything from manual saves to large-scale automation.

How import and export work

Polotno exposes two methods on the store:

ts
// Export — produces a plain JSON object
const json = store.toJSON();

// Import — accepts the same shape back
store.loadJSON(json);

Both work client-side and server-side. The output of toJSON() is a valid input to loadJSON() — round-trip is lossless. Use this for saving, transferring, transforming, generating, or rendering designs.

Why JSON, not a proprietary format

Most design tools store work in opaque binary formats: Photoshop's .psd, Figma's .fig, Sketch's .sketch. Those files are unreadable without the originating tool. They're expensive to parse, impossible to diff, and trap your work inside a single vendor.

Polotno designs are plain JSON. That choice has practical consequences:

  • You can read your own data. Open any export in a text editor and understand what's in it.
  • You can diff it. Two designs differ by exact field-level changes. Version control works.
  • You can transform it. Any language with a JSON parser can edit a Polotno design — no SDK call required.
  • You're not locked in. If you stop using Polotno, the JSON is still yours and still parseable.
  • It survives. JSON is a 25-year-old IETF standard. It will outlive any single design tool.

What a Polotno design looks like

A Polotno design is a Store object containing one or more Pages, each containing Elements (text, image, video, shape, group, line, table). A minimal example:

json
{
"width": 1080,
"height": 1080,
"pages": [
  {
    "id": "page-1",
    "children": [
      {
        "type": "text",
        "x": 100,
        "y": 100,
        "text": "Hello, world",
        "fontSize": 48,
        "fontFamily": "Inter"
      },
      {
        "type": "image",
        "x": 100,
        "y": 250,
        "width": 880,
        "height": 600,
        "src": "https://example.com/photo.jpg"
      }
    ]
  }
]
}

That's the whole design. Load it into Polotno with store.loadJSON(json) and you'll get a fully editable canvas with the text and image already placed. Export it back out with store.toJSON() and you'll get the same structure, with any edits applied.

The complete field reference — every element type, every property, every default — is published as a JSON Schema at polotno.com/docs/schema, generated from the same source the SDK uses internally.

Designed for LLMs and AI agents

The fastest-growing use of Polotno's JSON format is AI-driven design generation. Because the format is text, schema-validated, and self-documenting, it's the kind of output an LLM can produce reliably.

A typical pattern:

ts
// Prompt the model with the JSON Schema + a design brief.
const designJson = await llm.complete({
system: polotnoJsonSchema,
prompt: 'Design a square Instagram post announcing 30% off.',
responseFormat: 'json',
});

// Validate, then render.
validate(designJson, polotnoJsonSchema);
const blob = await renderFromJson(designJson);

What makes this work in practice — and not just in demos:

  • The output is verifiable. You can validate generated JSON against the schema before rendering — bad output is rejected at the boundary, not at render time.
  • Few-shot examples help. Including a handful of valid Polotno designs in the prompt can guide the model toward usable output — results vary by model, task, and complexity.
  • Round-tripping is lossless. An LLM can read an existing design, modify one field, and emit the result. Polotno re-renders it identically.

Common AI workflows customers build on top:

  • Brief-to-design agents — natural language to finished design.
  • Variant generation — one base design, dozens of localized or personalized variants.
  • Brand-bound generation — constrain the model to your design tokens (fonts, colors, logo positions) and let it fill in the rest.
  • Inline editing — "make the headline bigger and move the logo to the top-right" as a prompt against existing JSON.

Programmatic generation (without an LLM)

JSON-as-source also makes traditional automation simple. Generate designs from a CSV, a database query, a CMS export — anything you can map to fields.

ts
const designs = products.map(product => ({
...templateJson,
pages: templateJson.pages.map(page => ({
  ...page,
  children: page.children.map(el =>
    el.id === 'product-name' ? { ...el, text: product.name } :
    el.id === 'product-photo' ? { ...el, src: product.image } :
    el
  ),
})),
}));

await Promise.all(designs.map(json => renderFromJson(json)));

No editor needed. No headless browser. Pure data transformation.

Round-trip safety

store.toJSON() and store.loadJSON() are exact inverses. Export a design, re-import it, export again — the second JSON describes the same design as the first. This guarantee is what makes templates, version control, and AI-driven editing all viable.

Versioning, diffing, Git

Because designs are JSON, every workflow that exists for source code works for designs:

  • Commit designs to Git. Diff them in pull requests.
  • Store revisions in your database without binary blobs.
  • Snapshot a brand system and roll forward safely.
  • A/B test variants by changing one field at a time.

The schema as a contract

Polotno publishes its full JSON Schema at /docs/schema. Every element type — TextElement, ImageElement, VideoElement, SVGElement, LineElement, GroupElement, TableElement, GifElement, FigureElement — has its own page with all properties, types, and defaults. The schema is generated from the same source code the SDK uses, so it never drifts from reality.

Use it as:

  • A reference for hand-written design code.
  • A system prompt for LLM-driven generation.
  • A validation target before rendering.
  • A spec your own tools can compile against.

How it compares

PSDFigma .figPolotno JSON
FormatBinaryBinaryJSON
Human-readableNoNoYes
Diff in GitNoNoYes
Parse without SDKHardHardYes
LLM-friendlyNoNoYes
Public specPartialClosedPublished schema

FAQs

Can I generate a Polotno design entirely in code, without using the editor?

Yes. You can construct a valid JSON document from scratch and render it via the Cloud Render API or self-hosted rendering. The editor is optional.

Is the JSON format stable across SDK versions?

Yes. Polotno maintains backward compatibility on the JSON format. New fields are additive; older designs continue to render correctly on newer SDK versions.

Can I validate a design before rendering it?

Yes. The JSON Schema is published and works with any standard JSON Schema validator (Ajv, JSON Schema CLI, etc.).

How big are typical Polotno designs?

A simple design is a few KB. Complex multi-page templates can reach 100 KB or more. Images and videos are referenced by URL, not embedded, so payload size stays manageable.

Can I use Polotno JSON without Polotno?

The format is open and the schema is published. Most customers use Polotno's rendering, but the JSON is yours and the spec is on the public web.

Embed creative infrastructure into your product

TRUSTED BY

100,000+

CREATORS

300+

BUSINESSES

ExpediaUnbounceLovePopPostGridPredis.ai