GrobPaint

March 15, 2026 ยท View on GitHub

Somewhere between MS Paint and Paint.NET. Multiplatform by default.

Paint.NET doesn't run on macOS. GrobPaint fills that gap: a lightweight image editor with layers, blend modes, and selection tools, built with web technologies and a tiny Python backend. The goal isn't to clone Paint.NET or compete with Photoshop. It's to have the tools you actually need without the bloat.

Python Platform License

GrobPaint screenshot

Features

  • Layers - add, delete, duplicate, merge, reorder, per-layer opacity and blend modes (16 modes)
  • Tools - Pencil, Brush, Eraser, Fill, Eyedropper, Line, Rectangle, Ellipse, Text, Select, Magic Wand, Lasso, Move
  • Selection - rectangular, magic wand with live tolerance, and freehand lasso; move/resize/rotate content with handles, copy/cut/paste, crop to selection
  • Adjustments - brightness/contrast, hue/saturation/lightness, gaussian blur, sharpen (unsharp mask) - all with live preview
  • Color - HSV picker, RGB/Hex input, alpha channel, palettes (Lospec 500, PICO-8), swap primary/secondary
  • Canvas - zoom (scroll wheel, pinch, keyboard, editable input + slider), pan (space+drag, middle-click, trackpad), fit-to-view, grid overlay
  • File I/O - PNG, JPEG, BMP, GIF; native .gbp project format preserves layers as a ZIP archive
  • Sprite sheets - split a sheet into layers, or export layers as a horizontal sheet
  • Image operations - scale (nearest/bilinear/bicubic), canvas resize with anchor, flip, flatten
  • Multi-document - draggable tabs, multiple images open at once
  • Clipboard - copy/paste within app and to/from system clipboard
  • Auto-save - all work is persisted to localStorage automatically

Getting started

Run from source

python grobpaint.py

This launches a native window using pywebview. If pywebview isn't installed, it falls back to your default browser.

To force browser mode:

python grobpaint.py --browser

Dependencies:

  • Python 3.9+
  • pywebview (optional, for native window) - pip install pywebview

No npm, no bundler, no build step. The frontend is vanilla JS with ES modules. GrobPaint is also a PWA - it can be installed from the browser and works offline.

Build a standalone app

./build.sh

Produces dist/GrobPaint.app (macOS) or dist/GrobPaint/GrobPaint (binary) via PyInstaller.

Use in browser only

You can also open index.html directly or serve it with any static file server. File dialogs won't be available, but the editor falls back to browser file input and download for open/save.

Keyboard shortcuts

ShortcutAction
P B E F I L R O T S W MTool hotkeys
[ / ]Decrease / increase brush size
XSwap primary/secondary colors
+ / -Zoom in / out
Ctrl+0Fit in view
Ctrl+1Actual size (100%)
Ctrl+NNew image
Ctrl+OOpen file
Ctrl+SSave
Ctrl+Shift+SSave as
Ctrl+Z / Ctrl+Shift+ZUndo / redo
Ctrl+C / Ctrl+X / Ctrl+VCopy / cut / paste
Ctrl+A / Ctrl+DSelect all / deselect
Ctrl+GToggle grid
EnterCommit active transform
EscapeCancel active transform
DeleteDelete selection
Space + dragPan canvas

Project format

.gbp files are ZIP archives containing:

manifest.json       # dimensions, layer metadata (name, opacity, visibility, blend mode)
layers/
  layer_0.png
  layer_1.png
  ...

Architecture

The app is ~5000 lines of vanilla JavaScript split across five modules:

FileRole
js/core.jsEventBus, Layer, History (swap-based undo/redo), PaintDocument, Selection with contour tracing
js/renderer.jsCompositing engine, checkerboard background, zoom/pan, grid overlay
js/tools.jsAll tools, flood fill, flood select, lasso, Bresenham line
js/ui.jsColor system, HSV picker, layers panel, document tabs, menus, dialogs, image adjustments
js/app.jsApp init, canvas events, keyboard shortcuts, file I/O, clipboard
grobpaint.pyPython HTTP server + pywebview launcher, native file dialogs
sw.jsService worker for PWA offline support

No frameworks, no dependencies beyond one CDN include (JSZip for browser-side .gbp support).

Acknowledgments

GrobPaint was built with significant help from Claude by Anthropic.