Self-hosted service
Nriver/trilium-translation avatar
Nriver/trilium-translation

Nriver/trilium-translation: a hard-coded Chinese build of Trilium Notes

Translation for Trilium Notes. Trilium Notes 中文适配, 体验优化

2,864 stars313 forksHTMLAGPL-3.0

At a glance

What is it?
This fork patches Chinese UI text into official Trilium Notes releases and ships them as desktop archives and a Docker image. It is a distribution, not a plugin, and the language cannot be switched at runtime.
Who is it for?
Adopt it if you want a Chinese Trilium Notes and are willing to run a build that trails upstream releases; the README tells you to back up old data before use, and that instruction is the real gate. Do not adopt it if you need language switching, a current upstream version, or a supported upgrade path, because the translation is baked into the frontend and backend source and the README states you cannot switch languages.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 85 days ago.
What is it written in?
Mainly HTML, according to GitHub's language statistics.

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

Editorial analysis

What the fork actually ships

Trilium Notes is an English-first note application. This repository exists to remove that barrier for Chinese readers without waiting for upstream to merge translations. It is not a language pack you load into Trilium. It is a modified build: the README describes extracting resource files from the latest official Trilium Notes release, replacing UI text with regular expressions, and packing the translated files back into the package. The repository layout matches that description. You get demo-cn.zip, a font/ directory, a Dockerfile, and a docker-compose.yml that pulls nriver/trilium-cn from Docker Hub. The intended audience is narrow and obvious: Chinese-speaking users who want the desktop client or a self-hosted server in their own language, and who accept that they are running a fork rather than upstream. The README also points Android users to a separate project, Pocket Trilium, which is a different codebase and not covered here.

Regex replacement instead of an i18n layer

The mechanism is worth understanding before you trust it. According to the README, the translation works by extracting resource files from the latest official release and using regular expressions to replace UI text in each file. There is no message catalog, no locale negotiation, no runtime lookup. Translations live in translations.py and translations_cn.py, which the README says runs past 1000 lines. Some entries deliberately begin or end with quotes because the quotes are part of the regex match, and the README warns not to remove them. Placeholders such as ${xxxx} come from the original source and must not be modified. To catch text the first pass misses, you wrap it in double brackets {{}} in trans.py, then move the contents into the translations dict. That is a maintainable workflow for one translator, and a fragile one for a team: every upstream release can shift the strings your patterns match against, and a pattern that stops matching fails silently by leaving English in place. A pattern that matches too broadly can corrupt the interface, which is why the README says Trilium Notes may not function correctly if the translation contains mistakes.

Running the server with docker-compose

The fastest path to a working instance is the compose file in the repository root. It pins no version tag, so it pulls whatever nriver/trilium-cn currently is on Docker Hub. The service maps port 8080, mounts ./trilium-data into the container, and sets TRILIUM_DATA_DIR to /root/trilium-data.

yaml
version: '3'
services:
  trilium-cn:
    image: nriver/trilium-cn
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - ./trilium-data:/root/trilium-data
    environment:
      - TRILIUM_DATA_DIR=/root/trilium-data

Save that as docker-compose.yml and start it:

bash
docker-compose up -d

The README says the command downloads the Chinese build from Docker Hub, that you open http://127.0.0.1:8080 in a browser, and that your note data lands in the same directory as the compose file. The compose file also carries a commented healthcheck that curls http://localhost:8080/api/health-check and pipes the result through jq. It is disabled by default; uncomment it only if the image contains curl and jq, which the Dockerfile does install.

Desktop archives and the backup warning

For the desktop client, the README gives three steps: download the release that matches your operating system, unzip it, and run the binary (trilium for Linux, trilium.sh for a Linux server, trilium.exe for Windows, trilium.app for macOS). There is no installer and no package repository for the desktop build in the README, though the repository topics list scoop and AUR, which suggests community packaging exists. The warning that matters comes before all of this: if you have old data, back up before use. That is not boilerplate. Because the patch touches both frontend and backend source, a bad replacement can leave the application unable to start or unable to read your notes, and the README's recovery instruction is to redownload everything with init.py. There is no rollback command and no migration step documented. Treat the data directory as the thing you cannot afford to lose.

Building the translation yourself

If the published releases lag behind the upstream version you need, the repository expects you to build. The README lists the compile environment: Python 3 with requests, Node.js with asar, webpack and webpack-cli, and 7z if you want to produce a release archive.

bash
pip3 install requests --user
npm install -g asar webpack webpack-cli
npm install webpack --save-dev

The process is four scripts in order. Edit settings.py following its comments, edit translations.py (translations_cn.py is the reference), run python3 init.py to download the latest Trilium Notes, run python3 trans.py to produce a translation patch, then run python3 make_release.py to apply it across platforms. The README states its author works on Manjaro and that paths in the scripts need changing on other systems. It also carries a blunt warning: the scripts include rm -rf commands, so read them before running them. The numbered filenames in the repository root (1.init.py, 2.trans.py, 3.make_release.py) mirror this order.

Where this approach breaks down

The README's Limitations section is unusually direct. The translation is hard-coded into the frontend and backend source, so you cannot switch between languages. If you share a machine with an English reader, this build is wrong for you. If your translation has errors, the application may misbehave, and the documented fix is to redownload everything with init.py. There is also a version-coupling problem the README does not address: because each build targets a specific upstream release, the fork's usefulness depends on how quickly it is rebuilt after upstream ships. The most recent release listed is v0.63.7_20240530, and the repository's last push was on 2026-07-08, so the codebase is being touched even though the visible releases are older. Anyone who needs a recent upstream feature should verify the tag before installing rather than assuming the release list is current.

TriliumNext and the upstream alternative

The obvious alternative is TriliumNext, the successor project to Trilium Notes, which appears in the related searches for this repository. The difference is structural rather than cosmetic. TriliumNext is an upstream codebase that can build localization into the product itself, so a language becomes a setting rather than a build. This fork takes the opposite route: it leaves upstream untouched and rewrites the shipped artifacts. That buys speed, since a translator can patch a release without waiting for a merge, and it costs you the ability to upgrade normally, because every new upstream release resets the patching work. If your priority is a Chinese interface today and you accept a pinned version, the fork is the shorter path. If your priority is staying on current upstream code with a supported upgrade path, the fork is the wrong tool and you should look at how TriliumNext handles localization instead. Note that the README states the original translation code for Zadam's Trilium was moved to a branch named zadam-version, and that this repository now focuses on a modified version of Trilium.

Licence and the cost of staying current

The repository is AGPL-3.0. That matters for anyone who wants to run a modified Trilium as a network service: the AGPL's source-availability condition applies to users interacting with the service over a network, so if you patch the code further and host it, you should read the licence text rather than assume the fork's licence covers your changes. This is not legal advice. On maintenance cost, the honest accounting is that the fork's work is proportional to upstream churn: every release that changes UI strings invalidates some of the regex patterns in translations.py, and the README's own instruction for finding missed text (wrap it in {{}} in trans.py, then add it to the dict) is manual. Budget for re-running init.py, trans.py and make_release.py after each upstream release you care about, and for re-testing the interface, because a silent pattern miss leaves English text rather than an error.

Editorial conclusion

Adopt it if you want a Chinese Trilium Notes and are willing to run a build that trails upstream releases; the README tells you to back up old data before use, and that instruction is the real gate. Do not adopt it if you need language switching, a current upstream version, or a supported upgrade path, because the translation is baked into the frontend and backend source and the README states you cannot switch languages. Before committing, check the newest release tag against the upstream version you actually need, and confirm that the Docker image tag you pull matches it. If the tag lags, build from source with 1.init.py and 2.trans.py rather than assuming the image is current.

Frequently asked questions

How do I use Trilium Notes in Chinese?

Download the release for your operating system from the repository, unzip it, and run the binary (trilium, trilium.sh, trilium.exe or trilium.app). For a server, use the docker-compose.yml and run docker-compose up -d, then open http://127.0.0.1:8080.

Is Trilium Notes open source?

This translation fork is licensed AGPL-3.0, and the README describes it as a modified version of Trilium Notes, which it builds from official releases. The licence file is in the repository root.

Does Trilium Notes have an app?

The README lists desktop builds per platform: trilium for Linux, trilium.sh for a Linux server, trilium.exe for Windows and trilium.app for macOS. For Android it recommends a separate project, Pocket Trilium.

Official sources

  1. Issues
  2. License: AGPL-3.0
  3. Nriver/trilium-translation on GitHub
  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/nriver-trilium-translation.svg)](https://hysenlabs.com/projects/nriver-trilium-translation)