Interface·terminal·MIT
rtl-text
Persian, Arabic and Hebrew drawn joined, right-to-left and flush right in the transcript.

rtl-text makes Persian, Arabic and Hebrew readable in the Claude Code transcript. Most terminals do no bidi reordering and no Arabic shaping, so a Persian reply arrives backwards with its letters unjoined. The mod runs each right-to-left line through fribidi before Claude Code draws it, and the row comes out with the letters joined, the words in right-to-left order and the paragraph flush against the right edge. It draws locally and costs zero tokens.

Install
Needs Claude Code 2.1.287 or later, plus the fribidi command-line tool (brew install fribidi on macOS, apt install fribidi on Debian and Ubuntu), a monospace font that covers the Arabic Presentation Forms block, and a terminal that does not run its own bidi pass. The author declares no minimum Claude Code version and tested the mod on 2.1.271 through 2.1.273.
claude plugin marketplace add aliir74/claude-code-rtl
claude plugin install rtl-text@claude-code-rtl
Start claude and write in Persian, Arabic or Hebrew. There is no command: every transcript row that contains right-to-left text is reshaped as it is drawn. claude plugin update rtl-text picks up later releases.
How it works
The module hooks ui.render for four components. Claude’s replies and your own messages are treated as markdown. The output of slash commands and the result of Bash tool calls are treated as plain text. Any other component, including the results of other tools, is left to Claude Code. Like claude-mermaid, it rewrites rows of the transcript instead of drawing in the band above the prompt.
A row is only touched when it contains at least one Arabic-script or Hebrew-script letter. Digits alone do not count, so a line of Persian numerals stays as it is, and an all-Latin message takes a fast path straight back to the engine. Each line’s base direction follows the first letter in it: a line that opens with Persian is right-to-left, a line that opens with Latin is left-to-right. Latin runs inside a Persian sentence keep their own direction, because fribidi resolves the mix. With the default alignment of auto, only lines whose own direction is right-to-left are padded to the right edge; right pads every line and left shapes without padding.
Code is never reordered. Fenced and indented code blocks are handed to the terminal’s Code element untouched. Inline code spans and URLs are lifted out of the line as placeholders before shaping and put back afterwards, so a command inside a Persian sentence stays exactly as Claude wrote it. Since version 0.3.1 only the markers of a bold or italic span are lifted, so the text inside is shaped with the rest of the line; before that fix a bold Persian heading came out backwards. Bullets, headings and blockquote markers stay at the start of the line, and table cells are shaped one by one so the pipes keep their columns.
fribidi is run as an external binary through the hooks runtime’s process API, not as a native library or a WASM build. The text is wrapped to the viewport width in logical order first, and the finished lines of a whole message go to one fribidi subprocess per base direction, never one call per line. On the first render the mod probes fribidi --version at the configured path and then in the usual Homebrew, /usr/local, /usr and MacPorts prefixes. After three failed probes it switches shaping off for the session and logs one line in the transcript saying why each candidate failed. A call that runs past timeoutMs (2,000 ms by default) or any other error falls back to the engine’s own row, so a failure looks like the mod not being installed.
The mod reads only the text of the rows it draws. It makes no network calls, asks the model nothing and writes nothing to disk. Shaped messages are kept in an in-memory cache of 256 entries per session, because render hooks re-run on every redraw and resize. Six options live in the plugin’s config: alignment, fribidiPath, margin, cacheSize, timeoutMs and replyBullet, the marker the mod redraws on the opening line of a reply, on the right edge when the reply is right-to-left.
Limitations
- The prompt box is not covered. Typing Persian into the composer still comes out broken. The input is not a render component, so no mod can reach it; only a terminal with real bidi fixes that.
- Terminals with their own bidi undo the mod. The text is emitted already reordered, so a terminal that runs UAX #9 itself reorders it a second time. Ghostty is the only tested terminal. The author expects kitty, Alacritty, foot, Windows Terminal and the VS Code terminal to work, iTerm2 only with its experimental RTL off, and WezTerm only with
bidi_enabled = false(its default). macOS Terminal.app, GNOME Terminal and other VTE terminals, Konsole and mlterm do their own bidi: the mod is not needed there and would make things worse. - Copied text is in visual order. What is on screen is what you copy, in presentation forms, so it will not paste cleanly into an editor that expects logical order.
- The font matters. A proportional Persian face in a terminal grid pulls the letters apart. The README recommends Vazir Code Hack, with the lam-alef ligature forms filled from Vazirmatn, and warns against a proportional face as a plain fallback because it takes over the Latin glyphs too.
- A Bash result too large to show inline, which Claude Code saves to a file, is left alone rather than drawn as if the visible part were the whole output. Terminal only: any other surface goes back to the engine.
Similar Claude Mods
firstmate-calm
Hides tool rows and swaps the spinner for a sailboat. Toggle with /calm, zero tokens.
prompt-rail
Your session's prompts as a rail: hover to read one, click to jump back to it.
glass
The transcript redrawn like a desktop app: colored commands, a tool tree, code cards.
aside
Ask about the session so far in a read-only side pane. Nothing reaches the main thread.
Popular Claude Mods
The whole directory →claude-carbon
Estimated grams of CO2 for each answer and session, with a molecule and warming stripes.
effortless
Picks the effort for every prompt and shows how long the prompt cache stays warm.
claude-pokemon
A pixel Pokémon above the prompt that follows Claude's tools, levels up and evolves.
multi-core
ChatGPT, Cursor, Zen, Antigravity and Grok models in one Claude Code session, via /model.





