A Mastodon client for the Linux desktop, written in Rust with GTK 4.
Created by AI Sloperator with Claude Code.
No license is given.
- Multiple accounts, with OAuth login, switching and logout (which revokes the token)
- Timelines: home, local, federated, hashtags, lists, trending posts, bookmarks and favourites
- Notifications, mentions and private conversations
- Live updates over the streaming API, with an unread badge and a "new items" button
- Posts: content warnings, sensitive-media covers, image viewer with alt text, link cards (right-click to open the link or copy it, also as Markdown), polls (with voting), threads with indented replies, translation
- Actions: reply, boost, favourite, bookmark, edit, delete, delete & re-draft, pin, mute conversation, copy link or text, report
- Composer: character counter using the instance limit, content warning, visibility, language, media upload (file picker or paste) with alt text, polls, and Ctrl+Enter to send; if the server is slow or down, it shows that and you can cancel or try again without losing the post
- Profiles: bio, verified fields, follow or follow request, notify on new posts, hide boosts, mute, block, domain block, list membership, followers and following
- Search for accounts, hashtags and posts (URLs from other servers are resolved)
- Explore (trending posts, hashtags and news), followed hashtags, follow requests, list management, mutes and blocks, profile editing (including avatar and header)
- Keyword and hashtag filters: view, add, edit and delete them; matching posts are collapsed behind a warning or hidden, as each filter says
- Links to profiles, posts and hashtags on any server open inside the app
- The sidebar can shrink to icons only (the button at its foot), with labels as tooltips
| Key | Action |
|---|---|
| Ctrl+N | New post |
| F5 / Ctrl+R | Refresh |
| Alt+Left / Esc / Backspace | Back |
| Ctrl+F | Search |
| Ctrl+Enter | Send post |
| Ctrl+Q | Quit |
| PgDn / Space | Page down |
| PgUp / Shift+Space | Page up |
Paging lands on the start of a post where that doesn't skip anything, and pages through posts taller than the window. Paging up twice at the top of a feed checks for new posts; paging twice past either end of a thread checks for new replies. Space and Backspace still type in text fields, and Backspace does nothing on a top-level page (there's nothing to go back to).
In the image viewer:
| Key or gesture | Action |
|---|---|
| Right / Space, or click the image | Next image |
| Left / Backspace, or click its left 20% | Previous image |
| Swipe or drag left / right | Next / previous |
| Esc / Ctrl+W | Close |
System packages (Debian/Ubuntu names):
sudo apt install pkgconf libgtk-4-dev libsoup-3.0-dev
Then, with a stable Rust toolchain from rustup:
cargo build --release
./target/release/fedigoo
The only crate dependencies are the GTK bindings (gtk4) and the libsoup
bindings (soup3) plus their own dependencies. JSON handling and the HTML
conversion are built in. HTTPS uses libsoup and glib-networking.
fedigoo # GTK picks the backend (honours GDK_BACKEND)
fedigoo --x11 # force X11
fedigoo --wayland # force Wayland
./target/release/fedigoo --install
This copies the executable to ~/.local/bin/fedigoo, and adds a menu entry
(~/.local/share/applications/com.aisloperator.FediGoo.desktop) and an icon
(under ~/.local/share/icons/hicolor/), so FediGoo shows up in your
application menu and dock. fedigoo --uninstall removes those files and
leaves your accounts and settings alone.
Log in through the welcome screen. FediGoo opens your instance's authorisation page in the browser; paste the code it shows back into FediGoo.
All local data (accounts, access tokens, OAuth client registrations,
preferences) is in $XDG_CONFIG_HOME/fedigoo/config.json, normally
~/.config/fedigoo/config.json. The file is created with owner-only
permissions.
cargo test # offline unit tests
cargo test -- --ignored # also hits the public mastodon.social API
For testing the UI without a display, GTK's Broadway backend works, and
tools/broadway-input.py sends it real pointer and keyboard input (clicks,
drags, key shortcuts) in place of a web browser. Its docstring has the details.
This section is updated before each release, from a build on the reference system: Debian 13 (trixie) on amd64 (x86_64), using Debian's own packages for GTK 4, libsoup 3 and the other system libraries.
How much of it is specific to the reference system differs by list:
- Direct crates come from
Cargo.toml, so they are the same everywhere. - Indirect crates come from the committed
Cargo.lock, listed for an x86_64 Linux build. A build from the same lock file uses the same crate versions on any system, though another target may build a slightly different set of crates. Acargo updatecan change the versions. - Non-crate libraries (both lists) are what the reference system's release binary links to and loads. Another distribution, distribution version or architecture may have other library versions or sonames, link a different set, or load other modules at run time.
These are the dependencies in Cargo.toml, with their version requirements.
gtk4 is imported under the name gtk, and soup3 under the name soup.
These are the system libraries that the release binary links to directly, as reported
by objdump -p on the reference system. Through the crate bindings, the app's code also
calls Pango and GDK, which are loaded as part of GTK. Building also needs the
pkg-config and glib-compile-resources tools and the GTK 4 and libsoup 3 development
files (Debian: pkgconf libgtk-4-dev libsoup-3.0-dev).
- libc (GNU C Library)
- libgcc_s
- libgio-2.0 (GIO)
- libglib-2.0 (GLib)
- libgobject-2.0 (GObject)
- libgraphene-1.0 (Graphene)
- libgtk-4 (GTK 4)
- libsoup-3.0 (libsoup 3)
These are every other crate in the build (normal and build-time dependencies) as
resolved in Cargo.lock for x86_64 Linux at the time of this update, from
cargo tree -e normal,build. Where a crate appears in more than one version, all
versions are listed. A later cargo update within the same Cargo.toml requirements
may resolve different versions, which might bring in different crates. Some of these
(such as system-deps, pkg-config, syn and toml) are used only while compiling
and are not part of the binary.
autocfg1.5.1bitflags2.13.2cairo-rs0.22.9cairo-sys-rs0.22.9cfg-expr0.20.10equivalent1.0.3field-offset0.3.6futures-channel0.3.34futures-core0.3.34futures-executor0.3.34futures-io0.3.34futures-macro0.3.34futures-task0.3.34futures-util0.3.34gdk-pixbuf0.22.0gdk-pixbuf-sys0.22.9gdk40.11.5gdk4-sys0.11.5gio0.22.10gio-sys0.22.9glib0.22.10glib-macros0.22.9glib-sys0.22.9gobject-sys0.22.9graphene-rs0.22.8graphene-sys0.22.9gsk40.11.5gsk4-sys0.11.5gtk4-macros0.11.5gtk4-sys0.11.5hashbrown0.17.1heck0.5.0indexmap2.14.2libc0.2.191memchr2.8.3memoffset0.9.1pango0.22.9pango-sys0.22.9pin-project-lite0.2.17pkg-config0.3.34proc-macro-crate3.5.0proc-macro21.0.107quote1.0.47rustc_version0.4.1semver1.0.28serde_spanned1.1.2slab0.4.12smallvec1.16.4soup3-sys0.9.0syn3.0.9system-deps7.0.8,9.0.1target-lexicon0.13.5toml1.1.8+spec-1.1.0toml_datetime1.1.2+spec-1.1.0toml_edit0.25.17+spec-1.1.0toml_parser1.1.5+spec-1.1.0unicode-ident1.0.27version-compare0.2.1winnow1.0.4
These are the libraries loaded because of the direct ones above, as reported by ldd
for the release binary on the reference system, plus modules that GLib and GTK load at run
time, which ldd doesn't show. The exact set depends on how the distribution
built GTK, GLib and libsoup, and on the desktop, so other systems may differ.
- libatomic
- libblkid
- libbrotlicommon
- libbrotlidec
- libbz2
- libcairo
- libcairo-gobject
- libcairo-script-interpreter
- libcloudproviders
- libcom_err
- libdatrie
- libdconfsettings (dconf GSettings backend, loaded at run time)
- libdeflate
- libEGL, libGL and Mesa or other OpenGL/Vulkan drivers (loaded at run time by libepoxy and libvulkan)
- libepoxy
- libexpat
- libffi
- libfontconfig
- libfreetype
- libfribidi
- libgdk_pixbuf-2.0
- libgiognutls (glib-networking TLS module, loaded at run time)
- libgmodule-2.0
- libgnutls (GnuTLS, used by libgiognutls)
- libgraphite2
- libgssapi_krb5
- libharfbuzz
- libharfbuzz-subset
- libidn2
- libjbig
- libjpeg
- libk5crypto
- libkeyutils
- libkrb5
- libkrb5support
- libLerc
- liblzma
- liblzo2
- libm
- libmount
- libnghttp2
- libpango-1.0
- libpangocairo-1.0
- libpangoft2-1.0
- libpcre2-8
- libpixbuf_svg and other gdk-pixbuf image s, with librsvg (loaded at run time)
- libpixman-1
- libpng16
- libpsl
- libresolv
- libselinux
- libsharpyuv
- libsqlite3
- libstdc++
- libthai
- libtiff
- libunistring
- libvulkan
- libwayland-client
- libwayland-egl
- libwebp
- libX11
- libXau
- libxcb
- libxcb-render
- libxcb-shm
- libXcursor
- libXdamage
- libXdmcp
- libXext
- libXfixes
- libXi
- libXinerama
- libxkbcommon
- libXrandr
- libXrender
- libz
- libzstd