Forbidden Editor for Artists 😈
See the code[!IMPORTANT] Darkly is in beta! Features are being added daily. Please report bugs so we can squash them.
Do you suffer from the oppressive sanity of rulers, guides, and nondestructive workflows? Break free with Darkly, home of happy accidents and beautiful catastrophies. Release your creativity from the bonds of logic. Madness isn't a bug, it's a feature.
Darkly is a Photoshop alternative where painters are first-class citizens. It has a powerful brush engine, and dark arts to help you commune with your imagination.
Use it on the web here.
Documentation here.
https://github.com/user-attachments/assets/1fc0632d-5846-4c64-bac8-e39b0794b8b5
Darkly's unique brushes live inside a node-based system. This enables infinite customizability, mixing and matching of brush features, and on-the-fly creation of custom brushes.
Veils are where Darkly gets its name; "For now we see through a glass, darkly". They're a special layer that shrouds your canvas in a mysterious way, inviting you to see something that maybe wasn't there before.
Veils are nondestructive. You can paint as usual, behind the veil, and if you disable it, you'll see the full-res result.
Veils are essentially fancy shaders, and they are fun toys. But they have practical uses too:
[!NOTE] Adding too many veils can drain your battery due to the heavy load on your GPU.
Voids are a type of layer that specializes in pulling inspiration from outside sources.
You can use the Noise void to generate entropy, or Screenshare to stream another app (3D software, movie, or video game) directly into a layer. This is great for hybrid workflows, and situations where you need a quick reference, or want to try out different lighting or camera angles, without having to pose, render and paste over and over.
Voids support masks and blend modes. They are the natural compliment to veils, and a natural integration point for other art programs like Blender, which has its own dedicated void 🧡
These features are ordered roughly by importance. They will be implemented mostly in order from top to bottom, prioritizing ones most requested by the community.
For a feature to count, it must be:
.darkly document# Install all workspace dependencies (frontend + website + shared styles)
npm install
# Build the WASM package
wasm-pack build frontend/wasm --target web
# Start the frontend dev server
npm --prefix frontend run dev
# ...or expose it on your LAN (binds all interfaces, 0.0.0.0)
npm --prefix frontend run dev -- --host
Open the URL printed by vite (typically https://localhost:5173). Requires a browser with WebGPU support (Chrome 113+, Edge 113+, Firefox Nightly with flag).
GPU backend configuration (Linux): Chrome's WebGPU defaults to a software rasterizer on many Linux setups. Launch Chromium with GPU and Vulkan support:
chromium --enable-features=Vulkan --enable-unsafe-webgpu
You can verify the active backend at chrome://gpu - look for "Vulkan" under Graphics Feature Status. On macOS and Windows this is generally not needed (Metal and D3D12 are used by default).
Darkly's core is a standalone, platform-agnostic Rust crate, darkly. The document model, brush engine, GPU compositor, and undo system all live here with zero platform dependencies, and run anywhere wgpu does: native (Vulkan / Metal / DX12) or the browser (WebGPU). The app above is a Svelte frontend over this exact crate, through a thin WebAssembly bridge.
If you're building a graphics tool in Rust -- a drawing app, annotation layer, whiteboard, texture editor, etc. -- you can embed the engine instead of writing all these features from scratch.
cargo add darkly
See the crate README for a runnable example, and the API docs for full details.
We love hackers as much as we love artists. Contributions are welcome! Please see CONTRIBUTING.md for details on how to contribute and rules of thumb for the repo.
It's acceptable to use AI for this codebase, but careless vibe coding is strictly forbidden.
I (TheTechromancer) learned to code before AI, and have spent much of my career maintaining large codebases. The danger of feature creep and architectural bloat is real, which is why whenever a feature is implemented in Darkly, a human must first understand the changes and their long-term implications for the codebase.
Great care is being taken to keep Darkly lean and clean. This means enforcing modularity, guarding vigilantly against duplicate/dead code, and writing a shit ton of unit tests, including at least one regression test for every bug. See CONTRIBUTING.md for how we avoid AI slop.
Note that while we allow AI for coding, we are unlikely to accept any PR implementing generative AI in Darkly itself. AI features are not off the table; however they must run fully offline and without any reliance on third party APIs. Additionally, any feature that speeds up generation while sacrificing creative input or control from the artist, will likely be rejected.
Every PR must open with a short human-written description explaining why the effort was undertaken and who it's useful to, above the AI-generated technical description. PRs that look entirely machine-generated will be closed.
We are not sensitive to AI-related questions. If you're unsure, please ask!
Darkly stands on the shoulders of giants. Three programs in particular have influenced this project, and we love them dearly.
GIMP (source) - originally written by Spencer Kimball and Peter Mattis in 1995, and maintained today by Michael Natterer and Jehan Pagès, with decades of contributions from a community far too large to list here (see the upstream AUTHORS file).
Krita (source) - led by Halla Rempt, with core contributions over the years from Dmitry Kazakov, Cyrille Berger, Sven Langkamp, Wolthera van Hövell tot Westerflier, L. E. Segovia, Scott Petrovic, and many more (see the upstream developers.txt).
Graphite (source) - founded by Keavon Chambers (@Keavon), with the core team of Dennis Kobert (@TrueDoctor), Timon Schelling (@timon-schelling), and Adam Gerhant (@pendapia), plus heroic contributions from Hypercube (@0HyperCube), James Lindsay, and hundreds more. Graphite is a pioneer in bringing serious 2D graphics tooling to Rust + WebAssembly + WebGPU.
While Darkly's architecture is fundamentally different, it was really insightful to see how these tools tackled many of the same hard problems, and their unique and smart approaches that made them pillars of open source!
A special thank you to Nick Cameron for graciously gifting us the darkly crate on crates.io. 💜
Some of Darkly's veil and void shaders are ports or adaptations of work originally published on Shadertoy. I suck at shaders and the creators of these shaders are true artists. Please go see them in their native habitat!
1,065 commits
19 commits
Rust
65.5%
TypeScript
22.6%
Svelte
8.4%
WGSL
2.2%
Forbidden Editor for Artists 😈
See the code[!IMPORTANT] Darkly is in beta! Features are being added daily. Please report bugs so we can squash them.
Do you suffer from the oppressive sanity of rulers, guides, and nondestructive workflows? Break free with Darkly, home of happy accidents and beautiful catastrophies. Release your creativity from the bonds of logic. Madness isn't a bug, it's a feature.
Darkly is a Photoshop alternative where painters are first-class citizens. It has a powerful brush engine, and dark arts to help you commune with your imagination.
Use it on the web here.
Documentation here.
https://github.com/user-attachments/assets/1fc0632d-5846-4c64-bac8-e39b0794b8b5
Darkly's unique brushes live inside a node-based system. This enables infinite customizability, mixing and matching of brush features, and on-the-fly creation of custom brushes.
Veils are where Darkly gets its name; "For now we see through a glass, darkly". They're a special layer that shrouds your canvas in a mysterious way, inviting you to see something that maybe wasn't there before.
Veils are nondestructive. You can paint as usual, behind the veil, and if you disable it, you'll see the full-res result.
Veils are essentially fancy shaders, and they are fun toys. But they have practical uses too:
[!NOTE] Adding too many veils can drain your battery due to the heavy load on your GPU.
Voids are a type of layer that specializes in pulling inspiration from outside sources.
You can use the Noise void to generate entropy, or Screenshare to stream another app (3D software, movie, or video game) directly into a layer. This is great for hybrid workflows, and situations where you need a quick reference, or want to try out different lighting or camera angles, without having to pose, render and paste over and over.
Voids support masks and blend modes. They are the natural compliment to veils, and a natural integration point for other art programs like Blender, which has its own dedicated void 🧡
These features are ordered roughly by importance. They will be implemented mostly in order from top to bottom, prioritizing ones most requested by the community.
For a feature to count, it must be:
.darkly document# Install all workspace dependencies (frontend + website + shared styles)
npm install
# Build the WASM package
wasm-pack build frontend/wasm --target web
# Start the frontend dev server
npm --prefix frontend run dev
# ...or expose it on your LAN (binds all interfaces, 0.0.0.0)
npm --prefix frontend run dev -- --host
Open the URL printed by vite (typically https://localhost:5173). Requires a browser with WebGPU support (Chrome 113+, Edge 113+, Firefox Nightly with flag).
GPU backend configuration (Linux): Chrome's WebGPU defaults to a software rasterizer on many Linux setups. Launch Chromium with GPU and Vulkan support:
chromium --enable-features=Vulkan --enable-unsafe-webgpu
You can verify the active backend at chrome://gpu - look for "Vulkan" under Graphics Feature Status. On macOS and Windows this is generally not needed (Metal and D3D12 are used by default).
Darkly's core is a standalone, platform-agnostic Rust crate, darkly. The document model, brush engine, GPU compositor, and undo system all live here with zero platform dependencies, and run anywhere wgpu does: native (Vulkan / Metal / DX12) or the browser (WebGPU). The app above is a Svelte frontend over this exact crate, through a thin WebAssembly bridge.
If you're building a graphics tool in Rust -- a drawing app, annotation layer, whiteboard, texture editor, etc. -- you can embed the engine instead of writing all these features from scratch.
cargo add darkly
See the crate README for a runnable example, and the API docs for full details.
We love hackers as much as we love artists. Contributions are welcome! Please see CONTRIBUTING.md for details on how to contribute and rules of thumb for the repo.
It's acceptable to use AI for this codebase, but careless vibe coding is strictly forbidden.
I (TheTechromancer) learned to code before AI, and have spent much of my career maintaining large codebases. The danger of feature creep and architectural bloat is real, which is why whenever a feature is implemented in Darkly, a human must first understand the changes and their long-term implications for the codebase.
Great care is being taken to keep Darkly lean and clean. This means enforcing modularity, guarding vigilantly against duplicate/dead code, and writing a shit ton of unit tests, including at least one regression test for every bug. See CONTRIBUTING.md for how we avoid AI slop.
Note that while we allow AI for coding, we are unlikely to accept any PR implementing generative AI in Darkly itself. AI features are not off the table; however they must run fully offline and without any reliance on third party APIs. Additionally, any feature that speeds up generation while sacrificing creative input or control from the artist, will likely be rejected.
Every PR must open with a short human-written description explaining why the effort was undertaken and who it's useful to, above the AI-generated technical description. PRs that look entirely machine-generated will be closed.
We are not sensitive to AI-related questions. If you're unsure, please ask!
Darkly stands on the shoulders of giants. Three programs in particular have influenced this project, and we love them dearly.
GIMP (source) - originally written by Spencer Kimball and Peter Mattis in 1995, and maintained today by Michael Natterer and Jehan Pagès, with decades of contributions from a community far too large to list here (see the upstream AUTHORS file).
Krita (source) - led by Halla Rempt, with core contributions over the years from Dmitry Kazakov, Cyrille Berger, Sven Langkamp, Wolthera van Hövell tot Westerflier, L. E. Segovia, Scott Petrovic, and many more (see the upstream developers.txt).
Graphite (source) - founded by Keavon Chambers (@Keavon), with the core team of Dennis Kobert (@TrueDoctor), Timon Schelling (@timon-schelling), and Adam Gerhant (@pendapia), plus heroic contributions from Hypercube (@0HyperCube), James Lindsay, and hundreds more. Graphite is a pioneer in bringing serious 2D graphics tooling to Rust + WebAssembly + WebGPU.
While Darkly's architecture is fundamentally different, it was really insightful to see how these tools tackled many of the same hard problems, and their unique and smart approaches that made them pillars of open source!
A special thank you to Nick Cameron for graciously gifting us the darkly crate on crates.io. 💜
Some of Darkly's veil and void shaders are ports or adaptations of work originally published on Shadertoy. I suck at shaders and the creators of these shaders are true artists. Please go see them in their native habitat!
1,065 commits
19 commits
Rust
65.5%
TypeScript
22.6%
Svelte
8.4%
WGSL
2.2%