Contributing to PaintFE
February 25, 2026 ยท View on GitHub
Thanks for taking the time. PaintFE is a solo-maintained project and outside contributions mean a lot, whether that is a bug fix, a new locale file, a documentation improvement, or a filter idea.
This document covers how to get a development build running, the conventions used in the codebase, and what a pull request should look like before it is submitted.
Getting started
You will need a recent stable Rust toolchain. The project uses Rust edition 2024, so you need at least Rust 1.85.
git clone https://github.com/kylejckson/paintfe
cd paintfe
cargo build
cargo run
A debug build is fine for development work. For testing anything performance-sensitive (compositing, GPU pipelines, large images), build with --release.
Linux: You will need a few system packages before the build will succeed:
sudo apt-get install -y \
libgtk-3-dev \
libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
libxkbcommon-dev \
libvulkan-dev \
libwayland-dev \
libegl1-mesa-dev \
libssl-dev \
pkg-config
Windows: No additional system dependencies. A working DirectX 12 driver is all that is required at runtime.
Code style
The codebase uses standard rustfmt formatting. Run cargo fmt before committing. There is no custom .rustfmt.toml, so the defaults apply.
Clippy is also expected to pass cleanly:
cargo clippy -- -D warnings
If a Clippy lint is a false positive or genuinely not applicable to a specific case, you can suppress it with #[allow(...)] on that item -- but add a comment explaining why.
A few conventions used in the codebase:
- Operations that mutate canvas state live in
src/ops/. Filters go infilters.rs, geometric transforms intransform.rs, color adjustments inadjustments.rs, generation effects ineffects.rs. - UI code lives in
src/app.rs(main loop, menus) andsrc/components/(panels, tools, dialogs). - GPU pipelines live in
src/gpu/. If you are adding a GPU compute path, follow the pattern incompute.rsand expose it viaGpuRendererinrenderer.rs. - New tools are added as variants in the
Toolenum insrc/components/tools.rs. There is no per-tool trait file; everything goes throughToolsPanel. - Undo: use
PixelPatch/BrushCommandfor strokes,SingleLayerSnapshotCommandfor single-layer effect commits, andSnapshotCommand(full canvas) only for canvas-wide operations like resize or flatten.
Commit messages
Keep commit messages short and factual. No need for a strict format, but aim for something that explains what changed and why if it is not obvious.
Good:
Add Crystallize filter with configurable cell size
Fix gradient fast path skipping eraser opacity on single-layer canvas
Not helpful:
fix stuff
update
wip
If a commit fixes a reported issue, reference it: Fix crash when opening zero-byte PNG (#42).
Pull requests
Before opening a PR:
- Run
cargo fmtso the diff is clean. - Run
cargo clippy -- -D warningsand resolve anything new that your change introduced. - Build with
cargo build --releaseat least once to confirm there are no release-mode issues. - Test the feature or fix manually in the running application.
For anything non-trivial, open an issue first to discuss the approach. This is not a hard rule, but it avoids situations where significant work gets done in a direction that does not fit the project.
PR descriptions should explain what the change does, why it is being made, and any trade-offs or limitations you are aware of.
Adding a translation
Translations are plain text files in locales/. Each file is named with a BCP-47 language code (de.txt, ja.txt, etc.). The format is one key = value pair per line. Comments start with #.
To add a new language:
- Copy
locales/en.txtto a new file named with the correct language code. - Translate the values. Do not change the key names.
- Open a PR with the new file.
If you are updating an existing translation, check whether any keys in en.txt are missing from the file you are editing -- new features sometimes add new strings.
Reporting bugs
Open a GitHub issue. Include:
- Your OS and GPU
- PaintFE version (shown in Edit > Preferences > About)
- Steps to reproduce
- The log file from
%APPDATA%\PaintFE\paintfe.log(Windows) or~/.local/share/PaintFE/paintfe.log(Linux) if there is one
If the bug involves a specific file that triggers it, attaching the file to the issue is very helpful.
Security issues
Do not open a public issue for security vulnerabilities. See SECURITY.md for the private reporting process.
License
By submitting a pull request, you agree that your contribution will be licensed under the MIT license that covers this project.