Package Exports
- stable-diffusion-cpp-node-api
- stable-diffusion-cpp-node-api/src/js/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (stable-diffusion-cpp-node-api) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
node-stable-diffusion-cpp
WARNING: This library was vibe coded. The entire codebase — C++ bindings, JS wrappers, build system, and documentation — was generated by an AI assistant in a single session. It compiles, passes basic smoke tests, and the API surface matches the upstream C library. However, it has not been battle-tested in production. Edge cases, memory leaks under unusual error paths, and platform-specific build quirks may exist. Use at your own risk, report issues, and read the source before shipping anything important.
Native Node.js bindings for stable-diffusion.cpp — a pure C/C++ implementation of Stable Diffusion, SDXL, SD3, FLUX, Wan video, and more. Built on N-API for ABI stability across Node.js versions. All heavy operations (model loading, image/video generation, upscaling) run on background threads and return Promises.
Features
- Image generation — txt2img, img2img, inpainting, ControlNet, PhotoMaker, LoRA
- Video generation — Wan2.1/2.2 text-to-video and image-to-video
- Upscaling — ESRGAN-based super resolution
- Model conversion — safetensors/ckpt to GGUF quantized formats
- GPU auto-detection — Metal (macOS), CUDA (Linux/Windows), Vulkan
- Async everything — context creation, generation, upscaling all return Promises
- Callbacks — log, progress, and preview callbacks bridged to the JS event loop
- Electron-ready — N-API v8 targets Node.js 18+ / Electron 22+
- TypeScript — full type declarations included
Requirements
- Node.js >= 18
- CMake >= 3.15
- C++17 compiler (Xcode, GCC 9+, MSVC 2019+)
- Platform SDK for GPU backend (Xcode for Metal, CUDA Toolkit for NVIDIA, Vulkan SDK)
Installation
git clone --recursive <your-repo-url>
cd node-stable-diffusion-cpp
npm installThe npm install step compiles the native module. On macOS it automatically enables Metal; on systems with CUDA or Vulkan SDKs installed, those backends are enabled too.
Manual build
npm run build # Release build
npm run build:debug # Debug build
npm run rebuild # Clean + rebuild
npm run clean # Remove build artifactsQuick start
const sd = require('node-stable-diffusion-cpp');
const fs = require('fs');
// Optional: log what the library is doing
sd.setLogCallback(({ level, text }) => {
if (level >= 1) process.stderr.write(text);
});
// Optional: track generation progress
sd.setProgressCallback(({ step, steps, time }) => {
process.stderr.write(`\rStep ${step}/${steps} (${time.toFixed(1)}s)`);
});
(async () => {
// Load a model (runs on background thread)
// Use modelPath for single-file models (ckpt, safetensors, full gguf).
// Use diffusionModelPath only for standalone diffusion-only component files.
const ctx = await sd.StableDiffusionContext.create({
modelPath: 'path/to/model.gguf',
});
// Generate an image
const images = await ctx.generateImage({
prompt: 'a photo of an astronaut riding a horse on mars',
width: 512,
height: 512,
sampleParams: {
sampleSteps: 20,
guidance: { txtCfg: 7.0 },
},
});
// Save raw RGB pixels (use stb_image or sharp to encode to PNG)
const img = images[0];
console.log(`\nGenerated ${img.width}x${img.height} image (${img.data.length} bytes)`);
fs.writeFileSync('output.raw', img.data);
ctx.close();
})();Smoke test
A ready-made script is included:
node smoke.js path/to/model.ggufEdit the constants at the top of smoke.js to change prompt, dimensions, steps, etc.
API overview
| Function / Class | Description |
|---|---|
StableDiffusionContext.create(opts) |
Load a model, returns Promise<StableDiffusionContext> |
ctx.generateImage(opts) |
Text/image to image, returns Promise<SdImage[]> |
ctx.generateVideo(opts) |
Text/image to video frames, returns Promise<SdImage[]> |
ctx.getDefaultSampleMethod() |
Default sampler for loaded model |
ctx.getDefaultScheduler(method?) |
Default scheduler for sampler |
ctx.abort() |
Cancel any in-flight or queued generate call on this ctx |
ctx.close() |
Cancel in-flight work and free native resources |
UpscalerContext.create(opts) |
Load ESRGAN model, returns Promise<UpscalerContext> |
upscaler.upscale(image, factor?) |
Upscale an image, returns Promise<SdImage> |
upscaler.abort() |
Cancel any in-flight or queued upscale call on this ctx |
convert(opts) |
Convert model format, returns Promise<boolean> |
extractMetaData(path) |
Read model header (version, components, dtype stats) without loading weights, returns Promise<ModelMetadata> |
preprocessCanny(image, opts?) |
Canny edge detection (sync, in-place) |
setLogCallback(fn) |
Set/clear log callback |
setProgressCallback(fn) |
Set/clear progress callback |
setPreviewCallback(fn, opts?) |
Set/clear preview callback |
getSystemInfo() |
Backend/hardware info string |
getNumPhysicalCores() |
CPU core count |
version() / commit() |
Library version and git commit |
See docs/API.md for the full API reference with all options, types, and examples.
Supported models
Anything stable-diffusion.cpp supports:
- Stable Diffusion 1.x, 2.x
- SDXL, SDXL Turbo
- SD3, SD3.5
- FLUX.1 (dev, schnell)
- Wan2.1, Wan2.2 (video)
- Chroma, Qwen-Image
- LoRA, ControlNet, PhotoMaker
- GGUF quantized models (Q4_0, Q5_0, Q8_0, F16, etc.)
Image data format
All images are plain objects with raw pixel data:
interface SdImage {
width: number; // pixels
height: number; // pixels
channel: number; // 3 for RGB
data: Buffer; // raw RGB bytes, length = width * height * channel
}To save as PNG, use a library like sharp:
const sharp = require('sharp');
await sharp(img.data, { raw: { width: img.width, height: img.height, channels: img.channel } })
.png()
.toFile('output.png');License
MIT. See LICENSE.
stable-diffusion.cpp is also MIT licensed. GGML is MIT licensed.