# Invidious: a Crystal front end for YouTube that asks for no official API

> Twenty-four thousand stars of alternative front end, from a single-instance quick start to a hardened container build that puts debug symbols back on purpose.

**iv-org/invidious** — Invidious is an alternative front-end to YouTube

- Repository: https://github.com/iv-org/invidious
- Website: https://invidious.io
- Stars: 24,617 · Forks: 2,764
- Language: Crystal
- License: AGPL-3.0
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/iv-org-invidious

## The technical feature that matters most is the absence of an API

The feature list has a user half and a technical half, and the technical half is short on purpose. It lists embedded video support, a developer API, and two negatives: it does not use official YouTube APIs, and it carries no Contributor License Agreement. Those two lines are the project.

Every feature above them is downstream of that choice. No ads and no tracking follow from not participating in the ad system. Subscriptions independent from Google follow from not being signed in to Google. Notifications for every subscribed channel follow from holding the subscription list yourself instead of asking an account for a feed. The readme is blunt about the cost, in its own liability section, which disclaims responsibility for how the tool is used and points at the applicable regulations rather than pretending the question does not exist.

The user feature list also includes audio-only mode with background play on mobile, Reddit comment support, and a claim that no JavaScript is required. That last one is the most architecturally interesting item on the list. Rendering a video page, a preferences page and a subscriptions page without client-side scripting means the server does the work, which is why Crystal and a server-side approach make sense here.

Data portability is treated as a first-class feature rather than an afterthought. Subscriptions import from YouTube, NewPipe and FreeTube, and export to NewPipe and FreeTube. Watch history imports from YouTube and NewPipe. That set of names is a fairly precise description of who this is for: people who arrived from a mobile client, or who want to leave with their list intact.

## Three ways to use it, and only one of them involves you running anything

The quick start is two lines and the second one is a link to external documentation. As a user, you pick a public instance from a maintained list and start watching. As a host, you follow the installation instructions on the documentation site. There is no third path offered, and the distinction matters because the two have completely different costs.

The readme does not try to hide where the real content lives. Documentation is at docs.invidious.io, its source is in a separate repository, and the documentation carries an applications page listing other projects and browser extensions that work with Invidious. The recommended extension is one that rewrites YouTube URLs to whichever instance you use and replaces embedded YouTube players on other sites, which is the practical answer to the problem that a front end cannot fix a link someone else already published.

Communication is spread across Matrix, Libera IRC, a Mastodon account and email. The presence of four channels rather than one is a reasonable signal about how much traffic a project of this size carries.

Contributing is documented in the ordinary GitHub way, with a fork, a feature branch, and a pull request, plus a translation workflow through Weblate that does not require an account but recommends one for regular contributors. The repository tree includes a locales directory and a translation status badge, which is the practical measure of how many people the interface actually reaches.

## Reading the compose file as a description of the real dependencies

The repository's own compose file opens with a warning that it is for development, builds from the locally cloned source, and points anyone deploying to the compose file in the installation documentation. That warning is worth taking seriously, because the file it guards reveals the actual requirements: a Crystal web application, a PostgreSQL 14 service, and a schema applied on first boot.

The service definition waits for the database to report healthy before starting, and configures a healthcheck against the statistics endpoint rather than the front page:

```yaml
    healthcheck:
      test: wget -nv --tries=1 --spider http://127.0.0.1:3000/api/v1/stats || exit 1
      interval: 30s
      timeout: 5s
      retries: 2
```

Two details in there are worth pausing on. The port binding is to the loopback interface only, which is the correct default for a compose file and also a reminder that putting this behind a reverse proxy is the expected production shape. And the configuration block is embedded as an environment variable pointing at a commented example file, with the hmac key left as a placeholder value that obviously needs replacing before anything faces the internet.

The database service is deliberately plain: an official PostgreSQL image, a named volume for the data directory, the SQL directory mounted for schema, and the initialization script mounted into the entrypoint directory. Readiness uses the standard client utility against the configured user and database name, and the application waits on that condition before it starts.

## A Makefile that tells you what the binary needs

The build is small enough to describe in a Makefile, which is a good sign. There are two compilation switches, release and static, and two behaviour switches, one that produces an API-only build and one that skips the version check. Debug symbols are on by default and can be turned off with a single variable, which is the opposite of what most projects do and turns out to matter for running a public instance.

The library fetch and the build are two targets, and the build itself is a single Crystal invocation with progress and statistics output:

```makefile
get-libs:
	shards install --production

invidious: get-libs
	crystal build src/invidious.cr $(FLAGS) --progress --stats --error-trace
```

There is also a verify target that compiles without generating a binary, which the file describes as useful for searching for errors, and a target that no longer passes a flag the Crystal toolchain had deprecated. The help text at the bottom enumerates the targets for anyone who lands in the repository without knowing the conventions.

The practical consequence for an operator is that you can build a static binary with debug symbols and hand it to whatever supervisor you already run, without adopting the container at all. The container is a convenience, not a requirement, and the file structure supports that: a docker directory, a kubernetes directory, a systemd unit file and a nix directory all sit side by side at the top level.

## What the recent releases say about running a public instance

The release notes are organised by audience, which makes them unusually easy to read. Users, instance owners and developers get separate lists, and a user-facing entry can be as small as a message that now appears when comments are turned off.

Two instance-owner items from the August 2026 release are the ones that matter if you operate a public service. SOCKS5 proxy support was added, which matters in jurisdictions where direct egress is not available, and the videojs maximum buffer length became configurable through the config file, which turns an out-of-memory symptom into a setting. The same release added several locales once they passed a translation threshold, including Belarusian, Galician, Swiss German, Armenian, Latvian and Uzbek, which is a sensible gate: a translation ships once it is usable rather than as soon as it exists.

The July 2026 release is the security-relevant one. It closed a cross-user playlist deletion vulnerability, added a configuration flag to disable API endpoints that are easy to abuse, reduced the channel refresh job's backoff when no errors occur, and updated the user agent sent to YouTube. The flag to turn off the API is the interesting decision: for a public instance, the developer API is also an abuse surface, and making it opt-in is a reasonable position.

Then there is the August patch release, whose entire content is restoring debug information that the container build had dropped. The fix passes the correct link flag so debug symbols survive into the OCI image, and the stated reason is better stack traces and crash analysis. A patch release whose subject is diagnosability tells you what an operator actually needs from a service like this: not more features, but the ability to find out why it fell over at three in the morning.

## Reading the repository as evidence of where the project is heading

The tree is more informative than the readme about current priorities. There is a dependency manifest and lock file for Crystal packages, a spec directory for tests, a mocks directory, and separate docker and kubernetes deployment assets. Two entries stand out. There is an AI policy document at the top level, introduced alongside issue and pull request templates that carry a compliance field, and the August release notes describe that policy as banning low-quality generated submissions outright. That is a deliberate stance, and a project with a public instances list has good reason to care what arrives in its queue.

There is also a changelog and a legacy changelog side by side, which suggests a point where one was split off, most likely when automated release notes took over from a hand-maintained file. Combined with the four-part release notes format, the picture is a project that has automated its releases and now has to live with the consequences.

The scale is worth stating plainly. Twenty-four thousand six hundred stars, two thousand seven hundred and sixty-four forks, four hundred and ninety open issues, and a last push on 2026-09-18 with a release three weeks earlier. The AGPL-3.0 license matters here in a specific way: an instance operator who modifies and serves the code over a network is distributing it under the same terms, which is exactly the outcome that license was chosen to produce.

None of this makes the project easy to run. It scrapes a site that changes without notice, so breakage is a scheduling question rather than an exception. The release before this writing fixed video metadata and playback after upstream changes, which is the normal shape of work here, and the honest reading is that an instance operator is taking on a recurring maintenance commitment in exchange for a front end that does not track its users.

## Conclusion

Invidious is best understood as a piece of infrastructure with a user interface attached, not as a browser or a downloader. What it does well is refuse the official API, keep the interface usable with JavaScript turned off, and make hosting a public instance a documented operation rather than a folklore one. The recent releases show the project spending its effort on the unglamorous half: a build flag that restored debug symbols, a proxy option, a switch to disable the API surface, a cross-user playlist deletion fix. If you want to read one file to understand where the current work is, the release notes are more informative than the readme. Start from the instances list as a user, and from the installation documentation rather than the repository's own compose file if you intend to run one.

## FAQ

### What does invidious do?

It serves an alternative web front end for YouTube. Pages are rendered on the server, so watching, browsing and managing subscriptions work without client-side scripting, and the project states that it does not use the official YouTube APIs. Subscriptions and watch history are held independently of a Google account.

### Do I need to host Invidious myself to use it?

No. The quick start points you at a maintained list of public instances and that is the whole procedure. Hosting is a separate path described in the installation documentation, and it is the expensive one, since an operator inherits the job of reacting when YouTube changes its pages.

### Does Invidious let you import subscriptions from other services?

Yes, and the list is specific: subscriptions import from YouTube, NewPipe and FreeTube, and export to NewPipe and FreeTube. Watch history imports from YouTube and NewPipe, and Invidious user data itself can be exported and imported.

### What does an instance operator need to run Invidious?

A Crystal application and PostgreSQL. The repository's compose file, which its own header says is for development, configures both, waits for the database healthcheck before starting the application, and binds the port to loopback so a reverse proxy can sit in front.

### Why is the debug information fix in the latest release significant?

The container build had been omitting debug symbols, which removed the stack traces needed to diagnose crashes. The patch restores them by passing the correct link flag, so a public instance operator can investigate a failure after the fact.

## Sources

- [iv-org/invidious on GitHub](https://github.com/iv-org/invidious)
- [License: AGPL-3.0](https://github.com/iv-org/invidious/blob/master/LICENSE)
- [Project website](https://invidious.io)
- [README](https://github.com/iv-org/invidious/blob/master/README.md)
- [Releases](https://github.com/iv-org/invidious/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/iv-org-invidious
