A browser-native image converter for batch image processing. Files are processed locally in the browser with Web Workers and the @walujanle/image-converter-wasm Rust/WebAssembly package. This repository does not include an upload API.
Current project version: 1.1.2 - Stable Version (feature-complete; maintained as an archive)
- Converts images in batches.
- Supports JPEG, PNG, WebP, AVIF, and HEIC/HEIF as inputs.
- Outputs JPEG, PNG, WebP, and AVIF.
- Uses a worker pool for conversion work.
- Warms the converter worker after page load so the WASM engine is ready before the first conversion.
- Production builds generate a service worker that precaches hashed JS, CSS, worker, and WASM assets for faster repeat visits.
- Applies memory checks before unsafe conversions.
- Supports crop, resize, quality controls, WebP lossless mode, PNG optimization toggle, filename transforms, auto suffix, dataset logs, presets, and ZIP download with lazy-loaded ZIP packaging.
- Keeps simple and advanced modes independent with separate queues, settings, and persisted settings.
- Lets a converted image be converted again at different settings without removing and re-adding the file, per image or for the whole batch.
- Can preserve supported metadata when enabled; coverage depends on the selected output format.
- React 19
- TypeScript 6
- Node 24 LTS
- Vite 8
- Bun
- Zustand
- Tailwind CSS 4
- Web Workers
@walujanle/image-converter-wasm1.1.0 Rust/WASM image engine package- JSZip
- Biome
- Vitest
Image processing is not implemented directly in this web app. The conversion engine is provided by the npm package @walujanle/image-converter-wasm.
The web app uses that package from its Web Worker boundary for image decoding, crop, resize, encoding, metadata handling, and output dimension parsing. UI, queueing, presets, storage, downloads, ZIP packaging, cache registration, and service-worker generation stay in this repository.
bun install
bun run devThe Vite dev server usually runs at http://localhost:5173. The local port can change if another server is already using it.
bun run lint
bun run check
bun run typecheck
bun run test
bun run test:coverage
bun run auditBuild and preview:
bun run build
bun run previewDetailed documentation lives in docs/.
- Documentation Index: documentation map, status, validation baseline, source-of-truth files, and archival notes.
- Deployment Requirements: required response headers, the CSP, per-host configuration, and rebuilding from the archive.
- Architecture Guide: layers, data flow, worker model, cache model, validation, metadata, accessibility, and risks.
- Developer and AI Continuation Guide: code map, internal API notes, workflows, testing strategy, extension points, and continuation context.
- Changelog: stable release notes.
src/
|-- core/ Shared contracts, constants, and errors
|-- domain/ Pure validation, crop, format, and naming rules
|-- data/ Browser adapters for workers, storage, presets, ZIP, cache, and downloads
|-- presentation/ React UI, hooks, Zustand store, pages, and theme
|-- utils/ Shared utilities
|-- workers/ Conversion worker bridge to @walujanle/image-converter-wasm
`-- __tests__/ Vitest tests and binary fixtures
Imports inside src/ are written through the @/ alias, which resolves to src/.
Core flow:
page load
-> converter worker warmup
-> production cache registration when available
file selection
-> validation
-> mode-specific queue state
-> conversion orchestration
-> worker pool
-> worker bridge
-> @walujanle/image-converter-wasm decode/crop/resize/encode/metadata
-> artifact download or ZIP
- Image conversion is local-first in the browser.
- The repository has no upload API, cookies, or first-party analytics code.
- Production static headers are generated into
dist/_headersat build time and include a Content-Security-Policy, HSTS, Referrer-Policy, Permissions-Policy, nosniff, frame denial, COOP/COEP, and CORP directives. - The CSP is strict by default. Where a hosting platform injects its own scripts, extra sources can be allowed at build time through
CSP_SCRIPT_ORIGINS(forscript-src) andCSP_CONNECT_ORIGINS(forconnect-src) without weakening the default for other deployments — see.env.example. The app needs neither;connect-src 'self'is what makes local-only processing browser-enforced, so widening it is a deliberate tradeoff described in Deployment Requirements. - The
_headersformat is host-specific and is ignored silently by hosts that do not support it. GitHub Pages cannot serve these headers at all, and some platforms override individual headers with their own settings. See Deployment Requirements before deploying or migrating hosts. - File validation checks declared MIME, binary signatures, and ISO BMFF brands where supported.
- Large or unsafe images may be rejected before conversion.
- Metadata preservation is opt-in because metadata can include private information such as location, camera, author, or editing history.
The UI includes keyboard and screen-reader-oriented behavior, including focus states, skip-link support, modal semantics, switch semantics, mode button states, icon button labels, and live conversion status messaging.
Full WCAG conformance still requires manual assistive technology testing and automated accessibility checks outside the unit test suite.
- Separate chunked streaming conversion does not exist; conversions use the worker pipeline after memory checks.
- Maximum input size is about 10.7 MB for JPEG and WebP, and about 7.1 MB for PNG, AVIF, and HEIC. The limit is derived from a peak-memory model rather than chosen, because the browser engine holds the encoded input, the decoded frame, and the output at once. Oversized files are now rejected when you add them, with the real limit for that format in the message. Earlier versions advertised a 256 MB limit and then failed the conversion instead.
- Images above 8192 x 8192 pixels are rejected. The engine cannot hold a larger decoded frame on a 32-bit WebAssembly heap, so this is a hard limit rather than a tuning choice.
- AVIF output has limited metadata preservation compared with JPEG, PNG, and WebP.
- GIF and BMP input are not part of the current Rust/WASM image engine contract.
- Resize controls are available in advanced mode only with optional aspect ratio lock. Maximum resize input is 7680 px.
- HEIC/HEIF is input-only; HEIC output encoding is intentionally unavailable in the current Rust/WASM engine.
- PNG compression optimization is optional.
- Auto suffix appends resolution and quality info to output filenames when enabled.
- Numbering is available only when dataset log generation is enabled and applies to the generated dataset log file, not to individual filenames.
- Dataset log generation forces non-individual downloads through ZIP packaging when enabled, including single-image batch downloads, so
dataset_log.txtis delivered with the images. - Production bundle size is not stated here; run a fresh build when release measurement is required.
Last verified on 2026-07-28, against @walujanle/image-converter-wasm 1.1.0, TypeScript 6.0.3, Node 24.14.0, and Bun 1.3.14:
bun run lint: passed, on Biome'srecommendedpreset.bun run check: passed, including formatting and import order.bun run typecheck: passed.bun run test: 321 tests passed across 21 test files.bun run test:coverage: passed, 44.92% statements and 42.71% branches, measured across all ofsrc/.bun run audit: no vulnerabilities found.bun run build: passed.
The coverage figure is lower than 1.1.0's because it is now measured honestly. Coverage previously excluded the store, hooks, components, and worker bridge, reporting 96.57% over the pure layers alone. Nothing stopped being tested; the denominator more than doubled. See the Documentation Index for the full explanation.
The project is feature-complete and maintained as an archive. 1.1.1 was an audit
release: no new features, two data-loss fixes, an honest set of quality gates, and
documentation corrected against the source. 1.1.2 adds build-time CSP configuration and
finishes the archival pass — one import alias across the source, explanatory comments
moved into docs/, and formatting and import order verified repo-wide.
Legal compliance certification, full WCAG certification, and production header verification still depend on the final deployment environment and operational controls.
AGPL-3.0-only. See LICENSE.
This web app distributes and runs the @walujanle/image-converter-wasm package in the browser. That package is also licensed as AGPL-3.0-only, so the web app repository is licensed the same way for release consistency.