Complete guide to installing and running your first ComfyUI workflow with the SDK.
Requires Node.js >= 22 (modern WebSocket + fetch + ES2023 features). Works with Bun as well.
npm install comfyui-node
# or
pnpm add comfyui-node
# or
bun add comfyui-nodeTypeScript types are bundled; no extra install needed.
Minimal ESM usage example:
import { ComfyApi, Workflow } from 'comfyui-node';
import BaseWorkflow from './example-txt2img-workflow.json';
async function main() {
const api = await new ComfyApi('http://127.0.0.1:8188').ready();
const wf = Workflow.from(BaseWorkflow)
.set('6.inputs.text', 'Hello ComfyUI SDK')
.output('images:9');
const job = await api.run(wf, { autoDestroy: true });
const result = await job.done();
for (const img of (result.images?.images || [])) {
console.log('image path:', api.ext.file.getPathImage(img));
}
}
main();Fast reference for common operations. See Workflow Guide and API Features for detailed explanations.
import { ComfyApi, Workflow } from 'comfyui-node';
const api = await new ComfyApi('http://127.0.0.1:8188').ready();
const wf = Workflow.from(json)
.set('3.inputs.steps', 20) // dotted path set
.input('SAMPLER','cfg', 4) // input helper
.batchInputs('SAMPLER', { steps: 15, cfg: 3 })
.output('images:9'); // alias:nodeId
const job = await api.run(wf); // acceptance barrier
job.on('progress_pct', p => console.log(p,'%'));
const result = await job.done();
for (const img of (result.images?.images||[])) console.log(api.ext.file.getPathImage(img));import { PromptBuilder } from 'comfyui-node';
const builder = new PromptBuilder(base,[ 'positive','seed' ],[ 'images' ])
.setInputNode('positive','6.inputs.text')
.setInputNode('seed','3.inputs.seed')
.setOutputNode('images','9')
.input('positive','A misty forest')
.input('seed', 1234)
.validateOutputMappings();await api.run(wf); // high-level (Workflow)
await api.runWorkflow(wf); // alias
new CallWrapper(api, builder)
.onFinished(o => console.log(o.images?.images?.length))
.run(); // builder executionwf.output('alias:NodeId');
wf.output('alias','NodeId');
wf.output('NodeId'); // key = id
// none declared -> auto collect SaveImage nodespending -> start -> progress / progress_pct / preview -> output* -> finished (or failed)The main client for connecting to ComfyUI servers:
const api = new ComfyApi('http://127.0.0.1:8188', {
// Optional configuration
credentials: { type: 'basic', username: 'user', password: 'pass' },
wsTimeout: 60000 // WebSocket inactivity timeout (ms)
});
await api.ready(); // Wait for connection + feature probingUse Workflow when:
- You have an existing JSON workflow from ComfyUI
- You want to tweak parameters (prompts, steps, seeds)
- You need quick parameter changes
Use PromptBuilder when:
- You're building graphs programmatically
- You need validation (missing mappings, cycles)
- You need to serialize/deserialize builder state
See Workflow Guide for detailed comparison.
When you run a workflow, you get a WorkflowJob object:
const job = await api.run(wf);
// Listen to events
job.on('start', () => console.log('Started!'));
job.on('progress_pct', p => console.log(`${p}%`));
job.on('preview', ev => console.log('Preview:', ev.filename));
job.on('output', ev => console.log('Output node:', ev.nodeId));
// Wait for completion
const result = await job.done();
// or simply: await jobThe final result includes:
{
images: { images: [...] }, // Your declared outputs
_promptId: '12345', // ComfyUI prompt ID
_nodes: ['9'], // Nodes that produced output
_aliases: { images: '9' }, // Alias mappings
_autoSeeds: { '3': 1234567 } // Random seeds substituted
}See Workflow Guide for details.
- Workflow Guide – In-depth tutorial on the high-level Workflow API
- PromptBuilder – Lower-level graph construction
- Multi-Instance Pooling – WorkflowPool and ComfyPool for managing multiple servers
- API Features – Modular features (
api.ext.*) - Advanced Usage – Authentication, events, custom nodes, image attachments
- Troubleshooting – Common issues and diagnostics