Import a Figma local copy or REST file into a CE.SDK scene for continued editing.
The @imgly/figma-importer package runs in Node.js 22.15 or later (23.x requires 23.8+) alongside @cesdk/node. A Figma canvas becomes one CE.SDK scene. The engine holds one scene at a time, so save its archive before importing another canvas.
The downloadable recipe imports a bundled local sample without Figma credentials. Set FIGMA_INPUT to the path of your own .fig, or set FIGMA_FILE_KEY and FIGMA_TOKEN for REST import. A file key selects the REST path when both inputs are configured. Run the recipe with its dev script.
This guide covers input selection, canvas selection, source preservation, diagnostics, and archive saving.
Import the Package and Initialize the Engine#
Install @imgly/figma-importer alongside @cesdk/node and import the two entry points. Both inputs use the same scene mapper.
import { importFig, importFigmaFile } from '@imgly/figma-importer';We load optional environment variables and initialize the engine. To use your CE.SDK license, set CESDK_LICENSE and uncomment the license setting.
config();const engine = await CreativeEngine.init({ // license: process.env.CESDK_LICENSE, baseURL: process.env.IMGLY_LOCAL_ASSETS_URL});Choose the Canvas and Preservation Options#
Set FIGMA_CANVAS to a zero-based index or a canvas name. The recipe defaults to index 0. The returned canvases list contains every available name, and canvas identifies the one loaded. Use an index to distinguish canvases with duplicate names.
const selectedCanvas = process.env.FIGMA_CANVAS ?? '0';const options = { canvas: /^\d+$/.test(selectedCanvas) ? Number(selectedCanvas) : selectedCanvas, preserveFigmaData: process.env.PRESERVE_FIGMA_DATA !== 'false'};The importer keeps available source-specific information as JSON-valued x-figma/… metadata by default. Set PRESERVE_FIGMA_DATA=false to omit that metadata. Supported content still imports, but unmapped information is unavailable to the companion exporter.
Import a Local Copy#
In Figma, choose File → Save local copy. Read its bytes and call importFig() with the canvas and preservation options.
const input = process.env.FIGMA_INPUT ?? new URL('./assets/sample.fig', import.meta.url);const bytes = await readFile(input);return importFig(engine, bytes, options);The bundled assets/sample.fig was generated by the companion exporter and saved again by Figma. It demonstrates format compatibility; it does not represent the full range of independently authored Figma designs.
Import Through the REST API#
Use the file key from the Figma file URL and a token with access to that file. token defaults to the server’s FIGMA_TOKEN environment variable when omitted.
return importFigmaFile(engine, { fileKey, token: process.env.FIGMA_TOKEN, ...options});The options also accept nodeIds to request subtrees with their ancestor chains, a custom fetch, concurrency, and retry settings. Rate-limit responses use Retry-After with bounded retries. File permissions and Figma quotas still apply. Unavailable image fills produce placeholders and conversion notes.
Keep the token on the server. The package uses Node modules and cannot be imported directly into a browser bundle. For browser editing, a Node endpoint imports the file and returns an .imgly archive that the editor loads.
Review Conversion Notes#
We record the selected canvas, all canvas names, and typed messages in output/import-report.json. Inspect warnings and errors before relying on the imported design.
const outputDir = new URL('./output/', import.meta.url);await mkdir(outputDir, { recursive: true });const messages = result.logger.getMessages();console.log('Loaded canvas:', result.canvas);console.log('Available canvases:', result.canvases);for (const message of messages) { console.warn(`${message.type}: ${message.code} — ${message.message}`);}await writeFile( new URL('import-report.json', outputDir), JSON.stringify( { canvas: result.canvas, canvases: result.canvases, messages }, null, 2 ));Supported text, shapes, images, and styles become editable content. Auto-layout becomes absolute placement. Component instances become independent content, and component links and constraints do not become live CE.SDK behavior. Supported local instance text and style overrides are applied, including nested instances.
Ordinary frames become groups, which cannot clip overflowing children to the original frame bounds. The importer reports FRAME_CLIPPING_UNSUPPORTED for clipped containers with children. Masks and unsupported styles can also differ visually.
Preservation is best effort and depends on what the local file or REST response supplies. It does not guarantee identical files, fonts, or renders. On export, current engine state controls mapped properties; supported metadata supplies unmapped properties.
Save an Archive#
Wait for resources, then bundle the scene and accessible assets into output/design.imgly. A resource-loading failure rejects the wait; inspect the failing resource before retrying.
await engine.block.forceLoadResources([result.scene]);const archive = await engine.scene.saveToArchive();await writeFile( new URL('design.imgly', outputDir), new Uint8Array(await archive.arrayBuffer()));Import each additional canvas with a separate call and save each result before continuing. A subsequent import replaces the current scene. See Import From Archive to load the saved design.
Dispose the Engine#
Release the engine in finally so failed imports, resource loads, and file writes also clean up.
engine.dispose();Troubleshooting#
REST credentials are missing or rejected — Supply FIGMA_TOKEN on the server and confirm that it can access the requested file. Local .fig imports need no token.
An API request is rate-limited — Inspect the reported status and retry delay. Use a local copy when a quota prevents REST access.
Fonts or images differ — Review conversion notes and confirm that resources are accessible to the Node process. Missing or substituted fonts can change text layout.
A child extends beyond its frame — CE.SDK groups cannot reproduce ordinary Figma frame clipping. Review the clipping warning and adjust the design when the overflow affects the result.
API Reference#
| Method / Result | Description |
|---|---|
CreativeEngine.init(config) |
Initialize the Node engine |
importFig(engine, bytes, options) |
Import a selected canvas from local bytes |
importFigmaFile(engine, options) |
Import a selected canvas through REST |
result.canvases / result.canvas |
Read available names and the selected canvas |
result.logger.getMessages() |
Read typed conversion diagnostics |
engine.block.forceLoadResources([result.scene]) |
Await scene resources |
engine.scene.saveToArchive() |
Return the scene and accessible assets as a Blob |
engine.dispose() |
Release engine resources |
Next Steps#
Use Export to Figma to hand a CE.SDK scene back to Figma and verify the exported file there.