Tootsie - Mastodon Client for Android
Tootsie is a modern, high-performance, and privacy-respecting Mastodon client for Android. Built from the ground up with Jetpack Compose and Kotlin, it follows Clean Architecture principles to provide a smooth experience for the Fediverse.
🧪 Testers wanted
Google requires a closed test with at least 12 testers for 14 days before Tootsie can be published on Google Play. You can help:
- Join the Google group tootsie-testing (with the Google account of your Play Store)
- Opt in as a tester: https://play.google.com/apps/testing/com.pfitzer.tootsie
- Install Tootsie from the Play Store and keep it installed for at least 14 days
Bugs and ideas are welcome as issues. Without the Play Store, install the APK from the latest release.
📱 Screenshots
🚀 Features
- Multi-Account Support: Seamlessly switch between multiple Mastodon accounts without app reloads.
- Modern UI: Fully built with Jetpack Compose and Material Design 3, with adjustable text size.
- Offline-First Timelines: Home, local and federated timelines are loaded into a Room database (Paging
RemoteMediator) and stay fully scrollable without a network connection.
- Privacy First:
- UnifiedPush notifications, no Firebase/FCM required. Payloads are decrypted on the device (RFC 8291 Web Push encryption); a WorkManager polling fallback covers all accounts when no distributor is available.
- Access tokens are encrypted at rest with a non-exportable Android Keystore key (AES-GCM), in DataStore and in the Room database.
- Posts & Threads:
- Favourite, boost, bookmark and reply; the state updates immediately in every list.
- Edit own posts (text, content warning, media and alt texts, poll), see the edit history of edited posts, delete or delete & redraft.
- See who favourited and boosted a post.
- Translate posts in other languages through the server's translation service, or hand them to a translator app.
- Quote posts: boost or quote a post, with the author's quote policy respected (Mastodon 4.5+).
- Content warnings hide text, media and polls until expanded; sensitive media is blurred.
- Threads automatically load missing replies from other servers (Mastodon 4.5+).
- Polls (view, vote, create), custom emoji picker, draft auto-save and management (media, poll and language included); mark media as sensitive.
- Rich Media: Images, videos and audio (ExoPlayer); uncached remote media is loaded through the instance's media proxy.
- Filters:
- Timeline filters (hide boosts, replies, or show only media).
- Keyword filters to hide or warn about posts, matched against the visible text of a post.
- Organization: Lists (create, edit, manage members), followed hashtags, bookmarks, favourites, drafts.
- Discovery: Search for accounts, posts and hashtags; trending hashtags, posts and links; announcements.
- Profiles: Followers and following lists, notifications for new posts of an account, private notes, the server of remote accounts.
- Account Management: Profile editing, follow requests, muted and blocked accounts, blocked domains.
- Scheduled Posts: Pick a publication time when composing; reschedule, edit or delete scheduled posts.
- Reading position: The home timeline position and read notifications are synced with Mastodon's markers, shared with the web interface and other apps.
- Accessible: TalkBack actions on every post, counts read with their buttons, alt texts and fallbacks for media.
- Internationalized: English and German.
Some features depend on the server version: quote posts and fetching remote replies need Mastodon 4.5 or newer, decrypting push notifications needs Mastodon 4.4 or newer. On older servers Tootsie falls back to the previous behaviour (e.g. the boost button boosts directly).
🛠 Tech Stack
- Language: Kotlin 2.4
- Build: Gradle 9.7, Android Gradle Plugin 9.4, version catalog (
gradle/libs.versions.toml)
- UI Framework: Jetpack Compose with Material Design 3
- Architecture: Clean Architecture (Presentation, Domain, Data) + MVVM + MVI
- Dependency Injection: Hilt
- Local Database: Room with exported schemas and migration tests
- Preferences: DataStore
- Networking: Retrofit + OkHttp
- Serialization: Kotlinx Serialization
- Push Notifications: UnifiedPush
- Image Loading: Coil
- Paging: Paging 3
- Background Tasks: WorkManager
- Testing: JUnit, MockK, kotlinx-coroutines-test, Compose UI tests, Room
MigrationTestHelper
📋 Requirements
- A recent Android Studio that supports Android Gradle Plugin 9.4
- JDK 21 to run Gradle (the app itself compiles to Java 11 bytecode)
- Android SDK 37
- Android device/emulator running Android 12 (API 31) or higher
This is the beginning of the README. Read the rest at the original. Read the full README ↗