Compact Design: a JSON language models can write and Figma can import
Don't ask a model to speak Figma's plugin API. Don't ask it for CSS and hope a screenshot is a design. I wanted a format a model can write, a schema can reject, and Figma can turn into native, editable frames. That's Compact Design. It's a small JSON language. @compact-design/core validates, normalizes, lints, and patches it. The Figma plugin is the first adapter. Core never depends on Figma. Repo: github.com/Elliot727/compact-design A card looks like this { "canvas": { "id": "desktop", "name": "Desktop", "width": 1440, "height": 900, "fill": "#F8F5EE" }, "nodes": [ { "id": "card", "type": "FRAME", "x": 48, "y": 48, "w": 320, "h": 200, "fill": "#FFFFFF", "cornerRadius": 16, "layout": { "direction": "VERTICAL", "padding": 24, "itemSpacing": 12 }, "children": [ { "id": "title", "type": "TEXT", "w": 272, "h": 40, "text": "A quieter kind of stay.", "font": { "family": "Arial", "style": "Bold", "size": 24 }, "fill": "#23221E" } ] } ] } Required on a node: w and h. type defaults to FRAME. IDs are generated if you omit them - give anything you'll update later an explicit one. Hex fills. HUG / FILL / FIXED. Angle gradients. Elevation presets. Variables, styles, components, prototypes, images. One current schema. No version soup. This is the input API. Not Figma REST. Not a properties wrapper. Not 24px. What the engine actually does Compact Design JSON β @compact-design/core schema β normalize β semantic checks β lint / patch β adapter β Figma today; another tool can implement the same language Core is ordinary TypeScript. No figma.*, no plugin typings. import { validate, normalize, lint, applyPatch } from "@compact-design/core"; const result = validate(input); if (!result.valid) { console.log(result.issues); } else if (result.document) { console.log(lint(result.document)); } Issues come back structured, which is the point if a model is in the loop: { "valid": false, "issues": [{ "severity": "ERROR", "code": "SCHEMA_VALIDATION", "path": "nodes[0].children[2].layout.direction", "message": "must be HORIZONTAL, VERTICAL, or GRID", "suggestion": "Use the allowed property type or enum from compact-design.schema.json." }] } Schema and semantic errors block import. Lint does not. Lint is advisory: contrast, 44px targets, 4px spacing, missing Auto Layout, hard-coded colours, broken prototype destinations. The plugin does not render a browser thumbnail. A thumbnail would lie about fonts, Auto Layout, masks, and effects. You get counts, matches, and the repair JSON instead. Create, update, patch, export Every imported canvas and layer stores its JSON id as plugin data. β’ Create new refuses a canvas ID already on the page. β’ Update matching IDs replaces matching canvases in place. β’ Replace matching canvases rebuilds them from the document you just supplied. β’ Export selection writes Compact Design JSON back out. Full-document update is canvas-granular. A patch is node-granular. Failures roll back - the previous design is cloned first. { "patch": { "operations": [ { "op": "set", "id": "title", "set": { "text": "The same design.\nA different mood." } }, { "op": "remove", "id": "old-badge" }, { "op": "append", "parent": "card", "node": { "id": "note", "type": "TEXT", "w": 272, "h": 18, "text": "UPDATED WITH A JSON PATCH", "fill": "#B69B62" } } ] } } set changes only what you list. Everything else stays put. Try it The package is not on npm yet. Build from the repo. git clone https://github.com/Elliot727/compact-design.git cd compact-design npm install npm run build In Figma desktop: Plugins β Development β Import plugin from manifestβ¦ and pick plugins/figma/manifest.json. Then paste examples/design-language-showcase.json. It should land as a finished product screen, not an API reference board. Language docs, schema, and the other fixtures live next to it. If you generate UI with a model, this is the format I'd actually trust. Top comments (0)
Comments
No comments yet. Start the discussion.