- Enhanced cursor behavior for new tools: semantic select, mask lasso, and mask rectangle. - Updated mask edit state to include mask asset ID and kind. - Implemented inpaint region commands for adding, applying, and removing inpaint regions. - Introduced new operations for lasso and semantic selection tools. - Created UI components for candidate review and inpaint region management. - Added tests for inpaint region commands to ensure functionality. - Updated various components to support new inpaint features and improve user experience.
Image Studio
Image Studio is a Bun + React image editor prototype. It uses a command-driven architecture for document and editor state, a canvas/WebGL renderer layer, and a lightweight React UI for tools, layers, imports, exports, and shortcuts.
Features
- Import images into an artboard
- Save and open versioned project files with embedded, project-owned assets
- Automatic local recovery snapshots after document changes
- Export the active artboard as PNG
- Layer selection and layer sheet
- Select, transform, pan, brush, eraser, chroma key, and magic wand tools
- Mask-edit workflow support
- Undo/redo through command history
- Keyboard shortcuts and pointer/wheel canvas input
Tech stack
- Bun for runtime, package management, tests, and builds
- React 19
- Tailwind CSS 4
- shadcn/ui-style component utilities
- TypeScript
Getting started
Install dependencies:
bun install
Start the development server:
bun dev
To start Image Studio together with the local headless ComfyUI server:
bun run dev:full
The combined launcher reuses a ComfyUI server already listening at
http://127.0.0.1:8188. Otherwise, it starts the existing local ComfyUI
installation and stops that process when Image Studio exits. Its paths and
address can be overridden with the COMFYUI_BASE_DIR, COMFYUI_SOURCE_DIR,
COMFYUI_PYTHON, COMFYUI_MODEL_PATHS_CONFIG, COMFYUI_HOST, and
COMFYUI_PORT environment variables.
Build for production:
bun run build
Run the production server:
bun start
Scripts
| Command | Description |
|---|---|
bun dev |
Start the app with Bun hot reload |
bun run dev:full |
Start the app and local headless ComfyUI server |
bun run build |
Build the production bundle |
bun start |
Run the production server |
bun test |
Run tests |
bun run lint |
Run ESLint |
Keyboard shortcuts
| Shortcut | Action |
|---|---|
S |
Select tool |
B |
Brush tool |
E |
Eraser tool |
K |
Chroma key tool |
W |
Magic wand tool |
Shift + click |
Add to magic wand selection |
Alt + click |
Subtract from magic wand selection |
P |
Pan tool |
Space |
Hold to pan |
L |
Toggle layers |
Cmd/Ctrl + O |
Open image |
Shift + Cmd/Ctrl + O |
Open project |
Cmd/Ctrl + S |
Save project |
Cmd/Ctrl + Z |
Undo |
Shift + Cmd/Ctrl + Z |
Redo |
Delete / Backspace |
Delete selection |
Project structure
app/ Composition root for app wiring
commands/ Deterministic state changes and command history
core/ Pure document/domain models
editor/ Transient editor state, tools, viewport, selection, store
input/ Keyboard, pointer, wheel, and canvas input resolution
renderer/ Canvas/WebGL rendering and overlays
view/ React UI shell and controls
Architecture notes
State changes flow through commands. React components present state and dispatch user intent, while document/editor mutations are handled by command modules. The renderer consumes document and editor snapshots to draw the canvas and overlays without owning application state.