Contributing to Forgetty
April 21, 2026 · View on GitHub
Thanks for your interest in contributing! This guide gets you from clone to running the terminal, and helps you make your first contribution.
Building from source
Prerequisites
| Tool | Version | Install |
|---|---|---|
| Rust | stable | rustup.rs |
| Zig | 0.15+ | ziglang.org/download — builds libghostty-vt |
| GTK4 + libadwaita | 4.9+ | See below |
Install GTK4 development libraries:
# Debian/Ubuntu
sudo apt install libgtk-4-dev libadwaita-1-dev
# Fedora
sudo dnf install gtk4-devel libadwaita-devel
# Arch
sudo pacman -S gtk4 libadwaita
Clone and build
git clone --recursive https://github.com/vikgmdev/forgetty.git
cd forgetty
cargo build --release
The --recursive flag is required — libghostty-vt is a git submodule under crates/forgetty-vt/ghostty/. If you cloned without it:
git submodule update --init --recursive
First build takes a few minutes because Zig compiles libghostty-vt from source. Subsequent builds are fast.
Run
cargo run --release
Or with flags:
cargo run --release -- --working-directory ~/projects -e htop
Project structure
Forgetty is a Cargo workspace with 10 crates. The design principle is thin native shell + thick shared core — the GTK4 shell is ~7,400 lines, but ~70% of the code is platform-independent Rust that will be shared across future platform targets.
forgetty/
├── src/ # Binary entry point (main.rs, cli.rs)
├── crates/
│ ├── forgetty-core/ # Shared types, errors, coordinate types
│ ├── forgetty-vt/ # libghostty-vt FFI — VT parsing, screen state
│ │ └── ghostty/ # Git submodule (Ghostty source for Zig build)
│ ├── forgetty-pty/ # PTY spawn/lifecycle, I/O multiplexing
│ ├── forgetty-config/ # TOML config, 486 bundled themes, defaults
│ ├── forgetty-gtk/ # GTK4 platform shell — rendering, input, UI
│ ├── forgetty-watcher/ # Filesystem watcher for config hot reload
│ ├── forgetty-workspace/ # Session save/restore, workspace persistence
│ ├── forgetty-session/ # Daemon session manager (panes, tabs, routing)
│ ├── forgetty-sync/ # iroh QUIC transport for cross-device sync
│ └── forgetty-socket/ # JSON-RPC 2.0 over Unix socket
├── resources/themes/ # 486 bundled theme TOML files
├── assets/icons/ # App icon (SVG)
├── dist/linux/ # Desktop entry, man page, DEB build script
├── scripts/ # convert-iterm-themes.py (theme maintenance)
├── tests/
│ ├── stress/ # 25-scenario stress test suite
│ ├── integration/ # Integration tests
│ └── fixtures/ # Test fixtures
└── docs/
└── architecture/ # Technical docs and design decisions
Key crates
forgetty-gtk — Where most UI work happens. app.rs is the GTK4 application (tabs, splits, menus, shortcuts), terminal.rs handles per-pane rendering and state, input.rs maps GDK events to ghostty key/mouse encoders, clipboard.rs has the smart copy pipeline.
forgetty-vt — Safe Rust wrappers around libghostty-vt's C API. If you're adding a new terminal capability, this is where the FFI binding goes. Read the FFI section in the docs before touching this crate — there are hard-won rules from weeks of debugging.
forgetty-config — Config loading, theme system, and the bundled theme registry. Note: bundled_themes.rs is auto-generated by scripts/convert-iterm-themes.py — don't edit it by hand.
forgetty-pty — PTY management. Spawns the user's shell, handles resize, I/O channels.
Running checks
# Compile check (fast feedback)
cargo check --workspace
# Lint — must pass clean
cargo clippy --workspace -- -D warnings
# Run tests
cargo test --workspace
# Full release build
cargo build --release
Always run cargo clippy and cargo test before submitting a PR.
How we develop
Every feature goes through three phases:
- Plan — Write a spec with acceptance criteria (what does "done" look like?)
- Build — Implement, commit, verify no regressions
- QA — Test every acceptance criterion, verify behavior
For small fixes you can skip straight to a PR. For new features, writing clear acceptance criteria before you start coding will save time and make review faster.
Pull request guidelines
- One feature or fix per PR. Small, focused PRs get reviewed faster.
- Describe what changed and why. For bug fixes, include how to reproduce.
- Run checks locally before pushing:
cargo clippy --workspace && cargo test --workspace - Test manually — launch Forgetty and verify your change works. For UI changes, test with splits, multiple tabs, and at least one theme switch.
- Don't break existing features. If your change touches input handling, test that vim, htop, and basic shell usage still work.
- Match existing patterns. The codebase uses
Rc<RefCell<>>for shared state,try_borrow_mut()instead ofborrow_mut()to avoid panics, and GTK4 actions for keyboard shortcuts.
Branch naming
feat/quake-mode
fix/search-highlight-zoom
docs/config-reference
Commit messages
Use conventional prefixes:
feat: add quake/dropdown mode with global hotkey
fix: search highlights misaligned after font zoom
perf: reduce allocation in screen sync hot path
docs: add configuration reference
test: stress test for concurrent splits
Good first issues
Concrete, scoped tasks suitable for a first contribution:
-
Shift+Click to extend selection — Currently Shift+Click clears the selection instead of extending it to the click position. The selection code is in
crates/forgetty-gtk/src/terminal.rs. Look at how double-click-drag extends by word — similar logic, but from the existing selection anchor to the clicked cell. -
Auto-scroll during drag selection — When drag-selecting text and the mouse moves past the top or bottom edge of the viewport, the terminal should auto-scroll. The drag handling is in
terminal.rs. -
Tab reordering via drag-and-drop —
adw::TabBarsupports drag-to-reorder natively, but it needs to be wired up so the underlyingTabStateMapstays in sync. -
Custom cursor color in config — Add a
cursor_colorkey toconfig.tomlthat overrides the theme cursor color. Parsing inforgetty-config, rendering inforgetty-gtk/src/terminal.rs. -
Man page improvements — The man page at
dist/linux/forgetty.1could cover more CLI flags, environment variables, and config options.
Look for issues labeled good first issue on GitHub for the latest list.
Reporting bugs
Open a GitHub issue with:
- Forgetty version (
forgetty --version) - Linux distribution and version
- Display server (Wayland or X11):
echo $XDG_SESSION_TYPE - Steps to reproduce
- Expected vs actual behavior
- Terminal output or screenshots if relevant
Code of conduct
Be kind, be constructive, be welcoming. We're building this in the open and want contributions from everyone. Harassment, discrimination, and personal attacks have no place here.
License
By contributing to Forgetty, you agree that your contributions will be licensed under the MIT License, the same license that covers the project.
Questions?
Open a GitHub Discussion or file an issue. Happy to help you find the right place to start.