Questarr and the case for an Arr-style manager for a game library
Questarr is an *Arr-inspired game manager that helps you discover, track, and automatically download the games you want.
At a glance
- What is it?
- Questarr is a self-hosted TypeScript application that borrows the Sonarr and Radarr model for video games, tracking your collection against IGDB, RSS feeds and Steam, and driving downloads and library imports from one interface. Its heaviest requirements are an IGDB credential and a database choice you make at install time.
- Who is it for?
- Questarr suits a self-hoster with a large and shifting game library who wants one interface for tracking, discovery and import, because the Arr pattern it follows is proven and the metadata sources are mainstream APIs. It does not suit someone who only wants a list of games, since the operational machinery is the product, and it does not suit a deployment that cannot reach an external indexer.
- 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 TypeScript, 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
The Arr pattern applied to a library rather than a TV show
Questarr is a video game management application inspired by the Arr apps, with Sonarr, Radarr and Prowlarr named, along with GamezServer. The stated aim is to track and organise a video game collection with automated discovery and download management.
The Arr pattern is worth understanding before the feature list, because it explains the shape of the whole application. In the Arr family, the user's library is the source of truth, a monitor watches for wanted items, a download client fetches them, and an importer moves the finished file into the library. The application is the glue between a metadata provider and a download client, and the value is that the glue runs continuously so the user does not have to think about it.
Questarr applies that to games rather than episodes or films, and the metadata sources are the equivalent of an indexer. The feature list is organised the same way the Arr applications are, with separate sections for what the library knows, what it wants, and what it is fetching.
That framing also explains the product's nature. This is not a game launcher with a nice interface, and it is not a store front. It is a management console that assumes you already own the download infrastructure, and the interesting work is in the bookkeeping.
The project is GPL-3.0 licensed, written in TypeScript, and its documentation site is at doezer.github.io/Questarr/.
Backlog management is the feature that is not borrowed from Arr
The first row of the feature table is where Questarr departs from its models, and it is the one that makes this a game application rather than a renamed television manager.
Backlog management covers tracking game status, ratings, notes and a play journal, and there is a Backlog roulette feature to pick a game from the Library or the Playing state. That is a game-specific concept: a television backlog has a watched and unwatched, and a game backlog has a much richer set of states, and the play journal with ratings and notes is closer to a media server's user data than to a download queue.
Game discovery is the second row and it names the sources. You can browse IGDB, RSS feeds and xREL.to, manage ratings and visibility from the game details view, sync your Steam wishlist, and discover games already on disk through a Library Import feature.
The Steam wishlist sync is the piece that changes the daily use of the application. A wishlist is a queue of things you intend to buy, and pulling it into the application means the application knows what you want before you have done anything about it. Combined with the backlog state, that gives you one view of what you own, what you have finished, what you are playing, and what you have decided to get next.
The third row, search and filter, adds the piece that makes a big library usable. You can find games by genre, platform and keyword, with automatic search that continues until a release is found, release blacklisting, and preferred release groups and platforms. A Settings entry under Appearance scopes the application to your chosen platforms, with optional filters to hide shelved and owned games and to hide age-restricted or erotic content.
Download management, library import and the archive handling detail
The fourth row is the one that connects back to the Arr family, and it is where the operational detail sits.
Downloads can be automated, and library import is handled alongside, with archive updates that preserve unrelated installed files. There is manual review, optional security scanning, and experimental AI matching for associating a downloaded file with the right entry.
The phrase about archive updates preserving unrelated installed files is the one to notice. A common failure mode in these systems is that replacing a file inside a directory replaces the directory, so anything else the user had put there disappears. Preserving unrelated files is a specific fix for a specific annoyance, and it is a sign the author has run the thing against a real library.
Manual review and the option to scan are the middle ground between trusting the automated path entirely and not automating. AI matching is marked experimental, which is the correct word for a feature that infers which game a file is by looking at it.
The top-level directory listing shows the same emphasis in the code. There is a docs/ directory with separate documents for the backlog roulette and the library import, an extensions/ directory, a security/ directory, a charts/ directory, and a casaos/ directory alongside cosmos/, which are the two deployment targets the project supports beyond plain Docker. There are also migrations/ and migrations-pg/ directories, two separate sets because the application supports two databases.
The stack, and the database decision that shapes the install
The project supports two databases and makes you choose at install time, and the two configurations are visible in the repository.
The package scripts have parallel sets for the two. There is db:generate and db:migrate and db:push for the default path, and db:generate:pg, db:push:pg and db:check:pg that pass a separate Drizzle config file, drizzle.config.pg.ts against the ordinary drizzle.config.ts. The migration directories follow the same split with migrations/ and migrations-pg/, and there is a docker-compose.postgres.yml next to the ordinary docker-compose.yml. The ORM is Drizzle, and the schema lives in drizzle.config.ts.
The build is a single TypeScript package serving both the client and the server. The dev script runs the server with tsx, the build script runs vite build and then tsc with a build-specific tsconfig, and the start script runs the compiled server from dist. Tests are vitest for units and playwright for end to end, with a second playwright config for the stack.
The security tooling in the scripts is worth a mention because it is unusual in a hobby project: a secretlint pass with masking over the whole tree, an audit:prod script, a check:deprecated script for dependency deprecations, and a check:overrides script. A secretlint configuration at the root and a .zap/ directory suggest the project takes accidental credential commits seriously.
The stack also includes a husky/ directory for git hooks, a .pre-commit-config.yaml, and separate tsconfig files for the app and for the build.
Running it as a container, and the health check that tells you it works
The compose file is short and it shows the intended deployment: a single published image with a data volume and a health check.
services:
app:
image: ghcr.io/doezer/questarr:latest
ports:
- "${HOST_SIDE_PORT:-5000}:${CONTAINER_INTERNAL_SIDE_PORT:-5000}"
- "${SSL_PORT:-9898}:${SSL_PORT:-9898}"Two ports are published. The first is the application itself, with both sides defaulting to 5000 and overridable by environment variable so the host port can differ from the container port. The second is an SSL port with a different default, which is how the application is served over HTTPS without the reverse proxy doing the termination.
The health check is a real one rather than a sleep, and it polls the application's own health endpoint:
healthcheck:
test:
[
"CMD",
"node",
"-e",
"require('http').get('http://localhost:' + (process.env.PORT || 5000) + '/api/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))",
]
interval: 30s
timeout: 10s
retries: 3
start_period: 40sA forty second start period is generous and appropriate, because the first run applies migrations and may need to seed data. The three volumes are commented out in the file with an example of where to mount your media and downloads folder so the application can move files atomically, and there is a commented SQLITE_DB_PATH line for the database path.
The Dockerfile is a three stage build on a pinned node:26-alpine digest, and its comments are unusually explanatory about why the image looks the way it does, covering the apk upgrade for point release security fixes, and why g++, make and python3 remain necessary even though better-sqlite3 ships a prebuilt binary, since npm's implicit node-gyp rebuild still runs. It also installs 7zip and a glibc compatibility shim, with the reason spelled out: the glibc-linked 7za that the npm package bundles can never execute on a musl-only base image.
Credentials, encryption and the API keys you will need
The environment template is unusually well documented, and it distinguishes the one key you need from the ones you might want.
The IGDB client id and secret are required for game discovery and metadata features, and the instructions say to register an app on the Twitch developer console to get them. If they are not set, the application asks for them in its settings. Everything else is optional.
The Steam Web API key is optional and only needed for the achievements section of a game's journal tab, since wishlist import and app id lookups do not need it. The Nexus Mods API key is optional too, and is used to check whether a game has a section there and to show trending mods, with the rate limits written down as 500 requests per hour and 20,000 per day. The App key for a personal Nexus Mods account is where you get it.
The two security settings are the ones to set deliberately rather than leave alone. The JWT secret is optional, and if you do not provide one a secure random secret is generated and stored in the database, but setting a long random string yourself keeps sessions valid across server restarts. The credentials encryption key encrypts the stored indexer and downloader API keys, usernames and passwords at rest, and it must be a 64 character hex string, which the comment shows how to generate. If you do not set it, a random key is generated and stored in the database, which means the stored secrets become unreadable if that database is lost or restored without the key.
There is also a separate optional block for the server configuration, including the port to run on.
Where Questarr is the wrong tool
The first case is a small library. The operational weight here is real: a database to migrate, credentials to encrypt, an indexer to configure, and download clients to drive. If you have twenty games and no intention of acquiring another fifty, the machinery costs more than it returns.
The second is a deployment that cannot reach external services. Discovery depends on IGDB, and the RSS and xREL.to paths depend on those services being reachable. A closed network without outbound access gets an application with an empty catalogue, and no amount of configuration changes that.
The third is a user who wants a launcher. Questarr is a management console with a library, a backlog and a discovery feed. It does not launch games, and the play journal and ratings are bookkeeping rather than a platform integration.
The fourth is anyone uneasy about a GPL-3.0-only application that holds indexer credentials. The licence is fine for self-hosting, where nobody distributes it, but the copyleft is a real consideration for anyone planning to modify and redistribute it, and the recorded licence identifier is GPL-3.0-only with the text in a COPYING file.
Editorial conclusion
Questarr suits a self-hoster with a large and shifting game library who wants one interface for tracking, discovery and import, because the Arr pattern it follows is proven and the metadata sources are mainstream APIs. It does not suit someone who only wants a list of games, since the operational machinery is the product, and it does not suit a deployment that cannot reach an external indexer. Before you install it, get an IGDB application registered, because that credential is required for discovery while the others are optional, and note that the SQLite and PostgreSQL paths are both supported, that the licence is GPL-3.0-only, and that the last push was on 2026-10-20.
Frequently asked questions
What is Questarr?
It is a self-hosted video game management application inspired by the Arr apps such as Sonarr and Radarr, and by GamezServer. It tracks and organises a game collection with automated discovery, backlog management, search and filter, and download management with library import.
Where does Questarr get game metadata from?
From IGDB, RSS feeds and xREL.to, with the ability to manage ratings and visibility from the game details view, to sync a Steam wishlist, and to discover games already on disk through a library import. An IGDB application id and secret are required for discovery and metadata, while the Steam and Nexus Mods keys are optional.
Does Questarr support both SQLite and PostgreSQL?
Yes. The repository carries separate Drizzle configuration files and separate migration directories for the two, parallel npm scripts such as db:generate and db:generate:pg, and a docker-compose.postgres.yml alongside the ordinary compose file. The default compose deployment uses SQLite with the database under /app/data.
How is Questarr deployed?
Through Docker Compose, publishing the ghcr.io/doezer/questarr image on a configurable host port mapped to container port 5000, plus an SSL port. The compose file includes a health check that polls the /api/health endpoint every thirty seconds, and a commented mount for your media and downloads folder so the application can move files atomically.
How does Questarr handle credentials for indexers and downloaders?
Stored API keys, usernames and passwords are encrypted at rest, and the encryption key is a 64 character hex string you can generate with openssl rand -hex 32. If you leave it unset, a random key is generated and stored in the database, so the stored secrets would be unreadable if that database were lost. The session JWT secret works the same way and setting it yourself keeps sessions valid across restarts.
Official sources
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.
[](https://hysenlabs.com/projects/doezer-questarr)Was this useful?