wasm-html-to-image 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/llms.txt +220 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -207,10 +207,13 @@ app.listen(3000);
|
|
|
207
207
|
Generate dynamic social preview images at the edge:
|
|
208
208
|
|
|
209
209
|
```typescript
|
|
210
|
-
// wrangler.jsonc:
|
|
211
|
-
//
|
|
210
|
+
// wrangler.jsonc: no "rules" needed on current Wrangler (v3/v4) —
|
|
211
|
+
// `import ... from "*.wasm"` is bundled as WebAssembly.Module by default.
|
|
212
|
+
// Minimal wrangler.jsonc: { "main": "src/index.ts", "compatibility_date": "2026-09-01" }
|
|
213
|
+
// (Only configure "rules" yourself if you customize bundling rules or use a very old Wrangler.
|
|
214
|
+
// Note: @cloudflare/vite-plugin ignores "rules".)
|
|
212
215
|
|
|
213
|
-
import { render } from "wasm-html-to-image/workerd"
|
|
216
|
+
import { render } from "wasm-html-to-image"; // auto-selects the workerd build on Cloudflare ("wasm-html-to-image/workerd" also works)
|
|
214
217
|
|
|
215
218
|
export default {
|
|
216
219
|
async fetch(request: Request): Promise<Response> {
|
package/llms.txt
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# wasm-html-to-image
|
|
2
|
+
|
|
3
|
+
> High-performance WebAssembly HTML-to-image renderer and image optimization engine.
|
|
4
|
+
> Consolidates HTML rendering (Satoru / Skia / litehtml) and native image encoding (WebP / AVIF / JPEG) into a single, unified WASM binary.
|
|
5
|
+
|
|
6
|
+
## Core Capabilities
|
|
7
|
+
- **HTML to Image**: Render HTML strings, arrays (multi-page PDF), or remote URLs directly to PNG, JPEG, WebP, AVIF, RAW, ThumbHash, SVG, or vector PDF.
|
|
8
|
+
- **Image Optimization & Conversion**: Direct image-to-image resizing, cropping, and format re-encoding (e.g., JPEG to WebP/AVIF, GIF to animated WebP) without HTML layout overhead.
|
|
9
|
+
- **Universal Runtime**: Runs seamlessly on Node.js (>=20), Cloudflare Workers, Vercel Edge Runtime, Browsers, Deno, and CLI.
|
|
10
|
+
- **Zero Heavy Dependencies**: NO Puppeteer, Chromium, Playwright, or node-canvas required.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install wasm-html-to-image
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Subpaths & Environment Guide
|
|
23
|
+
|
|
24
|
+
Choose the appropriate import based on runtime and use case:
|
|
25
|
+
|
|
26
|
+
| Subpath | Target Environment | Description |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `wasm-html-to-image` | Universal (Recommended) | Auto-routes: uses `workerd` on Cloudflare, `single` elsewhere. Direct `render()`. |
|
|
29
|
+
| `wasm-html-to-image/single` | Node.js, Bundlers | Self-contained single-bundle WASM entry with instant `render()`. |
|
|
30
|
+
| `wasm-html-to-image/workerd` | Cloudflare Workers | Pre-compiled `WebAssembly.Module` compatible with strict Cloudflare isolates. |
|
|
31
|
+
| `wasm-html-to-image/edge-light` | Vercel Edge Runtime | Tailored for edge sandbox memory and execution constraints. |
|
|
32
|
+
| `wasm-html-to-image/workers` | Node.js, Browsers (on workerd: no pool, falls back to direct execution) | Multi-threaded worker pool for high-throughput batch rendering. |
|
|
33
|
+
| `wasm-html-to-image/react` | React (JSX) | Directly render React element trees. |
|
|
34
|
+
| `wasm-html-to-image/preact` | Preact (JSX) | Directly render Preact element trees. |
|
|
35
|
+
| `wasm-html-to-image/tailwind` | Tailwind CSS | Inlines UnoCSS / Tailwind utility classes into inline CSS styles. |
|
|
36
|
+
| `wasm-html-to-image/index` | High-throughput servers | Manual WASM module reuse via `loadHtmlToImageModule()` and `htmlToImage()`. |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Standard Usage Patterns
|
|
41
|
+
|
|
42
|
+
### 1. Zero-Config HTML Rendering
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { render } from "wasm-html-to-image";
|
|
46
|
+
|
|
47
|
+
const result = await render({
|
|
48
|
+
value: `<div style="padding: 20px; background: #1e293b; color: white; font-family: sans-serif;">
|
|
49
|
+
<h1 style="margin: 0; font-size: 24px;">Hello World</h1>
|
|
50
|
+
</div>`,
|
|
51
|
+
width: 800,
|
|
52
|
+
format: "png", // 'png' | 'jpeg' | 'webp' | 'avif' | 'svg' | 'pdf' | 'raw' | 'thumbhash'
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
console.log(result.data); // Uint8Array (or string for format: 'svg')
|
|
56
|
+
console.log(result.width, result.height); // Output dimensions
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 2. Image Optimization & Format Conversion
|
|
60
|
+
|
|
61
|
+
Pass an image buffer (`Uint8Array` or `Buffer`) or a `data:image/...` URL directly to `render()`. The library automatically detects image magic bytes and skips the HTML layout pass.
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import fs from "node:fs/promises";
|
|
65
|
+
import { render } from "wasm-html-to-image";
|
|
66
|
+
|
|
67
|
+
const inputBuffer = await fs.readFile("input.jpg");
|
|
68
|
+
|
|
69
|
+
// Convert & compress JPEG -> WebP
|
|
70
|
+
const webp = await render({
|
|
71
|
+
value: inputBuffer,
|
|
72
|
+
width: 600, // Optional resize
|
|
73
|
+
format: "webp",
|
|
74
|
+
quality: 80, // 0-100
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Convert -> AVIF with speed control
|
|
78
|
+
const avif = await render({
|
|
79
|
+
value: inputBuffer,
|
|
80
|
+
width: 800,
|
|
81
|
+
format: "avif",
|
|
82
|
+
quality: 75,
|
|
83
|
+
speed: 6, // 0 (best quality) - 10 (fastest)
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Crop and resize
|
|
87
|
+
const cropped = await render({
|
|
88
|
+
value: inputBuffer,
|
|
89
|
+
crop: { x: 50, y: 50, width: 300, height: 300 },
|
|
90
|
+
width: 150,
|
|
91
|
+
height: 150,
|
|
92
|
+
format: "png",
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 3. Cloudflare Workers (root import recommended)
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// wrangler.jsonc: no "rules" needed on current Wrangler (v3/v4) —
|
|
100
|
+
// `import ... from "*.wasm"` is bundled as WebAssembly.Module by default.
|
|
101
|
+
// Minimal wrangler.jsonc: { "main": "src/index.ts", "compatibility_date": "2026-09-01" }
|
|
102
|
+
// (Only configure "rules" yourself if you customize bundling rules or use a very old Wrangler.
|
|
103
|
+
// Note: @cloudflare/vite-plugin ignores "rules".)
|
|
104
|
+
|
|
105
|
+
import { render } from "wasm-html-to-image"; // auto-selects the workerd build on Cloudflare ("wasm-html-to-image/workerd" also works)
|
|
106
|
+
|
|
107
|
+
export default {
|
|
108
|
+
async fetch(request: Request): Promise<Response> {
|
|
109
|
+
const result = await render({
|
|
110
|
+
value: `<h1 style="color: blue;">Edge OGP Image</h1>`,
|
|
111
|
+
width: 1200,
|
|
112
|
+
height: 630,
|
|
113
|
+
format: "png",
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
return new Response(result.data, {
|
|
117
|
+
headers: { "Content-Type": "image/png" },
|
|
118
|
+
});
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 4. Vercel Edge Runtime (`edge-light`: caller-supplied wasm required)
|
|
124
|
+
|
|
125
|
+
Unlike `workerd`, `edge-light` bundles no default wasm: `render(options, wasm)` requires a pre-compiled `WebAssembly.Module` as the 2nd argument.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { render } from "wasm-html-to-image/edge-light";
|
|
129
|
+
|
|
130
|
+
const wasm = await WebAssembly.compile(
|
|
131
|
+
await (await fetch(wasmUrl)).arrayBuffer(),
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const result = await render(
|
|
135
|
+
{
|
|
136
|
+
value: `<h1 style="color: blue;">Edge OGP Image</h1>`,
|
|
137
|
+
width: 1200,
|
|
138
|
+
height: 630,
|
|
139
|
+
format: "png",
|
|
140
|
+
},
|
|
141
|
+
wasm,
|
|
142
|
+
);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 5. High-Throughput Worker Pool (`workers`)
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { render } from "wasm-html-to-image/workers";
|
|
149
|
+
|
|
150
|
+
const tasks = items.map((item) =>
|
|
151
|
+
render({
|
|
152
|
+
value: `<h1>${item.title}</h1>`,
|
|
153
|
+
width: 600,
|
|
154
|
+
height: 400,
|
|
155
|
+
format: "webp",
|
|
156
|
+
}),
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const images = await Promise.all(tasks);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 6. High-Throughput Server Module Reuse (`index`)
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { loadHtmlToImageModule, htmlToImage } from "wasm-html-to-image/index";
|
|
166
|
+
|
|
167
|
+
// Load WASM module once at server boot
|
|
168
|
+
const mod = await loadHtmlToImageModule();
|
|
169
|
+
|
|
170
|
+
// Reuse in request handlers
|
|
171
|
+
app.get("/ogp", async (req, res) => {
|
|
172
|
+
const result = await htmlToImage(mod, {
|
|
173
|
+
value: `<h1>${req.query.title}</h1>`,
|
|
174
|
+
width: 1200,
|
|
175
|
+
height: 630,
|
|
176
|
+
format: "png",
|
|
177
|
+
});
|
|
178
|
+
res.type("image/png").send(Buffer.from(result.data));
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Options Reference (`RenderOptions`)
|
|
185
|
+
|
|
186
|
+
| Option | Type | Default | Description |
|
|
187
|
+
|---|---|---|---|
|
|
188
|
+
| `value` | `string \| string[] \| Uint8Array \| ArrayBuffer` | - | HTML string, array of HTML strings (multi-page PDF), or raw image bytes (`Buffer` works as `Uint8Array`) |
|
|
189
|
+
| `url` | `string` | - | Remote URL to fetch and render (alternative to `value`) |
|
|
190
|
+
| `width` | `number` | `800` | Target viewport / output width in pixels |
|
|
191
|
+
| `height` | `number` | auto / content | Target viewport / output height in pixels |
|
|
192
|
+
| `format` | `string` | `"png"` | Output format: `"png"`, `"jpeg"`, `"webp"`, `"avif"`, `"svg"`, `"pdf"`, `"raw"`, `"thumbhash"`, `"none"` |
|
|
193
|
+
| `quality` | `number` | `85` | Compression quality (0-100) for JPEG, WebP, and AVIF |
|
|
194
|
+
| `speed` | `number` | `6` | CPU effort/speed (0=best quality/slowest, 10=fastest) for AVIF |
|
|
195
|
+
| `scale` | `number` | `1.0` | Device pixel ratio / render scaling factor |
|
|
196
|
+
| `crop` | `{ x, y, width, height }` | - | Rectangular cropping coordinates |
|
|
197
|
+
| `fallbackFonts` | `(Uint8Array \| Buffer)[]` | - | Inlined custom font binaries for air-gapped / offline rendering |
|
|
198
|
+
| `fonts` | `Record<string, Uint8Array \| Buffer>` | - | Font family mapping dictionary |
|
|
199
|
+
| `timeout` | `number` | `10000` | Timeout in milliseconds for resource loading |
|
|
200
|
+
|
|
201
|
+
Additional extension keys exist (e.g. `baseUrl`, `fit`, `animation`); see the type definitions for the full list.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Critical Rules for AI Agents (Anti-Patterns to AVOID)
|
|
206
|
+
|
|
207
|
+
1. **NEVER use Puppeteer, Playwright, or Chromium with this package**: `wasm-html-to-image` compiles litehtml and Skia directly to WebAssembly. It operates entirely in-memory without browser processes.
|
|
208
|
+
2. **DO NOT install `@napi-rs/canvas` or `node-canvas`**: Canvas rendering is built directly into the unified WASM engine.
|
|
209
|
+
3. **DO NOT pass Base64 data back and forth unnecessarily**: Pass raw `Uint8Array` or `Buffer` directly to `render()`.
|
|
210
|
+
4. **Cloudflare Workers preference**: Import from `wasm-html-to-image` (recommended; auto-selects the workerd build on Cloudflare, explicit `wasm-html-to-image/workerd` also works) (no wrangler rules needed on current Wrangler; only needed if you customize bundling rules or use very old Wrangler).
|
|
211
|
+
5. **Google Fonts resolution**: Google Fonts are downloaded automatically in WOFF2 format by default. You do NOT need manual font download logic unless working offline.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Official Links & Resources
|
|
216
|
+
|
|
217
|
+
- **Documentation**: [https://sorakumo001.github.io/wasm-html-to-image/master/docs/](https://sorakumo001.github.io/wasm-html-to-image/master/docs/)
|
|
218
|
+
- **Sample Code Repository**: [https://github.com/SoraKumo001/wasm-html-to-image-samples](https://github.com/SoraKumo001/wasm-html-to-image-samples)
|
|
219
|
+
- **Live Playground**: [https://sorakumo001.github.io/wasm-html-to-image/master](https://sorakumo001.github.io/wasm-html-to-image/master)
|
|
220
|
+
- **GitHub Repository**: [https://github.com/SoraKumo001/wasm-html-to-image](https://github.com/SoraKumo001/wasm-html-to-image)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wasm-html-to-image",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "HTML to image converter on a single unified WASM module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/single.js",
|
|
@@ -114,12 +114,14 @@
|
|
|
114
114
|
"./tailwind": {
|
|
115
115
|
"types": "./dist/tailwind.d.ts",
|
|
116
116
|
"import": "./dist/tailwind.js"
|
|
117
|
-
}
|
|
117
|
+
},
|
|
118
|
+
"./llms.txt": "./llms.txt"
|
|
118
119
|
},
|
|
119
120
|
"files": [
|
|
120
121
|
"dist",
|
|
121
122
|
"README.md",
|
|
122
|
-
"LICENSE"
|
|
123
|
+
"LICENSE",
|
|
124
|
+
"llms.txt"
|
|
123
125
|
],
|
|
124
126
|
"license": "MIT",
|
|
125
127
|
"dependencies": {
|