@zyrab/domo-og
v0.2.1
Published
An OG (Open Graph) image generator config based SVG templates and WASM engine.
Downloads
182
Maintainers
Readme
Introduction
@zyrab/domo-og is a modern utility to dynamically generate high-quality Open Graph images for your websites, blogs, and applications.
Why use Domo-OG?
Historically, generating SVGs and converting them to PNGs required OS-specific binaries or heavy headless browsers like Puppeteer. @zyrab/domo-og solves this by utilizing WebAssembly (@resvg/resvg-wasm). It runs perfectly across Windows, macOS, and Linux without complex native dependencies.
Furthermore, instead of wrestling with messy raw SVG strings, you design your images using clean, readable JSON configuration objects.
Key Features
- WASM Powered Engine: Cross-platform compatibility out of the box. No OS-specific binary downloads.
- Config-Driven Templates: Define layouts, backgrounds, text, and images via simple JavaScript objects.
- Dynamic Data Injection: Easily swap variables like
{{title}}or{{author}}at build time. - Smart Text Wrapping: Automatically calculates text line-breaks and multi-line positioning.
- Built-in Caching: Prevents redundant generation with an internal
og-cache.jsonmanifest, drastically speeding up static site generation (SSG) builds. - Remote Image Fetching: Safely fetches and caches remote background/element images with built-in size limits (20MB) to prevent memory issues.
Performance & Benchmarks
When it comes to automated Open Graph image generation, speed matters—especially for static site generators that might need to build thousands of pages.
Why is Domo-OG so fast?
Other popular generation tools rely on heavy stacks:
- Puppeteer / Playwright: They spin up an entire headless Chromium browser just to take a screenshot. This is infamously slow (often taking 1-3 seconds per image), highly resource-intensive, and prone to memory leaks.
- Satori: While much faster than Puppeteer, it relies on a custom React/HTML/CSS parsing engine (Yoga) in JavaScript to convert layouts into SVGs. This is heavily CPU-bound.
@zyrab/domo-og uses a completely different approach. By taking a simple JSON config, we completely bypass HTML/CSS layout engines and DOM parsing. The JSON is instantly mapped onto a flat SVG canvas and immediately handed off to the high-performance @resvg/resvg-wasm Rust engine to render the PNG.
Benchmark Results
Tested on an Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz (8 Cores, Node v22.19.0):
| Test Condition | Iterations | Avg Time per Image | Total Time | | --- | --- | --- | --- | | Simple Template (Cold) | 200 | ~33 ms | 6.7s | | Complex Template (Remote Image) | 50 | ~43 ms | 2.1s | | Simple Template (Cache Hit) | 200 | ~29 ms | 5.8s |
(Note: Cache hits skip rendering entirely, safely fetching from disk).
Installation
npm install @zyrab/domo-og
# or
yarn add @zyrab/domo-og
# or
pnpm add @zyrab/domo-ogQuick Start
Here is a basic example of generating an OG image for a blog post. By default, the generator uses a built-in template and handles relative project paths automatically.
import { generateOgImage } from "@zyrab/domo-og";
async function build() {
const imagePath = await generateOgImage({
slug: "my-first-post", // Used for caching and file naming
ogOutputPath: "public", // Where the assets/og-images folder will be created
title: "My Awesome First Post!", // Injects into {{title}} in the template
type: "Blog Article" // Injects into {{type}} if defined in template
});
console.log(`Generated successfully at: ${imagePath}`);
}
build();Configuration API (Templates)
Templates in Domo-OG are just JavaScript objects. This eliminates the need to manually manipulate SVG tags.
Root Configuration
| Property | Type | Default | Description |
|---|---|---|---|
| width | number | 1200 | The width of the generated image. |
| height | number | 630 | The height of the generated image. |
| fontPath | string | null | Path or URL to a custom .ttf, .otf, or .woff font. |
| background | object | null | The background layer configuration. |
| elements | array | [] | An array of element objects (text or images) to render on top. |
Background Object
| Property | Type | Description |
|---|---|---|
| type | "color" | "image" | Defines the type of background. |
| value | string | The hex/rgb color code (Required if type is "color"). |
| src | string | Path or URL to the background image (Required if type is "image"). |
Elements Array Objects
Elements render sequentially (the last element in the array renders on top).
Text Element
| Property | Type | Description |
|---|---|---|
| type | "text" | Identifies the element type. |
| content | string | The text to display. Supports variables e.g., {{title}}. |
| width | number | The width of the text element. |
| maxLength | number | The maximum length of the text element. |
| horizontalAlign | "left"|"center"|"right" | Horizontal alignment based on padding/width. |
| verticalAlign | "top"|"middle"|"bottom" | Vertical alignment based on padding/height. |
| fontSize | number | Font size in pixels (Default: 32). |
| color | string | Hex/rgb text color. |
| backgroundColor | string | Adds a highlighted background box behind the text. |
| borderRadius | number | Border radius for the text background box. |
| padding | number | Distance from the edges of the canvas. |
| bgPadding | number | Padding between the text and its own backgroundColor box. |
Image Element
| Property | Type | Description |
|---|---|---|
| type | "image" | Identifies the element type. |
| src | string | Local path or remote URL (http/https) to the image. |
| width | number | Width of the image (Default: 100). |
| height | number | Height of the image (Default: 100). |
| horizontalAlign | "left"|"center"|"right" | Horizontal alignment on the canvas. |
| verticalAlign | "top"|"middle"|"bottom" | Vertical alignment on the canvas. |
| padding | number | Distance from the edges of the canvas. |
Advanced Template Example
Here is an advanced template showcasing dynamic data, remote images, and custom styling.
const advancedTemplate = {
width: 1200,
height: 630,
background: {
type: "color",
value: "#1a1a1a",
},
elements: [
{
type: "image",
src: "https://example.com/mock-logo.png", // Mock remote image
horizontalAlign: "left",
verticalAlign: "top",
padding: 40,
width: 80,
height: 80,
},
{
type: "text",
content: "{{category}}", // Dynamic variable
horizontalAlign: "left",
verticalAlign: "top",
padding: 140, // Pushed down below the logo
fontSize: 24,
color: "#000000",
backgroundColor: "#E9FA00",
bgPadding: 8,
borderRadius: 4,
},
{
type: "text",
content: "{{title}}", // Dynamic variable
horizontalAlign: "center",
verticalAlign: "middle",
fontSize: 64,
color: "#FFFFFF",
maxLength: 20 // Forces line breaks after ~20 characters
}
]
};Core API Reference
generateOgImage(options)
The primary workhorse of the package. It builds the SVG, renders it to PNG, and manages the cache.
Options:
slug(String, Required): A unique identifier for the image (often the URL slug).ogOutputPath(String, Required): The relative or absolute path to your output directory (e.g.,"public"). Images are saved into${ogOutputPath}/assets/og-images/.template(Object, Optional): Your config template. Falls back to the built-in default config if omitted.routeKey(String, Optional): An alternative key to use for hashing/caching instead of slug....flatParams: Any other key passed in this object will be injected into the template (e.g., passingtitle: "Hello"replaces{{title}}in the template).
Returns:
Promise<String>: The relative path to the generated PNG (e.g.,assets/og-images/my-post-1a2b3c4d.png).
getDefaultConfig()
Returns a clean, modern, dark-themed default configuration object if you don't want to design one from scratch.
flushManifestImmediately()
(og-cache.json is debounced by default)
Forces the caching manifest (og-cache.json) to write to the disk immediately. Useful for build scripts that might exit before the standard 500ms debounce timer finishes.
Fonts & Fallbacks
The WASM rendering engine requires a valid .ttf, .otf, or .woff font file to render text. @zyrab/domo-og handles this intelligently:
- Explicit URL/Path: If you provide
fontPathin your config, it will fetch/load it. - Local Assets: It will automatically scan
${ogOutputPath}/assets/fonts/for any valid font file. - Internal Fallback: If neither are found, it safely falls back to a default font bundled within the package (
fonts/default.ttf).
Remote Image Security & Limits
To protect your build processes from memory leaks and hang-ups:
- Remote images have a strict 20MB size limit.
- The package uses a custom User-Agent:
Domo-OG-Builder/1.0. (Note: If your server blocks unknown User-Agents, ensure you whitelistDomo-OG-Builder/1.0to allow image fetching).
License & Acknowledgements
@zyrab/domo-og is licensed under the MIT License.
Engine Acknowledgment
This package relies on the fantastic @resvg/resvg-wasm for rendering SVGs to PNGs via WebAssembly. Please refer to the Resvg repository or the @resvg/resvg-wasm package for detailed licensing information regarding the underlying rendering engine.
