CreativeEditor SDK (CE.SDK) Headless Mode with native Node.js bindings lets your backend render scenes and exports with native C++ performance.
The @cesdk/node-native package provides CE.SDK’s full feature set through native C++ bindings, delivering better performance than the WASM-based @cesdk/node package.
You orchestrate the same actions a user can do from the UI using the CreativeEngine, which powers all CE.SDK features.
Common Use Cases#
- Automated pipelines: Generate batches of personalized assets from templates.
- Server-rendered previews: Produce thumbnails or proofs before a user ever opens the editor.
- Custom tooling: Embed CE.SDK logic inside CLI tools, workers, or queue processors.
- Compliance and governance: Enforce template rules during backend render jobs without exposing editing controls.
When to Use Headless Mode#
| Scenario | Headless (Node.js Native) | UI-Based Editor |
|---|---|---|
| Cron or queue-driven exports | Yes | No |
| Rendering without a browser | Yes | No |
| Letting users tweak the layout | No | Yes |
| Mixing custom UI with CE.SDK tools | Yes | Hybrid |
How Headless Mode Works with Native Bindings#
@cesdk/node-native provides the same Engine API as @cesdk/node. Without needing a DOM, your script can run server-side to:
- Start the engine.
- Edit and export assets.
You are responsible for:
- Handling file Input/Output.
- Monitoring memory.
- Disposing of the engine when the job ends.
Available Features#
- Create/edit scenes, pages, and blocks programmatically.
- Export compositions (complete edited scenes) in your desired format.
Requirements#
- Node.js v20+ (or the matching runtime for your serverless provider).
- @cesdk/node-native installed locally:
npm install @cesdk/node-native. - A valid CE.SDK license key.
- A supported platform: macOS (ARM or x64) or Linux (x64).
Quick Start: Initialize the Engine#
To try out the CE.SDK headless mode with native bindings:
- Open/create a Node.js project.
- Install the native Node.js package:
npm install @cesdk/node-native1. Create a CE.SDK Helper#
Create a reusable script that initializes the engine:
import CreativeEngine from '@cesdk/node-native';
// CE.SDK configconst defaultConfig = { license: process.env.LICENSE_KEY ?? '<YOUR_CESDK_LICENSE_KEY>',};
let engine;
// Export the CE.SDK initialization to reuse it.export async function getCreativeEngine(config = defaultConfig) { if (!engine) { engine = await CreativeEngine.init(config); } return engine;}
export function disposeCreativeEngine() { if (!engine) { return; } engine.dispose(); engine = undefined;}
export function getCreativeEngineConfig() { return defaultConfig;}This pattern is ideal for:
- HTTP handlers
- Queue workers
Each invocation:
- Calls
getCreativeEngine(). - Reuses the same instance.
- Disposes of the engine when your process shuts down to release native resources.
2. Reuse the Engine in a Script#
You can now script actions using CE.SDK. In the following example, the script assembles a greeting card entirely on the server.
In your Node.js project:
- Create a new script.
- Import your helper along with the needed feature:
import { writeFile } from 'node:fs/promises';import { disposeCreativeEngine, getCreativeEngine } from './CesdkHelper.js';- Copy-paste the following function:
async function buildGreeting() { // Get the engine const engine = await getCreativeEngine();
try { // Create a scene and append it to the page const scene = engine.scene.create(); const page = engine.block.create('page'); engine.block.setWidth(page, 800); engine.block.setHeight(page, 600); engine.block.appendChild(scene, page);
// Create an image block from a sample URL const imageBlock = engine.block.create('graphic'); engine.block.setShape(imageBlock, engine.block.createShape('rect')); const imageFill = engine.block.createFill('image'); engine.block.setString( imageFill, 'fill/image/imageFileURI', 'https://img.ly/static/ubq_samples/sample_1.jpg', ); engine.block.setFill(imageBlock, imageFill); engine.block.setPosition(imageBlock, 100, 100); engine.block.setWidth(imageBlock, 300); engine.block.setHeight(imageBlock, 300); engine.block.appendChild(page, imageBlock);
// Create a text block const textBlock = engine.block.create('text'); engine.block.setString(textBlock, 'text/text', 'Hello from Headless Mode!'); engine.block.setPosition(textBlock, 100, 450); engine.block.setWidth(textBlock, 600); engine.block.appendChild(page, textBlock);
// Export the page as PNG const pngBuffer = await engine.block.export(page, 'image/png');
// Write the file on disk await writeFile('greeting-card.png', Buffer.from(pngBuffer)); console.log('Export complete: greeting-card.png'); } catch (error) { console.error('Failed to export headless scene', error); } finally { // Dispose the Engine to free resources disposeCreativeEngine(); }}
buildGreeting().catch(error => { console.error('Unexpected failure', error); process.exitCode = 1;});- Run the script
node ./<path-to-your-file>/GreetingCard.js. - Check that your project contains the
greeting-card.pngfile.
The preceding script:
- Calls the
CesdkHelper.jshelper to start the engine. - Builds a scene containing:
- An image
- A text block.
- Exports the page to a PNG
Uint8Array. - Writes the image to the disk.
- Disposes of the engine.
Go Further#
-
Dig into the Node.js (Native) SDK reference
for every available Engine call. -
Start a new Node.js (Native) headless project
with a complete project template. - Need to mix headless logic with UI-driven editing? Engine interface guides show hybrid patterns.