{"slug": "show-hn-mastodon-desktop-client-made-with-claude-using-rust-and-gtk4", "title": "Show HN: Mastodon desktop client, made with Claude, using Rust and GTK4", "summary": "A Linux desktop Mastodon client called FediGoo, written in Rust with GTK 4 and built using Claude Code by AI Sloperator, was posted to Hacker News' Show HN. FediGoo supports multiple accounts with OAuth login, home, local, federated, hashtag, list, trending, bookmark and favourite timelines, live updates over the streaming API, polls, filters and an image viewer, and builds with only the gtk4 and soup3 crate dependencies after installing pkgconf, libgtk-4-dev and libsoup-3.0-dev. The project ships with no license, and its accounts, access tokens and preferences are stored in ~/.config/fedigoo/config.json with owner-only permissions.", "body_md": "A Mastodon client for the Linux desktop, written in Rust with GTK 4.\n\nCreated by [AI Sloperator](https://www.aisloperator.com/) with Claude Code.\n\nNo license is given.\n\n- Multiple accounts, with OAuth login, switching and logout (which revokes the token)\n- Timelines: home, local, federated, hashtags, lists, trending posts, bookmarks and favourites\n- Notifications, mentions and private conversations\n- Live updates over the streaming API, with an unread badge and a \"new items\" button\n- 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\n- Actions: reply, boost, favourite, bookmark, edit, delete, delete & re-draft, pin, mute conversation, copy link or text, report\n- 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\n- Profiles: bio, verified fields, follow or follow request, notify on new posts, hide boosts, mute, block, domain block, list membership, followers and following\n- Search for accounts, hashtags and posts (URLs from other servers are resolved)\n- Explore (trending posts, hashtags and news), followed hashtags, follow requests, list management, mutes and blocks, profile editing (including avatar and header)\n- Keyword and hashtag filters: view, add, edit and delete them; matching posts are collapsed behind a warning or hidden, as each filter says\n- Links to profiles, posts and hashtags on any server open inside the app\n- The sidebar can shrink to icons only (the button at its foot), with labels as tooltips\n\n| Key | Action | \n|---|---|\n| Ctrl+N | New post | \n| F5 / Ctrl+R | Refresh | \n| Alt+Left / Esc / Backspace | Back | \n| Ctrl+F | Search | \n| Ctrl+Enter | Send post | \n| Ctrl+Q | Quit | \n| PgDn / Space | Page down | \n| PgUp / Shift+Space | Page up | \n\nPaging 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).\n\nIn the image viewer:\n\n| Key or gesture | Action | \n|---|---|\n| Right / Space, or click the image | Next image | \n| Left / Backspace, or click its left 20% | Previous image | \n| Swipe or drag left / right | Next / previous | \n| Esc / Ctrl+W | Close | \n\nSystem packages (Debian/Ubuntu names):\n\n```\nsudo apt install pkgconf libgtk-4-dev libsoup-3.0-dev\n```\n\nThen, with a stable Rust toolchain from rustup:\n\n```\ncargo build --release\n./target/release/fedigoo\n```\n\nThe only crate dependencies are the GTK bindings (`gtk4`) and the libsoup\nbindings (`soup3`) plus their own dependencies. JSON handling and the HTML\nconversion are built in. HTTPS uses libsoup and glib-networking.\n\n```\nfedigoo            # GTK picks the backend (honours GDK_BACKEND)\nfedigoo --x11      # force X11\nfedigoo --wayland  # force Wayland\n./target/release/fedigoo --install\n```\n\nThis copies the executable to `~/.local/bin/fedigoo`, and adds a menu entry\n(`~/.local/share/applications/com.aisloperator.FediGoo.desktop`) and an icon\n(under `~/.local/share/icons/hicolor/`), so FediGoo shows up in your\napplication menu and dock. `fedigoo --uninstall` removes those files and\nleaves your accounts and settings alone.\n\nLog in through the welcome screen. FediGoo opens your instance's authorisation page in the browser; paste the code it shows back into FediGoo.\n\nAll local data (accounts, access tokens, OAuth client registrations,\npreferences) is in `$XDG_CONFIG_HOME/fedigoo/config.json`, normally\n`~/.config/fedigoo/config.json`. The file is created with owner-only\npermissions.\n\n```\ncargo test                   # offline unit tests\ncargo test -- --ignored      # also hits the public mastodon.social API\n```\n\nFor testing the UI without a display, GTK's Broadway backend works, and\n`tools/broadway-input.py` sends it real pointer and keyboard input (clicks,\ndrags, key shortcuts) in place of a web browser. Its docstring has the details.\n\nThis 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.\n\nHow much of it is specific to the reference system differs by list:\n\n- **Direct crates** come from`Cargo.toml` , so they are the same everywhere.\n- **Indirect crates** come from the committed`Cargo.lock` , listed for an x86_64 Linux\nbuild. A build from the same lock file uses the same crate versions on any system,\nthough another target may build a slightly different set of crates. A`cargo update` can change the versions.\n- **Non-crate libraries** (both lists) are what the reference system's release binary\nlinks to and loads. Another distribution, distribution version or architecture may have other\nlibrary versions or sonames, link a different set, or load other modules at run time.\n\nThese are the dependencies in `Cargo.toml`, with their version requirements.\n`gtk4` is imported under the name `gtk`, and `soup3` under the name `soup`.\n\nThese are the system libraries that the release binary links to directly, as reported\nby `objdump -p` on the reference system. Through the crate bindings, the app's code also\ncalls Pango and GDK, which are loaded as part of GTK. Building also needs the\n`pkg-config` and `glib-compile-resources` tools and the GTK 4 and libsoup 3 development\nfiles (Debian: `pkgconf libgtk-4-dev libsoup-3.0-dev`).\n\n- libc (GNU C Library)\n- libgcc_s\n- libgio-2.0 (GIO)\n- libglib-2.0 (GLib)\n- libgobject-2.0 (GObject)\n- libgraphene-1.0 (Graphene)\n- libgtk-4 (GTK 4)\n- libsoup-3.0 (libsoup 3)\n\nThese are every other crate in the build (normal and build-time dependencies) as\nresolved in `Cargo.lock` for x86_64 Linux at the time of this update, from\n`cargo tree -e normal,build`. Where a crate appears in more than one version, all\nversions are listed. A later `cargo update` within the same `Cargo.toml` requirements\nmay resolve different versions, which might bring in different crates. Some of these\n(such as `system-deps`, `pkg-config`, `syn` and `toml`) are used only while compiling\nand are not part of the binary.\n\n- [`autocfg`](https://crates.io/crates/autocfg)` 1.5.1`\n- [`bitflags`](https://crates.io/crates/bitflags)` 2.13.2`\n- [`cairo-rs`](https://crates.io/crates/cairo-rs)` 0.22.9`\n- [`cairo-sys-rs`](https://crates.io/crates/cairo-sys-rs)` 0.22.9`\n- [`cfg-expr`](https://crates.io/crates/cfg-expr)` 0.20.10`\n- [`equivalent`](https://crates.io/crates/equivalent)` 1.0.3`\n- [`field-offset`](https://crates.io/crates/field-offset)` 0.3.6`\n- [`futures-channel`](https://crates.io/crates/futures-channel)` 0.3.34`\n- [`futures-core`](https://crates.io/crates/futures-core)` 0.3.34`\n- [`futures-executor`](https://crates.io/crates/futures-executor)` 0.3.34`\n- [`futures-io`](https://crates.io/crates/futures-io)` 0.3.34`\n- [`futures-macro`](https://crates.io/crates/futures-macro)` 0.3.34`\n- [`futures-task`](https://crates.io/crates/futures-task)` 0.3.34`\n- [`futures-util`](https://crates.io/crates/futures-util)` 0.3.34`\n- [`gdk-pixbuf`](https://crates.io/crates/gdk-pixbuf)` 0.22.0`\n- [`gdk-pixbuf-sys`](https://crates.io/crates/gdk-pixbuf-sys)` 0.22.9`\n- [`gdk4`](https://crates.io/crates/gdk4)` 0.11.5`\n- [`gdk4-sys`](https://crates.io/crates/gdk4-sys)` 0.11.5`\n- [`gio`](https://crates.io/crates/gio)` 0.22.10`\n- [`gio-sys`](https://crates.io/crates/gio-sys)` 0.22.9`\n- [`glib`](https://crates.io/crates/glib)` 0.22.10`\n- [`glib-macros`](https://crates.io/crates/glib-macros)` 0.22.9`\n- [`glib-sys`](https://crates.io/crates/glib-sys)` 0.22.9`\n- [`gobject-sys`](https://crates.io/crates/gobject-sys)` 0.22.9`\n- [`graphene-rs`](https://crates.io/crates/graphene-rs)` 0.22.8`\n- [`graphene-sys`](https://crates.io/crates/graphene-sys)` 0.22.9`\n- [`gsk4`](https://crates.io/crates/gsk4)` 0.11.5`\n- [`gsk4-sys`](https://crates.io/crates/gsk4-sys)` 0.11.5`\n- [`gtk4-macros`](https://crates.io/crates/gtk4-macros)` 0.11.5`\n- [`gtk4-sys`](https://crates.io/crates/gtk4-sys)` 0.11.5`\n- [`hashbrown`](https://crates.io/crates/hashbrown)` 0.17.1`\n- [`heck`](https://crates.io/crates/heck)` 0.5.0`\n- [`indexmap`](https://crates.io/crates/indexmap)` 2.14.2`\n- [`libc`](https://crates.io/crates/libc)` 0.2.191`\n- [`memchr`](https://crates.io/crates/memchr)` 2.8.3`\n- [`memoffset`](https://crates.io/crates/memoffset)` 0.9.1`\n- [`pango`](https://crates.io/crates/pango)` 0.22.9`\n- [`pango-sys`](https://crates.io/crates/pango-sys)` 0.22.9`\n- [`pin-project-lite`](https://crates.io/crates/pin-project-lite)` 0.2.17`\n- [`pkg-config`](https://crates.io/crates/pkg-config)` 0.3.34`\n- [`proc-macro-crate`](https://crates.io/crates/proc-macro-crate)` 3.5.0`\n- [`proc-macro2`](https://crates.io/crates/proc-macro2)` 1.0.107`\n- [`quote`](https://crates.io/crates/quote)` 1.0.47`\n- [`rustc_version`](https://crates.io/crates/rustc_version)` 0.4.1`\n- [`semver`](https://crates.io/crates/semver)` 1.0.28`\n- [`serde_spanned`](https://crates.io/crates/serde_spanned)` 1.1.2`\n- [`slab`](https://crates.io/crates/slab)` 0.4.12`\n- [`smallvec`](https://crates.io/crates/smallvec)` 1.16.4`\n- [`soup3-sys`](https://crates.io/crates/soup3-sys)` 0.9.0`\n- [`syn`](https://crates.io/crates/syn)` 3.0.9`\n- [`system-deps`](https://crates.io/crates/system-deps)` 7.0.8` ,`9.0.1`\n- [`target-lexicon`](https://crates.io/crates/target-lexicon)` 0.13.5`\n- [`toml`](https://crates.io/crates/toml)` 1.1.8+spec-1.1.0`\n- [`toml_datetime`](https://crates.io/crates/toml_datetime)` 1.1.2+spec-1.1.0`\n- [`toml_edit`](https://crates.io/crates/toml_edit)` 0.25.17+spec-1.1.0`\n- [`toml_parser`](https://crates.io/crates/toml_parser)` 1.1.5+spec-1.1.0`\n- [`unicode-ident`](https://crates.io/crates/unicode-ident)` 1.0.27`\n- [`version-compare`](https://crates.io/crates/version-compare)` 0.2.1`\n- [`winnow`](https://crates.io/crates/winnow)` 1.0.4`\n\nThese are the libraries loaded because of the direct ones above, as reported by `ldd`\nfor the release binary on the reference system, plus modules that GLib and GTK load at run\ntime, which `ldd` doesn't show. The exact set depends on how the distribution\nbuilt GTK, GLib and libsoup, and on the desktop, so other systems may differ.\n\n- libatomic\n- libblkid\n- libbrotlicommon\n- libbrotlidec\n- libbz2\n- libcairo\n- libcairo-gobject\n- libcairo-script-interpreter\n- libcloudproviders\n- libcom_err\n- libdatrie\n- libdconfsettings (dconf GSettings backend, loaded at run time)\n- libdeflate\n- libEGL, libGL and Mesa or other OpenGL/Vulkan drivers (loaded at run time by libepoxy and libvulkan)\n- libepoxy\n- libexpat\n- libffi\n- libfontconfig\n- libfreetype\n- libfribidi\n- libgdk_pixbuf-2.0\n- libgiognutls (glib-networking TLS module, loaded at run time)\n- libgmodule-2.0\n- libgnutls (GnuTLS, used by libgiognutls)\n- libgraphite2\n- libgssapi_krb5\n- libharfbuzz\n- libharfbuzz-subset\n- libidn2\n- libjbig\n- libjpeg\n- libk5crypto\n- libkeyutils\n- libkrb5\n- libkrb5support\n- libLerc\n- liblzma\n- liblzo2\n- libm\n- libmount\n- libnghttp2\n- libpango-1.0\n- libpangocairo-1.0\n- libpangoft2-1.0\n- libpcre2-8\n- libpixbufloader_svg and other gdk-pixbuf image loaders, with librsvg (loaded at run time)\n- libpixman-1\n- libpng16\n- libpsl\n- libresolv\n- libselinux\n- libsharpyuv\n- libsqlite3\n- libstdc++\n- libthai\n- libtiff\n- libunistring\n- libvulkan\n- libwayland-client\n- libwayland-egl\n- libwebp\n- libX11\n- libXau\n- libxcb\n- libxcb-render\n- libxcb-shm\n- libXcursor\n- libXdamage\n- libXdmcp\n- libXext\n- libXfixes\n- libXi\n- libXinerama\n- libxkbcommon\n- libXrandr\n- libXrender\n- libz\n- libzstd", "url": "https://wpnews.pro/news/show-hn-mastodon-desktop-client-made-with-claude-using-rust-and-gtk4", "canonical_source": "https://github.com/aisloperator/fedigoo", "published_at": "2026-11-04 21:03:44+00:00", "updated_at": "2026-11-04 21:20:38.318372+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools"], "entities": ["FediGoo", "AI Sloperator", "Claude Code", "Mastodon", "Rust", "GTK 4", "Hacker News"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-mastodon-desktop-client-made-with-claude-using-rust-and-gtk4", "markdown": "https://wpnews.pro/news/show-hn-mastodon-desktop-client-made-with-claude-using-rust-and-gtk4.md", "text": "https://wpnews.pro/news/show-hn-mastodon-desktop-client-made-with-claude-using-rust-and-gtk4.txt", "jsonld": "https://wpnews.pro/news/show-hn-mastodon-desktop-client-made-with-claude-using-rust-and-gtk4.jsonld"}}