Skip to content

sethcottle/hangar

Repository files navigation

Hangar

Hangar

A native Bluesky client for Linux, built with Rust, GTK4, and Libadwaita. Learn more at hangar.blue.

Technical Preview: Hangar is in early development. The foundations are being built feature by feature. Expect rough edges, missing functionality, and breaking changes.

License Status Rust GTK4 AT Protocol Platform CI GitHub Release GitHub Downloads GitHub last commit GitHub issues Repo size

What is Hangar?

Hangar is a desktop Bluesky client designed specifically for Linux and the GNOME desktop environment. No Electron, no web views, no hybrid UI—just native GTK4 with Libadwaita for a fast, integrated experience.

Goals

  • Purpose-built: Built for Linux, feels at home in GNOME, with each feature being meticulously crafted
  • Performance: Instant startup, smooth scrolling, efficient memory usage, optimized networking
  • Full Bluesky support: Timeline, feeds, posts, interactions, notifications, and DMs

Current Status

This is a technical preview. The app is functional but incomplete. Development follows a slice-by-slice methodology. One feature at a time, end-to-end.

What Works

  • Authentication: OAuth (PKCE + DPoP) with persistent sessions, app password fallback
  • Timeline: Home feed with infinite scroll, cursor-based pagination, pull-to-refresh
  • Custom Feeds: Feed selector with Following, Discover, and pinned feeds
  • Live Updates: Background polling with seamless new post insertion
  • Rich Embeds: Image grids (1–4+), external link cards, video thumbnails, quote posts
  • Interactions: Like/unlike, repost/unrepost, quote, reply
  • Compose: Rich text highlighting (mentions, hashtags, URLs), mention autocomplete, image attachments (up to 4 with alt text), link card preview (Open Graph), language selection, per-post content warnings, interaction settings, thread composer
  • Navigation: Home, Mentions, Activity, Chat, Profile, Likes, Search tabs with drill-down views
  • Thread View: Full thread with parent posts and replies
  • Profile View: Own profile with banner, bio, follower/following/post counts; drill-down profiles from clicking avatars
  • Notifications: Mentions tab with filtered notifications; Activity tab with badge overlays and embedded post cards
  • Chat: Conversation list with unread badges and last message preview
  • Search: Search tab with results list and interactions
  • Settings: Display (post text size, color scheme), Accessibility (reduce motion), Account (content safety link, clear cache)
  • Caching: SQLite cache for posts, feeds, profiles, images, notifications with per-user isolation and automatic eviction
  • Accessibility: Accessible roles and labels, keyboard shortcuts (F5/Ctrl+R), reduced motion support, focus ring visibility, theme variable usage, non-color state indicators

What's Next

  • Follow/unfollow
  • Chat message thread view and sending
  • Keyboard shortcuts for navigation and post actions
  • Enhanced screen reader support (composite labels, live regions, focus management)
  • Image lightbox, loading skeletons
  • Full profile view on drill-down, profile editing
  • Internationalization (i18n) and Flatpak distribution
  • Bookmarks, moderation tools, desktop notifications, multi-account support
  • Lots of polish

Authentication

OAuth (Recommended)

Hangar uses OAuth (PKCE + DPoP) for authentication. When you sign in, a browser window opens to complete the authorization flow via your Bluesky PDS. Sessions are persisted locally and automatically refreshed.

App Password (Fallback)

App password authentication is also supported as a fallback:

  1. Go to bsky.app/settings/app-passwords
  2. Create a new app password
  3. Use that password to log in to Hangar

App passwords can be revoked at any time without affecting your main account password.

Session Storage

OAuth sessions are stored in a local file-based session store. App password sessions are stored securely using libsecret (the GNOME keyring). If libsecret/D-Bus is unavailable, app password session persistence will fail gracefully and you'll need to log in each time.

Installation

AppImage

Download the latest AppImage from the Releases page, make it executable, and run:

chmod +x Hangar-x86_64.AppImage
./Hangar-x86_64.AppImage

The AppImage supports delta updates via zsync and is also available through the AM AppImage package manager:

am -i hangar

Flatpak (sideload)

Download the .flatpak bundle from the Releases page and install:

flatpak install hangar.flatpak

Flathub submission is planned but not yet available.

Build from Source

Dependencies

Fedora/RHEL:

sudo dnf install gtk4-devel libadwaita-devel gcc pkg-config

Ubuntu/Debian:

sudo apt install libgtk-4-dev libadwaita-1-dev build-essential pkg-config

Arch:

sudo pacman -S gtk4 libadwaita base-devel

Build & Run

cargo build --release
cargo run --release

Architecture Overview

┌─────────────────────────────────────────────┐
│                  UI Layer                   │
│          GTK4 + Libadwaita widgets          │
│    (window, sidebar, post_row, dialogs)     │
└─────────────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────┐
│             Application Layer               │
│     Orchestrates login, data fetching,      │
│     navigation, state management            │
└─────────────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────┐
│            AT Protocol Layer                │
│         HangarClient wraps atrium           │
│     Converts atrium types → app types       │
└─────────────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────┐
│            External Crates                  │
│        atrium-api, reqwest, tokio           │
└─────────────────────────────────────────────┘

Threading Model

GTK runs on the main thread. Network I/O runs on background threads with a shared Tokio runtime. Results are sent back to the main thread via glib::timeout_add_local polling or glib::spawn_future_local. A semaphore limits concurrent API requests to 4.

Technology Stack

Component Technology
Language Rust (2024 edition)
UI Toolkit GTK4 + Libadwaita
AT Protocol atrium-api + atrium-oauth
HTTP Client reqwest (rustls-tls)
Async Runtime Tokio
Cache rusqlite (SQLite, bundled)
Secrets secret-service (libsecret bindings)
Serialization serde

Project Structure

src/
├── main.rs              # Entry point
├── app.rs               # Application lifecycle, data fetching, navigation
├── config.rs            # Constants (APP_ID, PDS URL)
├── runtime.rs           # Shared Tokio runtime
├── atproto/
│   ├── client.rs        # HangarClient — AT Protocol wrapper
│   ├── facets.rs        # Rich text facet parsing (mentions, links, hashtags)
│   └── types.rs         # Post, Profile, Session, Notification types
├── cache/
│   ├── db.rs            # SQLite database setup
│   ├── schema.rs        # Table definitions
│   ├── posts.rs         # Post cache operations
│   ├── feeds.rs         # Feed cache operations
│   └── profiles.rs      # Profile cache operations
├── state/
│   ├── oauth.rs         # OAuth flow (PKCE + DPoP, localhost callback)
│   ├── session.rs       # App password session persistence via libsecret
│   ├── session_store.rs # File-based OAuth session store
│   └── settings.rs      # AppSettings + FontSize (persistent JSON)
└── ui/
    ├── window.rs        # Main window, stack navigation, settings page
    ├── sidebar.rs       # Navigation rail with avatar menu
    ├── post_row.rs      # Post widget with embeds and actions
    ├── compose_dialog.rs # Rich compose (posts, replies, quotes, threads)
    ├── login_dialog.rs  # Sign-in dialog
    ├── avatar_cache.rs  # Image loading with LRU + SQLite caching
    └── style.css        # Custom CSS styles

Support Hangar

If you find Hangar useful, consider supporting its development:

GitHub Sponsors Liberapay Buy Me a Coffee Ko-fi PayPal Stripe

Contributing

Hangar is open source under the MPL-2.0 license. Contributions are welcome.

Before contributing:

  • Run cargo fmt (required)
  • Address clippy warnings
  • Follow existing code patterns
  • Keep changes focused—one feature per PR

Resources:

License

Mozilla Public License 2.0

About

Hangar is your Bluesky home base—built natively for Linux. ✈️

Topics

Resources

License

Stars

Watchers

Forks

Contributors