ICPixel | A browser-based pixel editor on ICP

Built a browser-based pixel editor on ICP called ICPixel.

The goal was to get as close as possible to a “real” tool (think Aseprite-level workflow), but fully in the browser and without relying on any traditional backend.

Frontend is React + TypeScript (Vite), backend is a Motoko canister. All user data (projects, balances, logs) lives directly in the canister and survives upgrades. Auth is Internet Identity, using the principal as the user key.

The canvas engine is fully custom (Canvas 2D, no external libs). Rendering runs through a compositor that reads the layer stack and applies filters at render time, so everything stays non-destructive. The drawing system (tools, strokes, undo, frames) is kept outside React state and handled imperatively - React is only used for UI.

Some of the things it does:

  1. Multi-layer editing with non-destructive filters
    Layers support opacity/visibility/locking, with filters like hue, brightness, blur applied at render time.

  2. Frame-based animation with onion skinning
    Timeline-based animation with adjustable playback and per-frame layer control.

  3. Multi-tab workspace (independent project states)
    Up to 2 canvases open at once, each with its own layers, frames, undo stack, and camera. Shared renderer underneath.

  4. Full selection toolkit + pixel tools
    Lasso, magic wand, rectangle select, marching-ants rendering, mirror drawing, dithering, pixel-perfect modes.

  5. Import/export + local-first workflow
    Works without login. Projects can be saved locally and re-imported anytime.

  6. On-chain project storage
    Logged-in users can persist projects directly to the canister.

  7. Built-in non-custodial wallet
    Address is derived client-side from the principal. No backend key handling. Ledger calls go directly to the ICP ledger.

  8. Simple on-chain “pixel” resource system
    Purchases are logged on-chain, with admin-gated crediting for auditability.

  9. Flexible export pipeline (static, animated, and project formats)
    Supports PNG (single frame), WebM (full animation), sprite sheet export, and full project export as .icpixel files.

  10. NFT generator + full collection export (in-browser)
    Trait groups are defined directly through the layer structure, with adjustable rarity weights and weighted preview generation. The export produces a complete ZIP package (traits, metadata, config, preview) entirely client-side - no uploads or backend processing.

UI has two modes: a dark “standard” one and a Win95-style grey theme. The editor loads instantly and is fully usable without logging in - auth only kicks in for persistence and wallet features.

Overall goal was to keep it fast, self-contained, and closer to a desktop tool than a typical web editor, while still leaning into what ICP enables.

Actively updating, improving.

Check it out: https://icpixel.org
Twitter: https://twitter.com/ICPixelEditor

How does this work if it’s all on the frontend? How can it be an NFT if it’s not on-chain?

My bad, that was worded poorly, the app itself doesn’t put the art on-chain, but it produces everything you need to mint NFTs properly.

Cool, would be a nice feature to add though. Collaborative art that’s owned by each of the contributors could also be a cool direction.

Yep, that’s cool, the plan is to expand into a community gallery where creators can showcase their work and actually monetize it.

Wow this is really cool and fast!

Reminds me of Amiga Paint or something.

Neat!

Glad you find it fun.

Looks amazing! Congratulations.

Looks really great. I made something but cant export as moving png, need to pay for it? If so than need to have some popup, currently its grey button, pressing it nothing happens.

Refreshed page, its gone now :frowning:

Glad you tried it out.
PNG sequence and WebM are both free, as is everything. I made a short video showing how to export these, here’s a workflow example:

Not sure which greyed-out button you hit if you can point me to it I’ll take a look.

Sorry, on refresh the editor doesn’t auto-save yet, so refreshing will reset the current project. You’ll want to save locally or to the canister before refreshing, then reload it after.

Thanks for giving it a go!

Might have been problem with browser, not sure, at first worked and than stopped popping up download tab. Now during second test worked fine.

Any reason why we cant export as GIF. WebM wont open in VLC player, cant even post any of those files in this forum.

GIF might be more useful.
kisses feel GIF

This is cute. Nice work

Yeah, makes sense. WebM is there mainly because it’s smaller and faster to generate in-browser, but I agree GIF is better for sharing, so I’ll likely add it as well for the next update.
For now, WebM should open fine in the browser, or you can just convert it to GIF online, there are a lot of quick tools for that.

Still lots more to add or work on, there’s so much possibility. :heart:

Thank you, it only gets prettier from this point.

Hope you don’t mind us listing it in OISY…?

Wow, neat, thank you very much! :heart: