Build EPUB, PDF, audiobook, comic, and WebPub readers in Flutter with one unified Dart API—powered by Readium toolkits on iOS, Android, and Web.
Get started · Example app · API docs
Select an iOS Simulator capture to see it full size.
| EPUB themes | Read-along | Narrated comics |
|---|---|---|
![]() |
![]() |
![]() |
| EPUB highlights | PDF pages |
|---|---|
![]() |
![]() |
Add the package:
flutter pub add flutter_readiumSee the complete reader screen for opening a local file or URL, mounting the reader, and closing the publication. The five-minute walkthrough continues with navigation, preferences, and position restoration.
flutter_readium is a federated plugin that delegates to the upstream Readium toolkit on each platform:
- swift-toolkit 3.11.0 on iOS
- kotlin-toolkit 3.3.0 on Android
- ts-toolkit (
@readium/shared,@readium/navigator) on Web
The canonical version pins live in flutter_readium/ios/flutter_readium.podspec, flutter_readium/android/build.gradle (ext.readium_version), and flutter_readium/package.json. Run bin/readium_versions to print them at any time.
| Format | Visual | TTS | Audio | Media Overlays |
|---|---|---|---|---|
| EPUB 2 | ✓ | ✓ | — | - |
| EPUB 3 | ✓ | ✓ | ✓ | - |
| WebPub | ✓ | ✓ | ✓ | ✓ (EPUB profile) |
| Audiobook | — | — | ✓ | - |
| ✓ | — | — | - | |
| CBZ | ✓ | — | — | - |
| DiViNa | ✓ | — | ✓¹ | ✓¹ (Guided Navigation) |
¹ DiViNa audio narration is driven by a Guided Navigation document and synchronizes at the page
level on all platforms (on Web, ts-toolkit has no DiViNa navigator, so images are rendered by a
plugin-side navigator). Panel-level zoom (the segments' xywh regions) is not yet implemented on
any platform.
LCP-protected publications are not currently supported. The underlying toolkits include an LCP adapter; it may be enabled in a future release.
| Feature | Android | iOS | Web |
|---|---|---|---|
| EPUB visual reading | ✓ | ✓ | ✓ |
| Comics (CBZ / DiViNa) | ✓ | ✓ | ✓ |
| PDF reading | ✓ | ✓ | — |
| Audiobook playback | ✓ | ✓ | ✓ |
| Media Overlays | ✓ | ✓ | ✓ |
| Text-to-Speech | ✓ | ✓ | Limited¹ |
| Highlights / decorations | ✓ | ✓ | ✓ |
| Reader preferences | ✓ | ✓ | ✓ |
| PDF preferences | ✓ | ✓ | — |
| Progress saving | ✓ | ✓ | ✓ |
| Content search | ✓ | ✓ | — |
| Background audio | ✓ | ✓ | — |
¹ Web TTS uses the browser's Web Speech API — voice availability and quality vary by browser.
macOS note: Native macOS desktop (
flutter run -d macos) is not supported — a no-op stub is registered so the Flutter macOS target still compiles, but every reader call returnsMethodNotImplemented. The upstreamswift-toolkitis iOS-only and has marked native macOSnot_planned. The iOS build runs fine on Apple Silicon Macs via "Designed for iPad".
| Requirement | Version |
|---|---|
| Flutter | 3.44.8+ |
| Dart SDK | 3.8.0+ |
| Android | minSdkVersion 24 |
| iOS | 15.0+ |
The development SDK is pinned separately in .flutter-version; contributors should use
bin/update_flutter_version to change that pin.
Complete the per-platform setup below before running the reader. See the full installation guide for details.
-
Set
minSdkVersionto 24 or higher inandroid/app/build.gradle. -
Enable core library desugaring — the readium-kotlin-toolkit artifacts require it, and the build fails at
checkDebugAarMetadatawithout it:android { compileOptions { isCoreLibraryDesugaringEnabled = true } } dependencies { coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5") } -
Change your
MainActivityto extendFlutterFragmentActivity(notFlutterActivity) — otherwise the reader view will crash at runtime. -
If using TTS or background audio, add to
android/app/src/main/AndroidManifest.xml:<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
The Android plugin exposes the following Gradle properties. Set them in your
app's android/gradle.properties to override the defaults at build time:
| Property | Default | Description |
|---|---|---|
flutterReadium.mediaOverlayFetchConcurrency |
8 |
Max number of media-overlay JSON files the Sync Audiobook navigator fetches in parallel. Higher values speed up opening publications with many overlays at the cost of more concurrent HTTP requests. |
Example android/gradle.properties:
flutterReadium.mediaOverlayFetchConcurrency=16Add the Readium pods to your ios/Podfile.
To avoid documentation drift, copy the exact Readium pod lines from:
flutter_readium/example/ios/Podfile(source-of-truth for app integration)- and keep them aligned with
flutter_readium/ios/flutter_readium.podspec(plugin-side pin)
Example shape:
target 'Runner' do
use_frameworks!
use_modular_headers!
# Readium pod lines: copy from flutter_readium/example/ios/Podfile
# ...
end-
Copy the plugin's JavaScript bundle into your web app:
dart run flutter_readium:copy_js_file <destination_directory>
The destination should live inside your
web/directory. -
Reference the script from
web/index.html:<script src="flutter.js" defer></script> <script src="readiumReader.js" defer></script>
Full documentation is in docs/:
- Getting Started
- Guides
- API Reference
- Architecture — Overview
- Troubleshooting — Troubleshooting
A complete example app is available in flutter_readium/example/, demonstrating EPUB and audiobook reading, TTS, preferences, and highlighting:
cd flutter_readium/example && flutter runThe README animation and capability screenshots are driven by a small integration-test-style showcase recorded from a booted iOS Simulator. Once the generated test fixtures are installed, regenerate them with:
bin/generate_readme_demo [--no-bezel] [--device-id <simulator-udid>]The physical device bezel is included by default. The script keeps the H.264 master under
build/readme-demo/ and replaces the checked-in media only after the capture and size checks pass.
- helper scripts:
cd flutter_readium/assets/_helper_scripts && npm run build:stats(outputsflutter_readium/assets/helpers/stats.htmlandflutter_readium/assets/helpers/stats.json) - web bundle:
cd flutter_readium && npm run build:stats(outputsflutter_readium/build/rollup-stats.htmlandflutter_readium/build/rollup-stats.json)
See CONTRIBUTING.md for development setup, build scripts, and contribution guidelines.
BSD 3-Clause — see LICENSE.





