Skip to content
MEHDImp4Public

About

Offline-ready Android client for Jellyfin, built with Expo, React Native, and TypeScript.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Latest commit

Β 

History

364 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

FINORA β€” Watch your way

FINORA Logo

A premium, cinematic Jellyfin client built with Expo & React Native β€” fast, private, offline-ready, and designed for a modern streaming experience.
Built with Expo SDK 57, React Native 0.86 (New Architecture & Hermes), and TypeScript.

πŸ‡¬πŸ‡§ English β€’ πŸ‡«πŸ‡· FranΓ§ais

APK Releases CI Status License: GPL-3.0 Expo SDK 57 React Native 0.86 TypeScript Strict Jellyfin Compatible

πŸ“₯ Browse APK Releases β€’ πŸš€ Quickstart β€’ 🀝 Contributing β€’ πŸ’¬ Discussions β€’ πŸ›‘οΈ Security


πŸ“– Table of Contents


🌟 Overview

FINORA is an open-source personal media client focused on delivering a modern, cinematic mobile streaming experience for Jellyfin.

Built with Expo SDK 57, React Native 0.86, and TypeScript, it combines native hardware-accelerated playback, resilient background downloads, responsive navigation, and privacy-focused credential storage in a polished mobile interface.

The Core Experience:

Open FINORA β†’ Browse instantly β†’ Choose content β†’ Play β†’ Watch smoothly β†’ Resume anywhere.

  • Smooth Navigation: Optimized for high-refresh-rate displays (up to 120 Hz) using React Native's New Architecture (Fabric renderer and Hermes engine).
  • Cinematic Dark Theme: Refined OLED dark theme, Netflix-style navigation, subtle elevation, and responsive cards.
  • Native Video Engine: Built on modern expo-video (AndroidX Media3 / ExoPlayer on Android and AVPlayer on iOS) with automated stream negotiation.
  • Privacy by Default: Authentication tokens stored in hardware-backed keystores where supported by the platform, passwords discarded immediately after authentication, and zero third-party telemetry.

πŸ“± FINORA in Action

🏠 Home 🎬 Details ▢️ Player πŸ” Search πŸ“₯ Downloads
Hero banners, continue watching & library carousels Rich metadata, season picker & episode grids Low-overhead playback, gestures & skip markers Instant multi-library search with live filters Background download manager with auto-resume

✨ Highlights

  • 🎬 Native Jellyfin Playback β€” Low-overhead hardware decoding via AndroidX Media3 (ExoPlayer) & AVPlayer.
  • πŸ“₯ Resilient Offline Downloads β€” Background media caching with HTTP Range resume after network drops or app restarts.
  • πŸ” Secure Credential Storage β€” Access tokens use expo-secure-store where available; passwords are never persisted and local references are discarded immediately after authentication.
  • πŸ”Ž Fast Library Search β€” Instant multi-library search with live suggestions and per-user history isolation.
  • 🎞️ Intro & Credits Skipping β€” Dynamic skip markers based on Jellyfin chapter metadata.
  • πŸ”Š Multi-Audio & Subtitles β€” Flexible track selection with custom subtitle overlay (SRT, WebVTT, ASS styling).
  • πŸ“± Modern Responsive UI β€” Fluid dark interface optimized for portrait, landscape, and foldable form factors.
  • 🚫 Strict Privacy β€” No advertisements, third-party analytics, or telemetry.

πŸ“₯ Download & Installation

Android (Direct APK)

Browse APK Releases

Standalone APKs are built automatically on every release:

Build Channel Recommended For Link
Release Candidates / Previews Testers validating the upcoming stable release Browse APK Releases
Stable Use only after a stable vX.Y.Z release is published Browse All Releases

How to install on Android:

  1. Download the .apk file directly on your Android phone from the GitHub Releases page.
  2. Tap the downloaded file in your browser notifications or file manager.
  3. If prompted, allow your browser or file manager to "Install unknown apps".
  4. Tap Install and launch FINORA.

iOS

Due to platform restrictions on third-party streaming clients, running FINORA on iOS requires compiling from source:

  1. Clone the repository on a macOS machine with Xcode installed.
  2. Run npx expo run:ios to compile and deploy to a connected iPhone or iOS simulator.

🎬 Detailed Features

1. Modern Playback Engine (FinoraPlayerEngine)

  • AndroidX Media3 & AVPlayer: Native video decoding with hardware acceleration and low memory footprint.
  • Stream Negotiation: Automated decision pipeline (PlaybackPlanner) prioritizing Direct Play > Direct Stream > Transcoding based on device profile.
  • Intuitive Gesture Controls:
    • Vertical swipe on the left edge for brightness control.
    • Vertical swipe on the right edge for volume adjustment.
    • Double-tap on the left/right edges for instant 10-second seek.
  • Intro & Credits Skipping: Automatic skip marker detection for Jellyfin intros, recaps, and credits chapters.
  • Subtitles & Multi-Audio: Support for SubRip (SRT), WebVTT, picture-based subtitles (PGS), and Advanced SubStation Alpha (ASS) styling via a dedicated subtitle overlay.
  • Watch State Synchronization: Real-time playback progress reporting and resume points synced directly with your Jellyfin server.

2. Interface Design & Navigation

  • Hero Backdrop Banners: Dynamic backdrops, high-resolution logos, and auto-computed watch progress bars.
  • Optimized Media Caching: Powered by expo-image with multi-tier memory and disk caching, progressive JPEG/WebP decoding, and Blurhash placeholders.
  • Responsive Layout: Fluid grids and carousels adapting seamlessly between portrait, landscape, and foldable form factors.

3. Offline Download Subsystem

  • Background Downloads: Uses Android foreground services (react-native-background-actions) to download large media files while the app is suspended.
  • Auto-Resume & Range Requests: Automatically resumes interrupted downloads after network drops or app restarts without restarting from byte zero.
  • Isolated Sandboxing: Offline media files and metadata are stored in private app sandbox storage (expo-file-system) and indexed locally per server and per user.

4. Library Discovery & Instant Search

  • Live Search: Rapid search with real-time suggestions, recent search history, and multi-library results.
  • Multi-Server & User Isolation: Search histories, download indexes, and view preferences are fully isolated per server and per user.
  • Rich Metadata Display: Detailed cast lists, community ratings, studio badges, and media resolution tags (4K, HDR, 1080p, 5.1 Surround).

5. Zero-Trust Security Architecture

  • Platform Secure Storage: Authentication tokens are stored through expo-secure-store; hardware-backed properties depend on the device and operating system.
  • Credential Lifetime: Passwords are never persisted and FINORA discards its local password reference immediately after authentication completes.
  • Sanitized Logging: All network logs and debugging outputs automatically redact authorization headers, passwords, and tokens ([REDACTED]).
  • Zero Third-Party Trackers: No analytics, telemetry, or third-party ads.

6. Background Notifications

  • Periodic background fetch (expo-background-task) checks for newly released movies, seasons, and episodes on your Jellyfin server.

πŸ› οΈ Tech Stack

Layer Technologies Purpose
Framework Expo SDK 57 Managed native build plugins, modern runtime modules
Runtime React Native 0.86+ + React 19 Native UI components, modern concurrent rendering
Architecture New Architecture (Fabric + Bridgeless) Direct native synchronous invocation via JSI, removing legacy bridge overhead
JS Engine Hermes Fast startup time and lightweight memory footprint via bytecode precompilation
Routing Expo Router v4 Typed file-based routing with native transitions
Player expo-video AndroidX Media3 / ExoPlayer on Android & AVPlayer on iOS
Images expo-image Native disk/memory caching with blurhash support
State TanStack Query v5 + Zustand Server state caching & lightweight atomic UI stores
Security expo-secure-store Platform secure storage for Jellyfin access tokens; hardware-backed properties depend on device/OS
SDK @jellyfin/sdk Official typed Jellyfin API client
Language TypeScript Strict mode type-safety across the entire codebase

πŸ—οΈ Project Architecture

FINORA enforces a strict separation of concerns to keep business logic maintainable, testable, and isolated:

FINORA Architecture
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Expo Router Pages                    β”‚  (src/app/)
β”‚     Screen Presentation & Reanimated Transitions       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Custom Hooks                        β”‚  (src/features/*/hooks/)
β”‚        UI Lifecycle, Gesture Arbitrators, Queries      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Domain & State Layer (TanStack/Zustand)   β”‚  (src/stores/, src/features/)
β”‚      PlaybackPlanner, DownloadManager, OfflineEngine   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Repository Layer                     β”‚  (src/core/repositories/)
β”‚     AuthRepo, MediaRepo, PlaybackRepo, SessionRepo     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          Native Modules & Jellyfin Engine              β”‚  (expo-video, SecureStore, SDK)
β”‚       AndroidX Media3, Keystore, @jellyfin/sdk         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Directory Structure

FINORA/
β”œβ”€β”€ assets/               # Branding assets, logos, and icons
β”œβ”€β”€ docs/                 # Documentation & release checklists
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app/              # Expo Router typed file-based navigation
β”‚   β”‚   β”œβ”€β”€ (tabs)/       # Main tab navigation (Home, Search, Downloads, Settings)
β”‚   β”‚   β”œβ”€β”€ details/      # Media and series details view
β”‚   β”‚   └── player/       # Fullscreen video player route
β”‚   β”œβ”€β”€ core/             # Foundational infrastructure
β”‚   β”‚   β”œβ”€β”€ jellyfin/     # Auth repository, SDK clients, and restore logic
β”‚   β”‚   β”œβ”€β”€ network/      # Sanitized HTTP client, logger, and network status
β”‚   β”‚   β”œβ”€β”€ repositories/ # Media, playback, user, and user-data repositories
β”‚   β”‚   β”œβ”€β”€ security/     # Keystore encryption, sanitization, and token storage
β”‚   β”‚   └── storage/      # Secure store & preferences handlers
β”‚   β”œβ”€β”€ features/         # Feature modules
β”‚   β”‚   β”œβ”€β”€ details/      # Media details, season picker, episode cards
β”‚   β”‚   β”œβ”€β”€ home/         # Hero banner, media carousels, resume watching
β”‚   β”‚   β”œβ”€β”€ library/      # Responsive media grid, filters, sorting
β”‚   β”‚   β”œβ”€β”€ notifications/# Background notifications for new server content
β”‚   β”‚   β”œβ”€β”€ offline/      # DownloadManager, background worker, resume logic
β”‚   β”‚   β”œβ”€β”€ onboarding/   # Server discovery and authentication
β”‚   β”‚   β”œβ”€β”€ player/       # FinoraPlayerEngine, controls, gestures, subtitles
β”‚   β”‚   β”œβ”€β”€ search/       # Live search, history, suggestions
β”‚   β”‚   └── settings/     # Server diagnostics, playback & subtitle preferences
β”‚   β”œβ”€β”€ stores/           # Atomic Zustand stores (player, settings, downloads)
β”‚   └── components/       # Design system components, FinoraCard, modals
β”œβ”€β”€ .github/              # Issue templates, PR template, CI workflows
└── package.json

πŸš€ Getting Started

⚠️ FINORA requires an Expo development build β€” it cannot run in Expo Go.
Native modules used by FINORA (expo-video, expo-secure-store, expo-background-task, etc.) require native code compilation.

Prerequisites

Local Setup

  1. Clone the repository:

    git clone https://github.com/MEHDImp4/FINORA.git
    cd FINORA
  2. Install dependencies:

    npm install
  3. Run on Android (generates native project and launches dev build):

    npx expo run:android
  4. Run on iOS (macOS required):

    npx expo run:ios
  5. Start the Metro development server:

    npx expo start --dev-client

Handy npm Scripts

Command Action
npm start Start Metro development bundler
npm test Run the complete automated Jest test suite
npm run typecheck Run TypeScript compiler in strict mode without emitting files
npm run android Compile and launch native Android development build
npm run ios Compile and launch native iOS development build

πŸ§ͺ Automated Testing & CI

FINORA maintains an automated test suite covering repository caching, playback planning, download recovery, and state managers:

# Run unit & integration tests
npm test

# Run TypeScript strict validation
npm run typecheck

Continuous Integration runs on every push and pull request to master via GitHub Actions:

  • TypeScript Strict Validation
  • Jest Unit & Integration Test Execution
  • Version and i18n consistency checks
  • Production Dependency Security Audit (npm audit --omit=dev --audit-level=high)
  • Expo Doctor (advisory)
  • Automated Standalone APK Packaging via GitHub Actions (build-apk.yml)

πŸ›‘οΈ Security & Privacy

  • Credential Handling: Passwords are never persisted; local references are discarded immediately after authentication and sensitive values are redacted from logs.
  • Hardware-Encrypted Keystore: Access tokens are stored in hardware-backed storage (expo-secure-store) where available on device.
  • Sanitized Logging: All network logs and debugging outputs automatically redact authentication headers, tokens, and query credentials ([REDACTED]).
  • No Third-Party Trackers: Zero telemetry, zero analytics, zero external user tracking.
  • Responsible Disclosure: Please see our Security Policy to report vulnerabilities privately.

🀝 Contributing

We welcome contributions of all kinds from the community!


πŸ’¬ Community & Support

  • GitHub Discussions: Share setup tips, show off your server configuration, or discuss feature ideas in Discussions.
  • Issue Tracker: Track ongoing fixes and feature developments in Issues.
  • Feature Requests: Propose enhancements and discuss ideas via Feature Requests.
  • Releases: Download standalone builds and review changelogs in Releases.

πŸ“„ License & Acknowledgements

FINORA is free software, licensed under the GNU General Public License v3.0 (GPL-3.0). See LICENSE for details.

Acknowledgements & Credits

  • The awesome Jellyfin project and community for creating the open-source media system.
  • The Expo and React Native teams for the modern mobile development platform.

About

Offline-ready Android client for Jellyfin, built with Expo, React Native, and TypeScript.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages