Image editor SDK · Rust core, one binary everywhere
Edit small. Render big. Identical.
Your users edit a preview in the browser. Your server applies the same edit log to the 80-megapixel original and produces the same pixels. Verified by hash.
The editor could not load here. Open the demo instead.
Marketing studio
A content team preparing campaign images with every tool, dark graphite, pill buttons.
<sealpixel-editor theme="dark" locale="en" active-tool="filter" show-download="never"
plugin-options='{"filter":{"presets":["grayscale","sepia","vintage","warm",{"name":"brand","label":"Brand","matrix":[[0.8,0.1,0.1,0,0.02],[0.05,0.85,0.1,0,0],[0.1,0.1,0.9,0,0.05],[0,0,0,1,0]]}],"thumbnails":true}}'></sealpixel-editor>
<style>
sealpixel-editor::part(button) { border-radius: 999px; }
</style>
<script type="module">
import '@sealpixel/element'; // registers the element and the bundled worker
import { allPlugins } from '@sealpixel/plugins';
const editor = document.querySelector('sealpixel-editor');
editor.plugins = allPlugins; // sticker and watermark ship, but are not in the default set
editor.addEventListener('sealpixel:process', (e) => {
upload(e.detail.bytes, e.detail.hash);
});
</script>
Loading the editor…
The editor could not load here. Open the demo instead.
Redaction desk
A compliance team blurring personal data in scanned forms. Redact, annotate and watermark, high-contrast theme, German interface.
The same component lays itself out for a phone on its own. No second UI to build, no mobile flag to set. Try it in the frame.
One component, two layouts
Below 768 px of container width the toolbar moves to the bottom and the tool panel sits above it. It reacts to its container, not the viewport, so a narrow sidebar gets the phone layout too.
Touch first
Pinch to zoom, drag to pan, one finger for crop handles, redaction boxes and annotations. Wheel and trackpad do the same on a desktop.
Only the preview travels
The phone loads and edits a small preview. The edit log goes to your server, which applies it to the full-resolution original. Same pixels, a fraction of the data.
Notches and home bars
Safe-area insets are respected. show-history="buttons" drops the timeline and show-export="never" hides Export, so the essentials fit on a small screen.
9:41
Loading the editor…
The editor could not load here. Open the demo instead.
Live editor in a phone frame. Drag, pinch, tap.
The edit log is the image
One log, one core
Every crop, filter and annotation is an operation in a JSON log. A Rust core compiled to WebAssembly executes it in a Web Worker, on Node, Deno, Bun or AWS Lambda. Same bytes in, same bytes out.
Byte-identical, hash-verified
Render the same source with the same log anywhere and the SHA-256 matches. Large uploads edit a proxy on the phone; the server renders the original from the same log.
Resume from JSON
Store the original once and the log next to it. Reopen any state, on any device, without generation loss. The log can travel inside the exported PNG, JPEG or WebP.
Every tool your users expect
Ten plugins ship in the box. Each one is a package you can drop, replace or extend.
Crop
Rotate by any angle, flip, aspect presets, handles that stay 7 px on every screen.
@sealpixel/plugin-crop
Finetune
Brightness, contrast, saturation, exposure, gamma, clarity and vignette.
@sealpixel/plugin-finetune
Filter
Grayscale, sepia, vintage, cool, warm and any 4×5 colour matrix, with strength.
@sealpixel/plugin-filter
Redact
Pixelate or blur rectangles and freeform regions. Cells snap to the source grid so proxy and original match.
@sealpixel/plugin-redact
Annotate
Rectangles, ellipses, lines, arrows, freehand paths and text. Fonts are hashed assets: identical glyphs everywhere.
@sealpixel/plugin-annotate
Sticker
Place logos and image assets with rotation, flips and opacity.
@sealpixel/plugin-sticker
Frame
Solid, inset and polaroid frames.
@sealpixel/plugin-frame
Watermark
Image or text, anchored or tiled, applied identically on the server.
@sealpixel/plugin-watermark
Resize
Contain, cover and fill to a target size. Lanczos3 down, Catmull-Rom up.
@sealpixel/plugin-resize
Fill
Background colour for areas a rotation or crop exposes.
@sealpixel/plugin-fill
A component for every stack
A Web Component underneath, thin typed wrappers on top. Controlled and uncontrolled edit logs everywhere.
Send the original and the edit log to one fetch handler. It validates the log, renders with the same WebAssembly binary and returns bytes, a hash and a job key. Repeat the request and it returns the cached result.
Zod-validated request, SSRF allowlist, size limits before decode
Idempotent job keys: same source, log and options, same object
S3 or URL sources, S3 or inline destinations, proxy mode for large uploads
Memory sizing table from 12 to 80 megapixels
POST /render
{
"source": { "kind": "s3", "bucket": "uploads", "key": "IMG_4821.jpg" },
"editLog": { "version": 1, "source": { "id": "IMG_4821", "width": 8192, "height": 5461 }, "ops": [ … ] },
"output": { "format": "image/jpeg", "quality": 0.92 },
"destination": { "kind": "s3", "bucket": "renders" }
}
200 OK
{
"key": "renders/3f9a…c1.jpg",
"hash": "3f9a4e…b7c1", ← equals the browser's hash for the same input
"width": 6144, "height": 4096,
"cached": false, ← true on the second identical request
"timings": { "decode": 412, "render": 1730, "encode": 388 }
}
Extend it without forking
A plugin is an npm package: operations with zod schemas, a reducer, a kernel in JavaScript or in Rust compiled to its own WebAssembly module, and an optional tool with panel and gizmo. It runs on the client and on the server without rebuilding the core.
Scaffold one
npm create @sealpixel/plugin acme-spotlight -- --kernel wasm-rustcd acme-spotlight && npm test # parity: Node vs Chromium, WebKit, Firefox
The tier follows your total number of seats and its price applies to every one of them. Add seats later and they are prorated to the renewal date you already have. If the total reaches a lower tier, that tier applies to every seat from the day you add them, prorated for the rest of the term and in full at the next renewal. The part of the term already gone is not recalculated.
Business Source License 1.1, Apache 2.0 after four years. No runtime license check: the software never phones home. Read the license
Our order process is conducted by our online reseller Paddle.com. Paddle is the Merchant of Record for all our orders and handles VAT, GST and sales tax. We stay the licensor of the software. Paddle Buyer Terms
Questions
Who uses Sealpixel free of charge?
Anyone under EUR 1,000,000 of gross annual revenue: individuals, and organizations below that threshold. Production and commercial products are included. Revenue counts across the whole group, so a subsidiary of a large company is not free. For client work the client’s revenue decides, so a freelancer building for a small startup pays nothing and the same freelancer building for a large customer is covered by that customer’s seats.
I am an agency. What do I pay?
One seat per developer who works on codebases that include Sealpixel, regardless of how many clients or products those codebases serve. A seat held by your developer covers all their client work, so your clients need no seats of their own, and none to run the finished application.
How do volume tiers work?
Tell us how many seats you need. 1 to 4 seats cost 499 EUR each per year, 5 to 9 cost 449, 10 to 24 cost 399, and the tier applies to every seat you hold. Seats added later are prorated to the renewal date you already have, and if the total reaches a lower tier, that tier applies to every seat from the day you add them — prorated for the rest of the term and in full at the next renewal. The part of the term already gone is not recalculated. From 25 seats we quote individually.
Can an open-source project use Sealpixel?
Yes. Sealpixel itself is source available under the Business Source License 1.1, not open source, so a project that depends on it inherits those terms: contributors below the revenue threshold need no seats, a company that develops the project needs seats for its developers, and copies and forks stay under the BUSL. Every release becomes Apache 2.0 four years after it was published.
Is Sealpixel open source?
No. Sealpixel is source available under the Business Source License 1.1. The source is public and you may read, modify, fork and redistribute it, and production use is free below the revenue threshold — but the BUSL is not an OSI-approved license, so calling it open source would be wrong. Four years after a version is published it converts to the Apache License 2.0, and that version is then open source in the OSI sense.
What is a developer seat exactly?
A seat belongs to a named person who writes, reviews, tests or integrates code in a project that includes Sealpixel. It can be reassigned when that person leaves. Designers in the codebase and QA engineers count. End users of your application never need a seat, whatever their number, and neither do people who only operate or administer it.
Can I build a SaaS on Sealpixel?
Yes. The only limit is a service whose primary value is the image editor itself, such as a hosted "edit your image" product or an image editing API sold to third parties. A photo-book shop, a CMS, a real-estate portal or a support tool with editing built in are all fine.
Who do I actually buy from, and who invoices me?
From Paddle. Our order process is conducted by our online reseller Paddle.com, which is the Merchant of Record for all our orders: you buy the seats from Paddle, Paddle invoices you and calculates, collects and remits VAT, GST or sales tax for your country. Enter your VAT or tax ID at the checkout so the right treatment applies. We stay the producer and licensor of Sealpixel — the software license is granted by us under the Developer Seat License, never by Paddle.
How does the refund work?
Cancel within 30 days of your first purchase and you get the full amount back, by the same route the payment came in. Paddle handles the refund as our Merchant of Record; write to us or to Paddle, we approve it either way. No questions asked.
What exactly is byte-identical?
The same source bytes plus the same edit log rendered through the same core version produce the same output bytes and SHA-256, in every browser, on Node, Deno, Bun and Lambda. When a phone edits a downscaled proxy and the server renders the original, the composition is identical (same normalized geometry) but the bytes differ, because the inputs differ. The docs spell this out.
How big is the download?
The WebAssembly core is about 1.3 MB raw and 390 KB with Brotli, loaded lazily when the editor mounts. The Lit UI and the render worker add a few tens of kilobytes. There is a budget check in CI.
Which browsers are supported?
Current Chrome, Edge, Safari and Firefox on desktop and mobile. Every commit runs the parity suite in Chromium, WebKit and Firefox, and the UI suite in Chromium and WebKit. On iOS Safari the download falls back to the share sheet.
Can I write my own tool?
Yes. npm create @sealpixel/plugin scaffolds a package with operations, a reducer, a JavaScript or Rust kernel and a tool panel. The testing kit renders your plugin in Node and three browsers and asserts equal hashes. Two example plugins ship in the repository.