Open-source project
euzu/tuliprox avatar
euzu/tuliprox

tuliprox: a Rust media gateway for IPTV and local libraries

Flexible IPTV playlist processor & proxy in Rust 🦀 - supports M3U, Xtream Codes, HDHomeRun, Plex, Emby & Jellyfin. Filtering, merging, scheduling & web delivery.

583 stars64 forksRustMIT

At a glance

What is it?
tuliprox is a self-hosted Rust service that sits between your media sources and your players, normalising Xtream, M3U, Stalker, Plex, Emby, Jellyfin and local libraries into one catalog and republishing it as M3U, an Xtream API, HDHomeRun or STRM. It stores its state in an embedded engine and needs no external database.
Who is it for?
Adopt tuliprox if you have more than one kind of media source and more than one kind of client, and you want to change providers or players without rebuilding every pairing, because the gateway is what turns an N by M integration problem into a one by one problem.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A gateway in the middle of your media stack

The pitch in the README is an N by M problem stated plainly. Instead of configuring every player against every upstream source, tuliprox sits in the middle. It imports your authorised media sources, normalises and enriches their metadata, filters and reorganises the catalog, manages provider connections, and publishes the result in the formats your clients already understand. The summary line captures the intent, one service, multiple sources, multiple users, multiple output formats, full control. The audience is a self-hosted setup with more than one source or more than one client, which is the ordinary situation for anybody who has moved providers, has both a live subscription and a media server, or wants to serve a family from one catalog. The design consequence is that the interesting work is in normalisation and connection management rather than in playback, because playback stays where it was, with the provider or the media server still doing the actual streaming.

The legal notice is part of the design

The README carries a legal notice, and for an IPTV gateway it is unusually specific, so it is worth reading as a statement of architecture rather than as boilerplate. It says that tuliprox does not provide, host, sell or distribute media content or access credentials, and that users are solely responsible for ensuring they have the necessary rights and authorisation to access, process, proxy, record or redistribute any media source configured with it, and that the software is intended for use with legally obtained and properly authorised content and services. The whole design follows from that. There is no credential store for pirate services, no built-in source catalogue and no content of its own, because the service only handles what you give it. For an evaluator, that matters in two ways. It removes the most obvious reason not to deploy a tool in this category, and it shifts the remaining risk onto you, because the service will happily proxy whatever a provider hands it.

Inputs: eight kinds of upstream, and one overlay concept

The input list is the most detailed part of the README, and it is where the work is. Xtream Codes sources bring live, video on demand, series, catchup and EPG metadata, with provider aliases and CSV batch accounts for bulk configuration. M3U and M3U8 playlists can be remote or local and carry headers, credentials, EPG sources and CSV batch inputs. Stalker and Ministra portals are supported with MAC address, credential or combined authentication, configurable MAG profiles, playback resolution through create_link, resumable refreshes and per-alias configuration. Plex, Emby and Jellyfin libraries can be imported selectively, with protected playback and artwork resolved through the gateway itself. A local media library can be scanned from disk and enriched with NFO or TMDB metadata. And there is a concept worth understanding on its own, staged sources, which overlay a prepared live, video on demand or series catalog while the original provider remains responsible for actual stream delivery, which is a way to present a curated catalog without touching delivery. The README also notes that large provider catalogs can be streamed incrementally rather than buffered in memory before processing starts, which is what makes the disk-based processing path viable on small hardware.

Outputs: four formats, matched to four kinds of client

The output table is the mirror image of the input list, and the choices are informed rather than generic. M3U and M3U8 are for IPTV players such as VLC, TiviMate and iMPlayer. The Xtream Codes API is for clients that expect live, video on demand, series, catchup, EPG, categories and account information, which in practice means the TV apps that ship with that API as their client contract. HDHomeRun is for Plex, Jellyfin and Emby and their tuner-style integrations, using SSDP discovery so the media servers find the gateway the way they would find a network tuner. STRM is for Kodi, Jellyfin and Emby libraries, where the media server records a pointer rather than the file. The point of the design is that a user swaps a provider without changing a player, and a user swaps a player without changing a provider. Between the two tables sit the processing features, with filtering, a mapping DSL, sorting, templates, EPG matching, metadata enrichment and curation, and the streaming layer adds a reverse proxy, redirects, shared MPEG-TS and HLS, an HLS cache and prefetch, catchup proxying and failover.

Embedded storage instead of a database server

The row that explains the deployment story is the storage one, which lists an embedded B+Tree engine, write ahead log protection, memory mapped scans, compression and compaction, with no external database required. The same promise appears in the feature list, that the stack stays small because it is Rust, a single application, embedded storage and no mandatory external database, and in the first feature, that there is no Python, Node.js, Java or mandatory database server. For a self-hosted box that matters more than it would for a cloud deployment, because the difference between one container and a container plus a database plus a migration story is the difference between a Raspberry Pi and a small VPS. The row on operations shows what the service does with that state, with a web UI, a REST API, a scheduler, health and readiness probes, notifications, QoS, stream history and a watchdog. The user-facing side is described as multi-user, with targets, plans, connection limits, priorities, output clusters, category access, network policies and server profiles per user, and the project also has a DVR crate, a messaging crate and a repository crate in the workspace.

Rust, Tokio, and treating the service as infrastructure

The first key feature is about operating the thing for a long time, and the numbers are the project's own. It is a single native application, with low CPU and memory overhead including disk-based playlist processing for memory constrained systems, and it says it can operate with as little as 256 MB of RAM depending on the workload. I/O is asynchronous on Tokio, and it runs on Raspberry Pi, NAS, small VPS instances and x86 or ARM systems. Two operational details are unusually good. There is a dedicated healthcheck endpoint and a ready endpoint, which the README says separate process liveness from actual provider capacity, and that separation is exactly what you want when a provider is down and the process is fine. And there is an optional runtime liveness watchdog that can detect a wedged async runtime and capture diagnostics, optionally triggering a restart when explicitly enabled. Hot configuration reloads reduce the need for service restarts, which matters for a gateway whose job is to survive provider changes without a maintenance window.

The workspace, the lint policy, and a pinned nightly

The repository is a Rust workspace with a lot of crates, and the build files are unusually explicit about how it is put together. The workspace members are the backend crates, the frontend, the shared crate and a test kit, with the resolver set to version 2, the workspace package version at 3.3.156, edition 2021 and a minimum Rust version of 1.95.0. The lint policy is shared across every crate rather than living in one file, with clippy's all and pedantic groups set to warn, wildcard imports denied, and a list of allowances for lints such as module name repetitions, must use candidates, missing errors documentation and large futures. The comment attached to that list explains the reason, that extracted crates must not silently lose the lint level that previously existed only as a crate attribute in the backend's main file. The Makefile does the same for toolchains, resolving rustup, cargo, cross, trunk, wasm-bindgen, cargo-set-version, cargo-machete and mdbook from the path or from the cargo bin directory, pinning a nightly toolchain by name and falling back to whatever nightly is installed if the pinned one is missing, and detecting the CPU count with nproc, getconf or sysctl in turn. There is also a Cross.toml for cross compilation and a book.toml, so the documentation is a book rather than a wiki.

Editorial conclusion

Adopt tuliprox if you have more than one kind of media source and more than one kind of client, and you want to change providers or players without rebuilding every pairing, because the gateway is what turns an N by M integration problem into a one by one problem. It does not fit a setup with a single provider and a single player, where the indirection is pure overhead, and it does not fit anyone who cannot hold the legal position the readme asks for, since the service carries no content and no credentials and the authorisation is entirely yours. Before you deploy it, read the output format table and pick the one your clients speak, and check the toolchain pinning in the Makefile, because the build expects a specific nightly toolchain alongside stable.

Frequently asked questions

What is tuliprox and what does it do?

It is a high performance, self-hosted media gateway in Rust that brings IPTV providers, media servers, playlists, EPG data and local libraries together behind one interface. It imports sources, normalises and enriches metadata, filters and reorganises the catalog, manages provider connections, and publishes the result in the formats clients already understand.

Which upstream sources and output formats does tuliprox support?

Inputs include Xtream Codes, M3U and M3U8, Stalker and Ministra portals, Plex, Emby and Jellyfin libraries, local media scanned from disk, staged catalogs and EPG data. Outputs are M3U and M3U8 for IPTV players, the Xtream Codes API, HDHomeRun with SSDP discovery for tuner style integrations, and STRM for Kodi, Jellyfin and Emby libraries.

Does tuliprox need a database?

No. The storage is an embedded B+Tree engine with write ahead log protection, memory mapped scans, compression and compaction, and the feature list emphasises a single native application with no Python, Node.js, Java or mandatory database server, and the ability to run with as little as 256 MB of RAM depending on the workload.

What does tuliprox do about provider connection limits?

Protecting provider connections is one of the stated reasons for the gateway, with sharing streams, enforcing connection limits, prioritising users, recovering from upstream problems and avoiding waste of provider slots on unnecessary background work. The operational side includes health and readiness probes, a scheduler, durable notifications, stream history, QoS snapshots, quality guards, hot reloads and audit events, and an optional runtime watchdog.

Is tuliprox responsible for the content it proxies?

No. The legal notice states that tuliprox does not provide, host, sell or distribute media content or access credentials, and that users are solely responsible for having the rights and authorisation to access, process, proxy, record or redistribute any source configured with it.

Official sources

  1. euzu/tuliprox on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/euzu-tuliprox.svg)](https://hysenlabs.com/projects/euzu-tuliprox)

Was this useful?