How it is built, and how to build it.
Sloom Studio is a TypeScript application: React 19 on Vite 8 for the interface, Electron 41 for the desktop shell, Capacitor for Android. One repository, one project model, four workspaces. About 2,400 tracked files and 960 test files run under Vitest.
Build, run, test
Node 20 or newer. No native toolchain is needed for the web build; the desktop build downloads a matching Electron once.
git clone https://github.com/Es00bac/sloom-studio.git
cd sloom-studio
npm ci
npm run dev # the app in a browser at the Vite URL
npm run build # tsc -b && vite build
npm test # vitest, the whole suite
npm run desktop:dev # Electron shell against the dev server
npm run dist:linux # AppImage and deb into release/
The desktop packager expects the bundled font library under build/font-library; npm run prepare:font-library stages it from a font-pack checkout described in resources/font-pack/. All bundled fonts are OFL or Apache licensed and the inventory records each one's source and hash.
Repository layout
| Path | What lives there |
|---|---|
src/features/{flow,image*,paper,video} | Workspace-level feature code and their workspace shells. |
src/components/ | Shared UI: the dockable panel system, the Image editor, Paper, Flow nodes, settings, recovery. |
src/store/ | Zustand stores: one per workspace plus settings, confirmation and dock state. |
src/lib/ | Formats and engines without UI: .sloom project files, .slimg v1 and v2, PSD via ag-psd, PDF/X output on pdf-lib, HarfBuzz shaping, Little CMS colour management, i18n. |
electron/ | Main process: windows, menus, the D-Bus panel-menu exporter for KDE, crash reports, the native render and upscaler bridges. |
shared/ | Contracts shared by renderer and main: project schema, workspace menus, third-party notices. |
ops/native-render, ops/local-upscaler | Optional desktop helpers: a local FFmpeg render service and the on-demand Real-ESRGAN upscaler. |
desktop/kde/ | The two Plasma applets. |
packaging/ | Desktop entry, Gentoo overlay, Arch PKGBUILDs. |
docs/ | User guide, bilingual manual, feature breakdown, the "Missing Hundred" gap register. |
The project model
A .sloom project is a ZIP container holding a JSON manifest validated against shared/project-schema.json, the four workspace states, and a source library of assets in named bins. Image and Paper also have standalone documents, .slimg and .slppr, so a single image or layout travels on its own. Everything is local: the only network code is the optional Flow provider layer and the opt-in LAN sync between a desktop and a phone.
Workspaces
Image
Tiled undo with 64 px deltas, masks with feathering, nested groups with pass-through blending, high-bit documents, a true CMYK mode with ICC conversion, text on Bézier paths, editable warps, vertical Japanese text, PSD round-trip that keeps structure.
Paper
Page grids, panels and balloons, HarfBuzz shaping, tategaki with furigana, hyphenation, imposition-aware PDF/X-1a and PDF/X-4 with output intents, KDP interiors, EPUB, CBZ and IDML interchange.
Video
Timeline with keyframes and overlays, proxy playback, equal-power audio fades, ffmpeg.wasm in the browser and a native FFmpeg service on the desktop, with render parity checks between the two.
Flow
A node graph on xyflow with provider packs, spend caps, result caching and resumable batch runs. Provider keys are encrypted at rest and never leave the machine except to the provider you chose.
Desktop shell
Electron with a sandboxed renderer and a small preload bridge. On Linux the app runs on native Wayland; because Chromium cannot register a menu with KWin there, the main process exports the menu bar as a com.canonical.dbusmenu object on the session bus, and the forked Plasma applet in desktop/kde/sloom-globalmenu picks it up. That fork changes about 25 lines of KDE's stock applet.
The engine seam
Sloom Studio's Image workspace has a built-in brush engine, the Studio engine, which is GPL like everything else here. A second, physical-media engine called Tiltmark powers Hane on Android and is proprietary; it is not in this repository. What remains is a seam: src/components/ImageEditor/tiltmark/ holds the document-format code that lets files with physical-media layers open read-only, plus no-op stubs that report the engine as absent. If you are looking for the interesting brush code, start at ImageBrushEngine.ts and tools/brushTool.ts. A commercial Tiltmark plugin that attaches at this seam is planned; contributions that keep the seam stable and testable are welcome, contributions that reimplement the engine are not the goal of this repository.
Packaging
scripts/package-linux-release.sh builds the web bundle, stages fonts, runs electron-builder for AppImage and deb (and rpm when rpmbuild exists), then produces the /opt tarball and the applet tarballs with checksums. The Gentoo ebuilds and Arch PKGBUILDs consume those exact artifacts.
Quality bar
Type-check and tests must pass; a behaviour change ships with a test change next to the code. The docs are written to describe what the code does today, and docs/userguide/15-qualified-missing-hundred-features.md is the register of gaps we know about, with a status for each. Read it before proposing a large feature; it may already be specified.