The two characters 鍛錬 that form this word carry the idea of the steady work
it takes to refine and consolidate a metal before it can be forged.
In the learning of a physical discipline, tanren does not refer to developing
one specific technique, but rather to the groundwork that has to come first.
Tanren is an open-source Japanese training app: hiragana and katakana,
the 2,136 jōyō kanji, and flashcards you write yourself. Grammar comes later.
Whatever you are studying, you answer in one of two ways.
|
Recognition Multiple choice matching, to build immediate reading. |
Direct input Typing it yourself, with the device's real Japanese IME where the answer is Japanese. |
|
Kana Both syllabaries, with the whole table on screen: you tick the families you want and the round repeats a sign until you get it right. |
Kanji A path of 86 levels ordered by the pieces kanji are built from. Meaning and readings are scheduled apart, and each card says how consolidated it is. |
Flashcards Decks and cards you write yourself, studied in either direction, with extra accepted answers and a furigana per card. |
|
Local-first No account, no server. Your data stays on the device. |
Spaced repetition FSRS decides what to review just before you would forget it, on kanji and flashcards. Kana stay out of it on purpose: an alphabet needs minutes, not days. |
Mobile-first Built for a small screen and thumb reach. Desktop works too. |
Grab the APK from the latest release
and open it on the phone. The build carries arm64-v8a and armeabi-v7a.
Play Protect refuses the install the first time. It says it has never seen an app from this developer, which is true: it happens to any app signed with a key Google does not know. Tap More details, then Install anyway. The warning will not go away while Tanren is distributed outside the stores.
minSdk is 24, so Android 7 and up in principle, but it has only been run on Android
15. Below Android 11 the on-screen keyboard may cover the question you are answering,
because older versions do not report keyboard insets reliably.
There is no desktop download, and that is deliberate. Android is the only surface you cannot use without an executable, so the release carries an APK and nothing else. On a desktop you clone and run, which takes two commands and is described below. Building and hosting three binaries for three operating systems would be three build chains to maintain for the secondary case.
- Node 20.19+ or 22.12+, as required by Vite 8.
- Rust stable 1.85+, required by edition 2024.
- On Linux, Tauri's system libraries. On Ubuntu 24.04:
sudo apt install -y libwebkit2gtk-4.1-dev build-essential curl wget file \
libxdo-dev libssl-dev libdbus-1-dev pkg-configOn macOS you need the Xcode command line tools, on Windows the Visual Studio Build Tools with the C++ workload, plus WebView2.
npm install
npm run tauri devThe first run compiles the whole Rust dependency tree and takes a few minutes. Later runs are immediate. The window opens in portrait shape, because the design targets the phone first.
| Command | What it does |
|---|---|
npm run tauri dev |
the full app, Tauri shell plus frontend |
npm run dev |
frontend only in the browser, without the Rust core |
npm run build |
production build of the frontend |
npm run lint |
oxlint, including the cross feature import rules |
npm run tauri build -- --no-bundle |
desktop executable, without the packaging step |
cargo check --workspace |
compile everything on the Rust side |
cargo test -p tanren-core |
domain tests, without starting Tauri |
The app builds but crashes on startup on Linux
If the error looks like this:
symbol lookup error: /snap/core20/.../libpthread.so.0:
undefined symbol: __libc_pthread_init, version GLIBC_PRIVATE
your terminal is inheriting the environment of an editor installed as a snap.
GTK_PATH points at the snap's GTK modules, GTK loads canberra-gtk-module from
there, and that module drags in the glibc under /snap/core20. The same thing
happens to WebKit's network process through GIO_MODULE_DIR.
The snap keeps the original values in *_VSCODE_SNAP_ORIG variables, so the clean
fix is to restore them. This works in both bash and zsh, and is safe to keep in your
shell startup file:
while IFS='=' read -r var val; do
name="${var%_VSCODE_SNAP_ORIG}"
if [ -n "$val" ]; then export "$name=$val"; else unset "$name"; fi
done < <(env | grep '_VSCODE_SNAP_ORIG=')For a single run, clearing the two variables at fault is enough:
env -u GTK_PATH -u GIO_MODULE_DIR npm run tauri devFrom a regular system terminal the problem does not occur.
MIT · Copyright © 2026 Omisen
Tanren bundles M PLUS Rounded 1c, subset to the characters the app displays.The font stays under the SIL Open Font License 1.1, whose text ships alongside it in
public/fonts/OFL.txt.
The app carries a Sources and licences screen, a row inside the Settings tab, because these licences ask for attribution
inside the medium the work travels in, and for an app that is the installed APK rather than this page.
The kanji tables are derived from kanjium by Uros O., which builds on EDICT, KANJIDIC and KRADFILE,
the property of the Electronic Dictionary Research and Development Group. Both are used under CC BY-SA 4.0,
which extends to derived data, so those tables carry it too while the code stays MIT.
"The pitch accent notation, verb particle data, phonetics, homonyms and other additions or modifications
to EDICT, KANJIDIC or KRADFILE were provided by Uros O. through his free database."
Details in
crates/core/data/kanji/ATTRIBUTION.md.
🚧 Early stage project, under active development.
