Model or dataset
lingarr-translate/lingarr avatar
lingarr-translate/lingarr

Lingarr translates subtitle files through whichever engine you point it at

Lingarr is an application that supports both local and SaaS translation services to translate subtitle files into a specified target language. With automated translation options, Lingarr simplifies translating subtitles.

890 stars76 forksC#NOASSERTION

At a glance

What is it?
Lingarr is a C# application that translates subtitle files into a target language using LibreTranslate, local AI models, DeepL, or a long list of hosted providers, with a queue for the work. It suits a media library owner with a folder of subtitles and no translation budget, and it needs a container and a database.
Who is it for?
Lingarr suits someone with a directory of subtitle files, a choice of translation engine, and a willingness to run a container with a database behind it, and it is particularly good when the translation has to stay on your own hardware through a local model.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

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

Editorial analysis

The engine is a choice, not the product

Lingarr is described as an application that uses translation technologies to automatically translate subtitle files to your desired target language, and the interesting design decision is where the intelligence is expected to live.

The service list is long, and it is the reason to look at this project rather than a script. There is LibreTranslate, which is self-hostable. There is local AI, with Ollama or any other OpenAPI compatible model or router, so a translation can run entirely on your own machine. Then there is a list of hosted and commercial options: DeepL, noted in the README as without pt-BR support, Anthropic, OpenAI, DeepSeek, Mistral, xAI, Gemini, and the consumer translation services Google, Bing, Yandex and Microsoft. The README closes the list with a sentence that is really the whole point: choose the service that best fits your needs.

That last group is what makes the project useful rather than merely interesting. A self-hosted LibreTranslate and a commercial API are the same interface to Lingarr, so the decision of which to use is a setting rather than a rewrite, and a user can move between them as cost and privacy requirements change.

The application itself is written in C#, and the repository layout shows a conventional .NET solution: Lingarr.slnx with Lingarr.Server, Lingarr.Client, Lingarr.Core, Lingarr.Contracts, Lingarr.Migrations, and separate test projects for the server and the migrations, plus a docs project. The CloudflarePlugin under samples shows that the provider surface is extensible, which matters for the hosted-engine list.

Two deployment paths, one compose file

The Docker path is the documented one, and the compose file is where you can see the whole shape of the deployment.

The service block is short enough to read in full:

yaml
  lingarr:
    image: ghcr.io/lingarr-translate/lingarr:latest # or lingarr/lingarr:latest
    container_name: lingarr
    restart: unless-stopped
    environment:
      - ASPNETCORE_URLS=http://+:9876
      - DB_CONNECTION=mysql
      - DB_HOST=lingarr-db
      - DB_PORT=3306
      - DB_DATABASE=lingarr
      - DB_USERNAME=lingarr
      - DB_PASSWORD=your-password # provide a password
    ports:
      - "9876:9876"

Three things in that block are worth calling out. The port is 9876, and ASPNETCORE_URLS is set to http://+:9876 so the container listens on all interfaces rather than only loopback, which is what makes the published port work. The database is a separate service, lingarr-db, running mariadb:latest with its own healthcheck that runs a SELECT 1 against the configured database. And the depends_on block waits for that database to report healthy before starting the application.

That waiting matters, and the README says why in a single sentence: Lingarr starts quickly, so if migrations fail, using a healthcheck combined with depends_on is recommended. The race the healthcheck removes is a container that boots, tries to migrate, finds the database not yet ready, and exits. The compose file handles it, and the note explains the reasoning so the pattern is not cargo-culted.

The volumes are the third element. The example mounts a movies directory at /movies, a TV directory at /tv, and a config directory at /app/config, which is where the settings and the Hangfire database live. The media paths are the input, and the config path is the state.

The command line path for people who prefer it

The README also gives a Docker CLI route, step by step, for people who do not want a compose file in their setup.

The first step is creating the network, because both containers need to talk to each other over it:

bash
# Create the network
docker network create lingarr

# Start MariaDB
docker run -d \
  --name lingarr-db \
  --restart unless-stopped \
  -e MYSQL_DATABASE=lingarr \
  -e MYSQL_USER=lingarr \
  -e MYSQL_PASSWORD=your-password \
  -e MYSQL_ROOT_PASSWORD=your-root-password \
  -v /path/to/db:/var/lib/mysql \
  --network lingarr \
  mariadb:latest

The Lingarr container then follows with the same environment variables, the same volume mounts and the same port mapping, and the image name is either ghcr.io/lingarr-translate/lingarr:latest or lingarr/lingarr:latest. The README notes both registries publish the images.

There is a practical point about the image tags, and it is in a table of its own. The latest tag is the latest stable release, a version tag such as 1.2.3 pins a specific version, and main is a development build from the main branch, marked with a warning sign. All three support amd64 and arm64, and the README states that as of 1.0.3 all images support both AMD64 for Intel and AMD processors and ARM64 for Raspberry Pi and Apple Silicon, with Docker pulling the correct architecture automatically. That is what makes the container usable on a single-board computer next to the media library, which is where most people running this would put it.

The database is your choice, and the queue is a database

By default Lingarr uses MySQL, with PostgreSQL and SQLite also supported, and the environment variable table spells out which settings are required for which.

DB_CONNECTION takes mysql, postgresql or sqlite. For the first two you must also set DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME and DB_PASSWORD, while the sqlite path needs only a file location, which is given separately as DB_HANGFIRE_SQLITE_PATH=/app/config/Hangfire.db.

That last variable name is the tell for the architecture. Hangfire is the job queue, and the sqlite file is its storage, so a SQLite deployment keeps the whole application state in the mounted config directory with no separate database container. The same directory holds the rest of the settings, and the README points at a Settings.MD file for additional settings that can be set as environment variables so they persist across a reinstall. That last point is the operational one: a container that is recreated on upgrade should not lose the configuration, and the project pushes those settings to environment variables for exactly that reason.

The job behaviour is tunable too. MAX_CONCURRENT_JOBS sets how many jobs run at once and defaults to 1, and JOB_TIMEOUT_MINUTES is the number of minutes of silence before Hangfire retries a job, defaulting to 30 and documented as sqlite only. A single worker by default is a sensible choice for a translation queue, where a single misbehaving file should not spawn a dozen concurrent calls against a paid API, and it is the setting a user is most likely to raise once they trust the pipeline.

Where the boundary of the tool sits

Three limits are worth stating plainly, because the feature list is generous and the boundaries are not in the README's headline.

The first is that the output is a subtitle file, and the quality of a machine-translated subtitle is a different thing from a translated script. Subtitle lines are short, idiomatic, and timed to a spoken sentence. A translation that is grammatical but a beat too long will not fit, and a translation that drops the register of a line will read wrong on screen. The project automates the substitution of words; it does not re-author the line for the frame. Anyone using this for subtitles they will publish should expect to proof them.

The second is that a local model changes the arithmetic but not the shape. Running a translation through an Ollama model or an OpenAI compatible router keeps the text on your own hardware, which matters for private media. It does not change the fact that a general-purpose model is being asked to do a constrained, timed, register-sensitive task. The README lists LibreTranslate and local AI first, and the quality difference between them and the commercial engines is not something the documentation claims to measure.

The third is that this is a self-hosted application with a web interface, a database and a background worker, which is a fair amount of moving parts to run for a task that could be a script. A user with twenty subtitle files has a simpler answer available. The tool earns its complexity when a library of thousands of files arrives over time, when translations need to be reviewed and retried, and when the choice of engine has to be configurable rather than baked into a script.

There is also a licensing question to settle. The README badge shows AGPL-3.0 and the LICENSE file is at the repository root, while the licence field on the repository carries a custom classification that GitHub cannot map, so the terms are worth reading in the file itself before this is deployed anywhere with external users.

Editorial conclusion

Lingarr suits someone with a directory of subtitle files, a choice of translation engine, and a willingness to run a container with a database behind it, and it is particularly good when the translation has to stay on your own hardware through a local model. It is the wrong tool for translating a script you are about to record, where the timing and the wording both have to be re-authored by a translator, and the wrong tool for anyone who needs subtitle translation as part of a video workflow, because the project only handles the subtitle file. Before you deploy it, read the Settings.MD file the README points at for the settings that survive a reinstall, confirm the job queue behaviour you want with MAX_CONCURRENT_JOBS and JOB_TIMEOUT_MINUTES, and check the licence file in the repository root, since the README badge shows AGPL-3.0 while the licence field carries a custom classification.

Frequently asked questions

Which translation services can Lingarr use?

The README lists LibreTranslate, local AI through Ollama or any OpenAI compatible model or router, DeepL, Anthropic, OpenAI, DeepSeek, Mistral, xAI, Gemini, and the Google, Bing, Yandex and Microsoft translation services. The DeepL option is noted as not supporting pt-BR.

How do I run Lingarr with Docker?

The compose file creates a lingarr service and a MariaDB service on a shared network, with the application waiting on the database healthcheck. The service listens on port 9876, takes its database settings through environment variables, and mounts your media directories and a config directory for its state.

Does Lingarr need a database, and which ones are supported?

By default it uses MySQL, and PostgreSQL and SQLite are also supported, set with DB_CONNECTION. The MySQL and PostgreSQL paths require the host, port, database name, username and password, while SQLite uses a local file whose location is given by DB_HANGFIRE_SQLITE_PATH.

Which CPU architectures do the Lingarr Docker images support?

Both AMD64 and ARM64, and the README states that as of 1.0.3 all images support them, so Docker pulls the correct architecture automatically. The latest, a pinned version and the main development tag are all published for both.

Official sources

  1. Issues
  2. lingarr-translate/lingarr on GitHub
  3. README
  4. 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/lingarr-translate-lingarr.svg)](https://hysenlabs.com/projects/lingarr-translate-lingarr)

Was this useful?