Japanese study companion
  • Rust 61%
  • Swift 19.9%
  • TypeScript 14.3%
  • C 3.3%
  • CSS 1.3%
  • Other 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-12 12:00:00 -04:00
.cargo feat(sync): initial impl 2026-10-12 12:00:00 -04:00
apps feat(srv): initial impl 2026-10-12 12:00:00 -04:00
bind feat(sync): initial impl 2026-10-12 12:00:00 -04:00
core feat(sync): initial impl 2026-10-12 12:00:00 -04:00
crates feat(cli): initial impl 2026-08-30 12:00:00 -04:00
data/src feat: initial impl 2026-08-30 12:00:00 -04:00
extras/dir feat(cli): initial impl 2026-08-30 12:00:00 -04:00
lib/gogaku feat(sync): initial impl 2026-10-12 12:00:00 -04:00
sql feat(srv): initial impl 2026-10-12 12:00:00 -04:00
src feat(sync): initial impl 2026-10-12 12:00:00 -04:00
tests feat(sync): initial impl 2026-10-12 12:00:00 -04:00
xtask feat(web): initial impl 2026-08-30 12:00:00 -04:00
.gitignore chore(git): create .gitignore 2026-05-31 17:00:00 -04:00
.swift-format feat(lib): initial impl 2026-08-30 12:00:00 -04:00
build.rs feat(sync): initial impl 2026-10-12 12:00:00 -04:00
bun.lock feat(web): initial impl 2026-08-30 12:00:00 -04:00
Cargo.lock feat(srv): initial impl 2026-10-12 12:00:00 -04:00
Cargo.toml feat(srv): initial impl 2026-10-12 12:00:00 -04:00
clippy.toml build(cargo): init 2026-08-30 12:00:00 -04:00
LICENSE-APACHE chore(license): initial release 2026-05-31 17:00:00 -04:00
LICENSE-MIT chore(license): initial release 2026-05-31 17:00:00 -04:00
package.json feat(web): initial impl 2026-08-30 12:00:00 -04:00
PRIVACY.md feat(srv): initial impl 2026-10-12 12:00:00 -04:00
README.md feat(srv): initial impl 2026-10-12 12:00:00 -04:00
rust-toolchain.toml feat(sync): initial impl 2026-10-12 12:00:00 -04:00
rustfmt.toml build(cargo): init 2026-08-30 12:00:00 -04:00

Gogaku

Japanese study companion.

Important

Consider this to be pre-alpha software. I make no guarantee of the stability of any documented APIs until the first official release.

Goal

This project aims to provide a fast, offline-first iOS experience for studying Japanese. Vocabulary lookup is powered by the standard community dictionaries (JMdict, KANJIDIC2, and friends), scheduling runs through the FSRS-6 algorithm, and the interface gradually shifts from English to Japanese as the user's vocabulary matures. Anything the user produces stays portable: cards, their scheduling, the review log and the settings are one SQLite file every frontend reads, which copies out as a backup and back in on another device.

Organization

The project is partitioned into the top-level gogaku Rust library, the SwiftUI app for iOS and macOS, and the Swift bindings that bridge the two over the C ABI. A command-line frontend lives alongside as a workspace peer.

Workspace

Cargo (Rust's package manager) manages a workspace of several crates, specified within its manifest. The iOS app is consumed as an Xcode project under apps/ios/ that depends on the Swift package in bind/swift/, which links the C ABI in lib/gogaku/.

./
├── Cargo.lock           # cargo lockfile
├── Cargo.toml           # cargo manifest
├── LICENSE-APACHE       # apache 2.0 license
├── LICENSE-MIT          # mit license
├── PRIVACY.md           # privacy policy
├── README.md            # this document
├── apps/                # frontend apps
│  ├── cli/              # command-line app
│  ├── ios/              # SwiftUI iOS and macOS app
│  ├── srv/              # sync server
│  └── web/              # browser app
├── bind/                # language bindings
│  ├── swift/            # Swift package
│  └── wasm/             # WebAssembly bindings
├── core/                # core library crates
│  ├── dict/             # dictionaries and packs
│  ├── fsrs/             # FSRS scheduling
│  ├── grammar/          # Japanese conjugation
│  └── text/             # Japanese scripts
├── crates/              # supporting crates
├── data/                # vendored source data
├── extras/              # extra crates
│  └── dir/              # standard directories
├── lib/                 # foreign function interfaces
│  └── gogaku/           # C ABI
├── sql/                 # database schema
├── src/                 # top-level gogaku library
└── xtask/               # build tasks

Modules

Main components of gogaku are outlined below.

  • gogaku: top-level library that manages dictionary data and review state. pack is the container every lookup reads, memory-mapped where there is a filesystem. dict holds the records and the views that read them, one module per upstream source behind those, and dict::pkg, which builds packs, and downloads their sources behind the optional http feature. find is the search engine over them, and base is the study state behind the optional base feature: table holds a module per table, and study runs study sessions over them. base::sync keeps a base in step with a server, behind the optional sync feature, which implies base. deck shares decks (word lists) as files, and makes decks from the charts. Moving a deck in and out of a base needs the base feature, and the rest does not.

Core

  • gogaku-dict: dictionary records and the packs that hold them, re-exported by gogaku as dict and pack.
  • gogaku-fsrs: FSRS scheduling, checked against Anki and against the FSRS crate the model was transcribed from, re-exported by gogaku as fsrs.
  • gogaku-grammar: Japanese conjugation, re-exported by gogaku as text::form.
  • gogaku-text: Japanese scripts and word forms, re-exported by gogaku as text.

Frontends

  • gogaku-cli: a command-line interface for dictionary lookup, charts, study, and settings.
  • gogaku-ios: a native iOS and macOS application built with SwiftUI.
  • gogaku-web: a browser application, served as static files.

Bindings

  • libgogaku: the C ABI for the Swift bindings.
  • GogakuKit: Swift package wrapping that ABI.
  • gogaku-wasm: WebAssembly bindings, dictionaries and database.

Extras

  • gogaku-dir: standard directories for the base and the packs, shared by the frontends on a desktop.

Supporting

  • bfmt: human-readable byte size formatting and parsing.
  • rune: visual fingerprints for identifiers.
  • tui: terminal screens in an inline viewport.
  • tests: integration tests of the gogaku library.
  • xtask: build tasks, run as cargo xtask. cargo xtask pack builds the packs the browser app serves.

Testing

Rust unit tests live alongside each crate's source and run via cargo test --workspace. The browser app's tests run with bun run test from apps/web.

Credits

Gogaku would not be possible without the community dictionaries it depends on. The dictionary files are fetched on-device from upstream.

Dictionaries

These files are the property of the Electronic Dictionary Research and Development Group, and are used in conformance with the Group's license. They are made available under the Creative Commons Attribution-ShareAlike 4.0 license. The files are converted into Gogaku's own format, which reorders and indexes them for search. Entries are otherwise unchanged.

JLPT kanji levels are from the JLPT kanji lists by Jonathan Waller, licensed under Creative Commons Attribution.

Examples

Example sentences in JMdict are from the Tatoeba project, licensed under Creative Commons Attribution 2.0 France.

Privacy

The project does not collect or transmit any data. Any data used by the project remains solely on your device.

See the Privacy Policy for full details.

License

This project is dual-licensed under both the MIT License and the Apache License 2.0. You have permission to use this code under the conditions of either license pursuant to the rights granted by the chosen license.