feat: i18n / localization support for TUI strings instead of hardcoded English
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 19.9k
- Forks
- 2.3k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 30
Description
Problem
All TUI interface strings in jcode are hardcoded as English &'static str literals directly in Rust source code. This includes:
- Header labels: model name, provider, status indicators
- Picker column headers: MODEL, PROVIDER, METHOD, ACCOUNT, STATE, TARGET, CONFIG, ITEM, STATUS, WINDOW
- Status messages: "Thinking...", "Streaming", "Sending...", "Idle", "Running tool: ..."
- Onboarding screens: welcome text, login prompts, suggestion cards
- Keybinding hints: "↵ open", "↵ select", "↑↓ ←→ ↵ Esc"
- Tool display labels: format strings for tool calls, batch progress, caching warnings
- Many more across ~30 UI files (30K+ lines) in
crates/jcode-tui/src/tui/
There is no locale detection, no translation system, and no config option to switch the UI language. This makes jcode less accessible to non-English-speaking users.
Suggested Solution
Add an optional i18n layer to the TUI so that UI strings can be localized without modifying source code:
Approach (fluent-rs)
Use the fluent-rs ecosystem (the Rust implementation of Mozilla's Fluent localization system), which is well-suited for a Rust TUI:
- Add
fluent-rs/unic-langiddependencies tojcode-config-types(for the config field) andjcode-tui(for string resolution) - Add
language = "..."field to[display]inconfig.toml(default:"en-US") - Extract hardcoded strings into
.ftl(Fluent) files under e.g.locales/en-US/tui.ftlandlocales/zh-CN/tui.ftl - Replace
"LABEL"witht!("label")calls throughoutjcode-tui/src/tui/ - Bundle locale files at compile time via
include_str!orfluent-template, so no runtime file discovery is needed
Minimal first step
A minimal PR could:
- Add the config field and
fluent-bundledependency - Extract just the most visible strings (~50-100 labels: column headers, status lines, onboarding text, keybinding hints)
- Ship
en-US.ftl(identical to current hardcoded text) andzh-CN.ftl - Leave the remaining strings for follow-up PRs
This gives an incremental path: every new feature adds its strings to the .ftl file instead of hardcoding, and over time the entire TUI becomes localizable.
Alternative: rust-i18n crate
rust-i18n is a simpler macro-based approach with automatic extraction. It uses YAML files and a t!() macro. Less powerful than Fluent but easier to get started with.
Why a plugin won't work
jcode has no plugin/dynamic-loading system (no WASM, no dlopen, no libloading). An i18n solution must therefore be built into the core codebase rather than shipped as an external plugin.
Benefits
- Enables community-contributed translations (Chinese, Japanese, Korean, etc.)
- Makes jcode more accessible globally
- Separates UI text from logic (better engineering practice)
- Opens the door for right-to-left (RTL) language support later
Issue inspired by a user who wanted to use jcode with a Chinese-language TUI.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the configuration types in jcode-config-types and the UI entry points under crates/jcode-tui/src/tui/. Inventory the highest-visibility strings named in the issue and compare Fluent with the rust-i18n alternative before choosing an approach. Done should include a language config field, bundled en-US and zh-CN resources, and localized labels, status lines, onboarding text, and keybinding hints.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, localization
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100