JSPM

stable-diffusion-cpp-node-api

0.12.2
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 298
  • Score
    100M100P100Q91274F
  • License MIT

Node.js N-API bindings for stable-diffusion.cpp — run Stable Diffusion, SDXL, SD3, FLUX, and Wan video models natively

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 install

The 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 artifacts

Quick 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.gguf

Edit 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.