@squoosh-kit/oxipng 0.2.1 → 0.2.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.
Files changed (2) hide show
  1. package/README.md +221 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,221 @@
1
+ # @squoosh-kit/oxipng
2
+
3
+ [![npm version](https://badge.fury.io/js/%40squoosh-kit%2Foxipng.svg)](https://badge.fury.io/js/%40squoosh-kit%2Foxipng)
4
+ [![Bun](https://img.shields.io/badge/Bun-000000?logo=bun&logoColor=white)](https://bun.sh/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
7
+
8
+ ![Squoosh-Kit](https://github.com/bnowak008/squoosh-kit/blob/main/squoosh-kit-banner.webp)
9
+
10
+ ## Squoosh-Kit
11
+
12
+ Squoosh-Kit is built on a simple idea: provide a lightweight and modular bridge to the powerful, production-tested codecs from Google's Squoosh project. This package (`@squoosh-kit/oxipng`) is one of those modules.
13
+
14
+ **Directly from the Source**
15
+ We don't modify the core OxiPNG codec. The WebAssembly (`.wasm`) binary is taken directly from the official Squoosh repository builds. This means you get the exact same performance, quality, and reliability you'd expect from Squoosh.
16
+
17
+ **A Thin, Modern Wrapper**
18
+ Our goal is to provide a minimal, modern JavaScript wrapper around the codec. We handle the tricky parts—like loading WASM, managing web workers, and providing a clean, type-safe API—so you can focus on your application. The library is designed to be a thin bridge, not a heavy framework.
19
+
20
+ **Modular by Design**
21
+ We believe you should only install what you need. As a standalone package, `@squoosh-kit/oxipng` allows you to add lossless PNG optimization to your project without pulling in other unrelated image processing tools.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ bun add @squoosh-kit/oxipng
27
+ # or
28
+ npm install @squoosh-kit/oxipng
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ```typescript
34
+ import { optimize, createOxipngOptimizer } from '@squoosh-kit/oxipng';
35
+ import type { ImageInput } from '@squoosh-kit/oxipng';
36
+
37
+ const imageData: ImageInput = {
38
+ data: rawPixelBuffer,
39
+ width: 800,
40
+ height: 600,
41
+ };
42
+
43
+ // Optimize PNG with default settings (level 2)
44
+ const optimizedPng = await optimize(imageData);
45
+
46
+ // Higher optimization effort
47
+ const maxOptimized = await optimize(imageData, { level: 6 });
48
+
49
+ // For multiple images, use a persistent optimizer
50
+ const optimizer = createOxipngOptimizer('worker');
51
+ const result = await optimizer(imageData, { level: 3 });
52
+ await optimizer.terminate();
53
+ ```
54
+
55
+ ## What is OxiPNG?
56
+
57
+ OxiPNG is a lossless PNG optimizer. It re-encodes existing PNG data using more aggressive compression settings, reducing file size without any quality loss. A typical optimization at level 2–4 can reduce PNG file sizes by 10–30% with no visible difference.
58
+
59
+ OxiPNG is a good fit for:
60
+
61
+ - Reducing PNG sizes before serving to clients
62
+ - Optimizing screenshots or UI assets
63
+ - Post-processing after PNG encoding (pair with `@squoosh-kit/png`)
64
+
65
+ ## Public API
66
+
67
+ Only the following exports are part of the public API and guaranteed to be stable across versions:
68
+
69
+ - `optimize(imageData, options?, signal?)` - Optimize raw pixel data to a compressed PNG
70
+ - `createOxipngOptimizer(mode?)` - Create a reusable optimizer function
71
+ - `ImageInput` type - Input image data structure
72
+ - `OxipngOptions` type - Optimization configuration
73
+ - `OxipngOptimizerFactory` type - Type for reusable optimizer functions
74
+
75
+ ## Real-World Examples
76
+
77
+ **Optimize PNGs in a build pipeline**
78
+
79
+ ```typescript
80
+ const optimizer = createOxipngOptimizer('client'); // No worker overhead for batch
81
+
82
+ for (const imagePath of pngFiles) {
83
+ const imageData = await loadImageAsRgba(imagePath);
84
+ const optimized = await optimizer(imageData, { level: 4 });
85
+ await writeFile(imagePath, optimized);
86
+ console.log(
87
+ `Optimized ${imagePath}: ${imageData.data.length} → ${optimized.length} bytes`
88
+ );
89
+ }
90
+
91
+ await optimizer.terminate();
92
+ ```
93
+
94
+ **Optimize with a timeout**
95
+
96
+ ```typescript
97
+ const controller = new AbortController();
98
+ const timeout = setTimeout(() => controller.abort(), 30000);
99
+
100
+ try {
101
+ const optimized = await optimize(imageData, { level: 6 }, controller.signal);
102
+ await writeFile('output.png', optimized);
103
+ } catch (error) {
104
+ if (error.name === 'AbortError') {
105
+ console.log('Optimization timed out — try a lower level');
106
+ }
107
+ } finally {
108
+ clearTimeout(timeout);
109
+ }
110
+ ```
111
+
112
+ ## API Reference
113
+
114
+ ### `optimize(imageData, options?, signal?)`
115
+
116
+ Optimizes raw RGBA pixel data into a compressed PNG. This is a lossless operation — the output PNG decodes back to identical pixel values.
117
+
118
+ - `imageData` - `ImageInput` object with your pixel data
119
+ - `options` - (optional) `OxipngOptions` for compression settings
120
+ - `signal` - (optional) `AbortSignal` to cancel the operation
121
+ - **Returns** - `Promise<Uint8Array>` with the optimized PNG data
122
+
123
+ **Note**: Higher `level` values produce smaller files but take longer. Level 2 is a good default for most use cases.
124
+
125
+ ### `createOxipngOptimizer(mode?)`
126
+
127
+ Creates a reusable optimizer. More efficient for processing multiple images.
128
+
129
+ - `mode` - (optional) `'worker'` or `'client'`, defaults to `'worker'`
130
+ - **Returns** - A function with the same signature as `optimize()`
131
+
132
+ ## Cancellation Support
133
+
134
+ To cancel an optimization in progress, pass an `AbortSignal`:
135
+
136
+ ```typescript
137
+ const controller = new AbortController();
138
+
139
+ const optimizePromise = optimize(imageData, { level: 6 }, controller.signal);
140
+ setTimeout(() => controller.abort(), 10000);
141
+
142
+ try {
143
+ const result = await optimizePromise;
144
+ } catch (error) {
145
+ if (error.name === 'AbortError') {
146
+ console.log('Optimization was cancelled');
147
+ }
148
+ }
149
+ ```
150
+
151
+ ## Input Validation
152
+
153
+ All inputs are automatically validated before processing:
154
+
155
+ ```typescript
156
+ // Will throw TypeError: image must be an object
157
+ await optimize(null);
158
+
159
+ // Will throw TypeError: image.data must be Uint8Array or Uint8ClampedArray
160
+ await optimize({ data: [0, 0, 0, 255], width: 32, height: 32 });
161
+
162
+ // Will throw RangeError: image.data too small
163
+ await optimize({ data: new Uint8Array(100), width: 800, height: 600 });
164
+ ```
165
+
166
+ ### Package Size
167
+
168
+ **Size breakdown:**
169
+
170
+ - JavaScript code: ~4-6KB gzipped
171
+ - TypeScript definitions: ~2KB
172
+ - WASM binary: ~20-30KB gzipped
173
+
174
+ ### Worker Cleanup
175
+
176
+ When using worker mode, clean up when done:
177
+
178
+ ```typescript
179
+ const optimizer = createOxipngOptimizer('worker');
180
+
181
+ try {
182
+ const optimized = await optimizer(imageData, { level: 4 });
183
+ } finally {
184
+ await optimizer.terminate();
185
+ }
186
+ ```
187
+
188
+ ### `OxipngOptions`
189
+
190
+ ```typescript
191
+ type OxipngOptions = {
192
+ level?: number; // 0–6, optimization effort (default: 2)
193
+ interlace?: boolean; // Use Adam7 interlacing (default: false)
194
+ };
195
+ ```
196
+
197
+ - `level` — Controls how hard OxiPNG tries to compress. Higher = smaller files, slower processing.
198
+ - `0` — No optimization (fast, no size reduction)
199
+ - `1-2` — Light optimization (fast, good results)
200
+ - `3-4` — Moderate optimization (balanced)
201
+ - `5-6` — Maximum optimization (slowest, smallest files)
202
+ - `interlace` — Enables Adam7 interlacing, which allows progressive rendering in browsers. Interlaced PNGs are typically slightly larger.
203
+
204
+ ## Performance Tips
205
+
206
+ - **Level 2 is the sweet spot** — Good compression with fast processing; use for most cases
207
+ - **Level 6 for static assets** — Worth the extra time for files that will be served many times
208
+ - **Use workers for UI apps** — Higher levels can take several seconds on large images
209
+ - **Use client mode for build tools** — Direct processing is simpler in Node/Bun scripts
210
+ - **Pair with @squoosh-kit/png** — Encode raw pixels with png, then optimize with oxipng
211
+
212
+ ## Works With
213
+
214
+ - **Bun** - First-class support, fastest performance
215
+ - **Node.js** - Works great in server environments
216
+ - **Browsers** - Full Web Worker support for responsive UIs
217
+ - **TypeScript** - Complete type definitions included
218
+
219
+ ## License
220
+
221
+ MIT - use it freely in your projects
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squoosh-kit/oxipng",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "description": "OxiPNG codec for squoosh-kit, providing PNG optimization functionality.",
6
6
  "author": "Bartosz Nowak <bnowak008@gmail.com>",
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/bnowak008/squoosh-kit.git",
11
11
  "directory": "packages/oxipng"
12
12
  },
13
- "homepage": "https://github.com/bnowak008/squoosh-kit/tree/main/packages/oxipng#readme",
13
+ "homepage": "http://squoosh-kit.dev",
14
14
  "publishConfig": {
15
15
  "access": "public",
16
16
  "registry": "https://registry.npmjs.org/"