Self-hosted service
madeofpendletonwool/PinePods avatar
madeofpendletonwool/PinePods

PinePods: one self-hosted podcast server for the whole household

Pinepods is a complete podcast management system that allows you to play, download, and keep track of podcasts you enjoy. All self hosted and enjoyed on your own server!

1,027 stars77 forksRustGPL-3.0

At a glance

What is it?
PinePods is a self-hosted podcast management system written in Rust, where one server holds the subscriptions, history, queue and downloads for an entire household and every device syncs against it. Its differentiator is the built-in gpodder compatible sync server, which means existing clients such as AntennaPod can keep working, and its cost is a multi part stack with a Python backend, a Rust API and a Yew web client.
Who is it for?
Adopt PinePods if your household listens to podcasts on several platforms and you want one server that owns the subscriptions, the history, the queue and the downloads, and if you are willing to run and update it yourself. Do not adopt it for a single person with one device, where a standalone client does the same job without a server, and do not adopt it if you need an installation-free setup.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository received new commits within the last day.
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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One server owns the subscriptions and the history

PinePods describes itself as a complete, self-hosted podcast management system written in Rust, with the tagline of a forest of podcasts, rooted in the spirit of self-hosting.

The model is stated plainly. You run one server, your whole household connects to it, and your subscriptions, history, queue, downloads and settings follow you from device to device, because everything lives in your own database. The README is explicit that it is self-hosted and open source, that your podcasts and listening data stay on your hardware in Postgres or MySQL and MariaDB, and that it is multi-user, where one instance serves your whole family, each with their own library, stats and settings.

That last point is the one that distinguishes it from a personal podcast app. A personal app keeps your subscriptions on your phone. A server keeps them in a database, which is the only arrangement that survives a phone replacement and the only one that lets two people in the same house have different libraries from the same server.

The client surface is broad. Native apps everywhere is listed for web, Linux, Windows, macOS, Android and iOS, plus a CLI client, and the README adds that you can listen in the browser, on the desktop, on your phone, in the car, or even from the terminal. The 0.9.0 release from 2026-06-26 is titled with Video, CarPlay, Android Auto, and a Whole New Look, which is the current work: video podcasts, the two automotive integrations and a visual redesign.

The project is GPL-3.0 licensed, the last push was on 2026-10-17, and the site is pinepods.online with a documentation site for the full story and deep configuration.

The built-in gpodder server is the interoperability decision

The feature that makes PinePods different from a self-hosted player is the bring your own apps line in the README: a built-in gpodder-compatible sync server lets you keep using AntennaPod and friends alongside PinePods.

That is a real architectural choice, and it is worth understanding what it means. The gpodder protocol is a synchronisation API that podcast clients use to exchange subscription lists and playback state. By implementing it, PinePods does not require you to abandon your existing client. You point AntennaPod at your PinePods server as its sync backend, and your subscriptions live in your database while the app you already know does the playing.

The repository reflects that, with a dedicated gpodder-api/ directory alongside the main application. It also comes with OIDC and SSO, MFA and TOTP, so the server is not a shared machine with an open door, and there is a Firewood CLI for the terminal.

The gpodder route and the native app route are two different answers to the same question. If the household is happy with the built-in apps, everything is in one place and the integration work is done for you. If somebody insists on their existing client, the gpodder server means they can, without the server having to implement every client protocol in existence. The README treats this as a feature of the platform rather than a compatibility afterthought, and the gpodder-api/ directory in the tree says the same thing.

A Rust core with a Yew web client and a Python backend

The repository layout shows that this is a multi part project rather than a single binary, and the directory names are the clearest description of the architecture.

There is a web/ directory, and the topic list includes yew, the Rust web framework, so the browser client is a Rust WebAssembly application. There is a rust-api/ directory, so there is a Rust service layer as well. There is a Backend/ directory, and the topic list includes fastapi and python, and the root requirements.txt is the Python dependency list. There is a mobile/ directory for the phone apps, a clients/ directory, and a pinepods-ai/ directory.

The Python requirements are short and reveal what the backend is doing:

text
mariadb
python-dateutil
python-dateutil
passlib
itsdangerous
keyring
cryptography
python-multipart
fernet
asyncio
pytz
psycopg[binary]
mygpoclient
appdirs
argon2_cffi
httpx
psycopg[pool]

Two entries in that list are worth pausing on. passlib with argon2_cffi is the password hashing stack, keyring and cryptography and fernet handle secrets and encryption, and itsdangerous is the signing library that goes with session cookies, which matches the multi-user requirement. mygpoclient is the Gpodder client, which is the sync server talking to the protocol, and httpx is the HTTP client the service uses to fetch feeds. psycopg appears twice, once plain and once with the pool extra, and mariadb covers the other database.

One thing to notice is that the file is hand maintained. python-dateutil is listed twice and asyncio is listed even though it is part of the standard library, which is a small sign that this dependency list is edited by hand rather than generated, and worth a glance before you rely on it.

Discovery across three catalogues plus your own library

The Discover row of the feature table is about finding things, and it splits into two halves that are worth separating.

The first half is external search. You can search across Podcast Index, iTunes and YouTube, and you can follow podcast hosts via PodPeople DB, and you can generate shareable episode links. Three catalogues rather than one is a practical decision, since a show can be missing from any of them, and the YouTube entry matters for the video podcasts that the 0.9.0 release added support for.

The second half is search inside what you already have, that is, search inside your own library for episodes. For a household with a few hundred subscriptions and a long history, finding an episode you half remember is a different problem from finding a new show, and treating it as a separate feature is the right call.

The Organize row covers the rest of the library surface: subscriptions, smart playlists and manual playlists, saved episodes, favorites with favorite categories, full history, and local file-system podcasts for the shows you have already downloaded and want the server to treat as part of the library.

The Listen row is where the playback features live: audio and video podcasts, variable speed, chapters, transcripts, downloads, a persistent queue panel, serial auto-play and per-podcast auto-download. Two of those deserve comment. Serial auto-play means one episode after another, which is the behaviour most people want from a podcast queue and which most apps implement awkwardly. And per-podcast auto-download means the download policy is per show rather than global, which is the setting people actually want when they follow one daily news show and twenty weekly ones.

Distribution across desktop, mobile and app stores

PinePods is distributed through every channel an application like this normally uses, and the badges at the top of the README list them all.

Flathub for Linux, the App Store for iOS, Google Play for Android, IzzyOnDroid, and Obtainium for people who want to track releases from the source repository directly. There is also a Docker container build workflow in the repository's actions, and the root has a dockerfile, a dockerfile-arm, a .dockerignore and a deployment/ directory, so a server install is a container story rather than a source build.

The validation images are a detail that shows care. Alongside the main dockerfile there are Dockerfile.validator and Dockerfile.validator.postgres, and a validate_db.py script at the root, which together suggest a way to check that a database schema is valid against a given database engine before the application is pointed at it. There are also run-tests.sh and setup-tests.sh scripts and a tests/ directory, so the project has a test story for a stack this size.

The community channels are a Discord server and a Matrix room, and the topic list includes hacktoberfest, which is a reasonable way to read the shape of the contributor base. The chat presence matters for a self-hosted project, because the people who run it are the people who support it.

Where PinePods is the wrong tool

The limits are mostly about scope of commitment, and the project is honest about how much it asks of the person running it.

The first is that it is a server with a database, a Rust core, a Python backend, a Rust API, a web client and mobile clients. Any of those can be a thing that needs updating, and an update to the server can require a client update, which is why the 0.9.0 release title mentions CarPlay and Android Auto alongside the new look. A self-hosted project with a client surface this wide has a maintenance cost that a single user application does not.

The second is that it is a podcast system, not a media library. The list of formats and features is about episodes, subscriptions, queues and playback. If your content is books, music albums or local video files, none of this applies, and the local file-system podcasts support is for podcast episodes you have already downloaded rather than for a general media server.

The third is the database requirement. The data lives in Postgres or MySQL and MariaDB, so a deployment needs a database server running and backed up, and the backup of a podcast server is only as good as the backup of that database.

The fourth is the single user case. The multi-user design is the point of the project, and for one person with one phone the whole architecture is overhead: a standalone client keeps the subscriptions on the device, needs no server and cannot break when the server is down. The gpodder support is what lets somebody use PinePods as the sync backend for an existing client, and if that is not what you want, the server is optional weight.

The fifth is a small one about the repository itself. The completed_todos.md file at the root and the mix of dockerfile, dockerfile-arm, Dockerfile.validator and Dockerfile.validator.postgres suggest a build story that has grown organically, and the requirements file is hand edited, as the duplicated dateutil entry shows. None of that is a blocker, but it is the shape to expect from a project run by volunteers, and it argues for reading the documentation site before you plan a deployment.

Editorial conclusion

Adopt PinePods if your household listens to podcasts on several platforms and you want one server that owns the subscriptions, the history, the queue and the downloads, and if you are willing to run and update it yourself. Do not adopt it for a single person with one device, where a standalone client does the same job without a server, and do not adopt it if you need an installation-free setup. Verify first that the media formats you need are supported, that your database is Postgres or MySQL and MariaDB as the project requires, and that the release you deploy matches the client versions you use, since the 0.9.0 release changed the client surface with video, CarPlay and Android Auto.

Frequently asked questions

What is PinePods?

PinePods is a complete, self-hosted podcast management system written in Rust. You run one server, your household connects to it, and your subscriptions, history, queue, downloads and settings follow you from device to device because everything lives in your own database, with Postgres or MySQL and MariaDB.

Can I keep using AntennaPod with PinePods?

Yes. The README describes a bring your own apps feature in which a built-in gpodder-compatible sync server lets you keep using AntennaPod and other clients alongside PinePods, and the repository has a dedicated gpodder-api/ directory for that protocol.

Which databases and clients does PinePods support?

Your data stays on your hardware in Postgres or MySQL and MariaDB, and the clients are web, Linux, Windows, macOS, Android and iOS, plus a CLI client called Firewood. The server also offers OIDC and SSO with MFA and TOTP.

How do I install PinePods on my own server?

The README links the documentation site at pinepods.online for the full story and deep configuration, and the repository carries a dockerfile, a dockerfile-arm, a Dockerfile.validator, a Dockerfile.validator.postgres and a deployment/ directory, with a Docker container build workflow in the project actions.

Official sources

  1. License: GPL-3.0
  2. madeofpendletonwool/PinePods on GitHub
  3. Project website
  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/madeofpendletonwool-pinepods.svg)](https://hysenlabs.com/projects/madeofpendletonwool-pinepods)

Was this useful?