Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rustyfin 🦀

Rust Edition Axum Tokio SQLx Jellyfin License Build

A lightweight, Jellyfin-compatible media server written in Rust.
Implements the Jellyfin REST API — use any Jellyfin client (Web, Android, iOS, TV, Roku, Kodi) to browse and stream your library.


🎯 Why Rustyfin?

Aspect Jellyfin (C#/.NET) Rustyfin (Rust)
Memory (idle) ~200–400 MB ~15–30 MB
Startup ~5–15 s < 500 ms
Binary size ~100 MB (self-contained) ~8–12 MB (static)
Architecture Monolith 7-crate Workspace
Concurrency ThreadPool Tokio async (io_uring/epoll/kqueue)
Deployment Docker, bare metal Single static binary + Docker

✅ Implemented (v0.1)

  • Jellyfin-compatible REST API — Works with official Jellyfin clients
  • User Auth — JWT tokens, API keys, Quick Connect, Argon2 password hashing
  • Library Management — Create/scan/delete libraries (Movies, Series, Music, Photos, Books)
  • Media Browsing — Items, filtering, sorting, pagination, resume points
  • Metadata Providers — TMDb, OMDb, local NFO files
  • Image Proxy — Caching, on-the-fly resize, format conversion
  • Direct Play / Direct Stream — Range requests, seeking, HLS/DASH passthrough
  • SQLite Database — Zero-config, embedded, SQLx compile-time checked queries

🚧 Roadmap

  • HLS Transcoding (FFmpeg integration)
  • Playback tracking (watched, resume, favorites)
  • Subtitle support (SRT, ASS, VTT, OpenSubtitles)
  • Session & Device management
  • Full-text & Fuzzy Search
  • Collections & Playlists
  • Scheduled Tasks (auto-scan, cache cleanup)
  • Plugin System
  • Full Jellyfin Client Compatibility (Web, Android, iOS, TV apps)
  • Official Docker Image (ghcr.io/peopleandpixel/rustyfin)

🏗 Architecture: Cargo Workspace (7 Crates)

rustyfin/
├── crates/
│   ├── rustyfin-server   # Entry point, config, server bootstrap
│   ├── rustyfin-api      # Axum routes, handlers, OpenAPI docs
│   ├── rustyfin-auth     # Argon2, JWT, API keys, Quick Connect
│   ├── rustyfin-core     # Business logic: scanning, metadata, images
│   ├── rustyfin-db       # SQLx + SQLite, migrations, repositories
│   ├── rustyfin-model    # Shared DTOs, entities, Jellyfin API types
│   └── rustyfin-cli      # CLI utilities (migrate, admin, benchmark)
├── docker/
│   ├── Dockerfile
│   └── docker-compose.yml
├── .github/workflows/ci.yml
└── Cargo.toml (workspace)

🚀 Quick Start

Prerequisites

  • Rust 1.85+ (2024 Edition) — rustup update stable
  • SQLite3 dev headers (bundled via sqlx)

Build & Run

git clone https://github.com/peopleandpixel/rustyfin.git
cd rustyfin

# Build release (optimized, static binary ~10 MB)
cargo build --release --workspace

# Run
./target/release/rustyfin

Default: http://0.0.0.0:8096 · Data dir: ~/.rustyfin/
First run: Creates admin / adminchange immediately!

Configuration (Environment Variables)

Variable Description Default
RUSTYFIN_BIND Bind address:port 0.0.0.0:8096
RUSTYFIN_DATA Data directory (DB, cache, config, logs) ~/.rustyfin
RUSTYFIN_DB SQLite connection string sqlite://<data>/rustyfin.db?mode=rwc
RUSTYFIN_SECRET JWT signing secret Random UUID (regenerated each start!)
RUSTYFIN_SERVER_ID Unique server identifier Random UUID
RUSTYFIN_API_KEY Static API key for integrations Disabled
RUST_LOG Log level (debug, info, rustyfin=trace) info

Example (production):

RUSTYFIN_BIND=127.0.0.1:8096 \
RUSTYFIN_DATA=/srv/rustyfin \
RUSTYFIN_SECRET="$(openssl rand -base64 32)" \
RUSTYFIN_API_KEY="my-integration-key" \
./target/release/rustyfin

Docker

docker build -t rustyfin .
docker run -d \
  -p 8096:8096 \
  -v /path/to/media:/media:ro \
  -v /path/to/data:/data \
  -e RUSTYFIN_DATA=/data \
  -e RUSTYFIN_SECRET="$(openssl rand -base64 32)" \
  rustyfin

🔧 Development

# Live reload
cargo install cargo-watch
cargo watch -x "run --release"

# Run all tests
cargo test --workspace

# Format & lint (CI checks these)
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings

# Generate SQLx query cache (for offline builds)
cargo sqlx prepare --workspace

# Build docs
cargo doc --workspace --no-deps --open

🧪 Testing with Jellyfin Clients

Client Status Notes
Jellyfin Web ✅ Works Full browsing, playback
Jellyfin Android ✅ Works Direct play/stream
Jellyfin iOS/tvOS ✅ Works Direct play/stream
Jellyfin Roku ⚠️ Partial Some endpoints missing
Jellyfin Kodi Addon ⚠️ Partial Auth works, browsing WIP
Infuse (iOS) ✅ Works Via Jellyfin API
Swiftfin ✅ Works Native Jellyfin client

📊 Performance

Metric Value
Idle RAM ~18 MB
Streaming 1080p (direct) ~25 MB
Cold start → ready < 300 ms
Library scan (10k items) ~8 s (parallel)
Binary size (stripped) 9.2 MB

🤝 Contributing

  1. Fork → Feature branch (git checkout -b feat/amazing-feature)
  2. Commit (git commit -m 'feat: add amazing feature')
  3. Push → Open PR
  4. CI must pass: fmt, clippy, test, build

📜 License

MIT License — see LICENSE for details.


🙏 Acknowledgments

  • Jellyfin — The free software media system we're compatible with
  • Axum — Ergonomic web framework
  • SQLx — Compile-time checked SQL
  • Tokio — Async runtime
  • TMDb / OMDb — Metadata APIs

👤 Author

Jens Reinemuth — Senior Full-Stack Dev (Rust, Flutter, PHP/Symfony, DevOps, AI)
🇪🇺 EU Citizen · 🇵🇹 Portugal · 📧 jens@reinemuth.pt · GitHub · LinkedIn
💼 Open to remote roles in Germany/EU · 25+ years experience

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages