Smart multi-language RTL support for Cursor AI Chat, Agents Window and Plan files. Uses a purpose-built algorithm that detects text direction per element - Hebrew, Arabic and Persian text is automatically right-aligned, while English text stays left-aligned. Mixed-language conversations just work.
| Before | After |
|---|---|
![]() |
![]() |
| Before | After |
|---|---|
![]() |
![]() |
| Before | After |
|---|---|
![]() |
![]() |
- Smart multi-language algorithm - detects text direction per element using weighted RTL/LTR scoring, so Hebrew, Arabic and Persian content is right-aligned while English-heavy content stays left-aligned
- One-click Enable/Disable via Command Palette
- Status Bar indicator showing current RTL patch state (ON / OFF / UPDATE NEEDED)
- Automatic update detection when Cursor updates overwrite
main.js - Extension update checks with release-page and VSIX download shortcuts
- Auto re-apply option to silently re-apply after Cursor updates
- Markdown table support for mixed RTL/LTR table content, including Plan files
- Plan editor support for Cursor's TipTap/ProseMirror-based
.plan.mdeditor - Agents Window support including the agent conversation and side Plan view
- Transactional patching with automatic backup and rollback on failure
- Cross-platform support for Windows, macOS, and Linux
| Command | Description |
|---|---|
Cursor RTL: Enable RTL Support |
Backup main.js, apply RTL patch, copy the loader script |
Cursor RTL: Disable RTL Support |
Restore main.js from backup, remove the loader script |
Cursor RTL: Check Status |
Show whether the RTL patch is currently active |
Cursor RTL: Re-apply After Update |
Re-apply patch after a Cursor update overwrote it |
Cursor RTL: Check for Extension Updates |
Check GitHub releases for a newer extension version |
- RTL: ON - Patch is active
- RTL: OFF - Patch is not applied
- RTL: UPDATE NEEDED - Cursor was updated, patch needs re-applying
Click the status bar item for a quick-pick menu with available actions.
| Setting | Default | Description |
|---|---|---|
cursorRtl.autoReapply |
false |
Automatically re-apply RTL patch when Cursor updates overwrite main.js |
cursorRtl.showStatusBar |
true |
Show RTL status indicator in the status bar |
cursorRtl.checkForExtensionUpdates |
true |
Automatically check GitHub releases for Cursor RTL extension updates |
cursorRtl.updateCheckIntervalHours |
6 |
How often to check for extension updates while Cursor is open |
cursorRtl.updateRemindLaterHours |
24 |
How long to wait before showing the same update again after choosing Remind Later |
- Download the latest
.vsixfrom the Releases page - In Cursor, press
Ctrl+Shift+Pto open the Command Palette → search forVSIX→ select Extensions: Install from VSIX... → choose the downloaded file - Look for "RTL: OFF" on the right side of the bottom status bar → click it → select Enable RTL
- Approve the installation → close and reopen all Cursor windows
Note: If Cursor is installed in a system directory (e.g.
C:\Program Files), you may need to run Cursor as Administrator for the patch to apply.
This extension modifies two files inside Cursor's app directory:
main.js- A single line is inserted after the copyright comment to load the RTL scriptcursor-rtl-loader.cjs- A small loader is copied alongsidemain.js; it injects the extension's bundledresources/rtl.jsinto Cursor workbench windows
The rtl.js styling and direction script stays in the installed extension directory, so it updates with the extension package.
The loader runs in Cursor's Electron main process. It watches existing and newly-created browser windows, waits until a window has loaded workbench.html, and then injects rtl.js once for that workbench URL.
Inside the workbench, rtl.js does an initial scan at startup, a few delayed startup scans while Cursor finishes rendering, and then re-scans on relevant DOM mutations, focus changes, and visibility changes. It is not a continuous polling loop.
The direction algorithm assigns an explicit dir="rtl" or dir="ltr" to matching Markdown, chat and composer elements. For mixed text, RTL characters are scored against weighted LTR tokens; code-like tokens such as paths, API names and uppercase identifiers count less than regular English words. Lists and tables use the majority direction of their direct items or cells.
Plan files and the Agents Window side Plan view use Cursor's TipTap/ProseMirror rich-text editor. Because that editor owns and may rewrite its DOM, Plan content also gets generated CSS rules scoped to the active Plan editor instead of relying only on direct dir attributes.
- Timestamped backups: Before any modification,
main.jsis backed up asmain.js.rtl-backup-<timestamp> - Signature verification: The extension verifies that
main.jscontains the expected Microsoft copyright comment before patching - Idempotent operations: Enabling when already enabled does nothing; disabling when not enabled does nothing
- Transactional writes: If patching fails mid-way, the backup is automatically restored
- Dry-run preview: Before enabling, you see exactly which files will be modified
To completely undo all changes:
- Run
Cursor RTL: Disable RTL Supportfrom the Command Palette - Restart Cursor
This restores the original main.js from the backup and removes the copied loader script.
- Cursor updates may overwrite
main.js, requiring re-application of the patch - The extension shows a "[Unsupported]" warning in Cursor's title bar (same as any extension that modifies app files, like Custom CSS extensions)
- Requires write permissions to Cursor's app directory (may need Administrator/sudo on some systems)
Compatible with Cursor 2.4.37+ (uses app.on('browser-window-created') pattern).
Visual checks can capture and compare the real Cursor UI for RTL layout regressions:
npm run visual:capture
npm run visual:compareSee visual/README.md for the full workflow and privacy notes.
Cursor RTL collects telemetry for the sole purpose of improving the extension, understanding failures, and maintaining compatibility with Cursor updates. Telemetry is enabled by default.
The extension may send usage events such as extension startup/shutdown, patch apply/remove/reapply, status checks, update detection, and version availability. These events may include diagnostic environment details such as Cursor version, release channel, patch state, platform, architecture, locale, timezone, hostname, OS username, and home directory. The extension does not intentionally send workspace file contents, editor text, or clipboard contents.
Telemetry can be disabled with an advanced environment variable before launching Cursor:
$env:CURSOR_RTL_TELEMETRY_OPTOUT = "1"
& "$env:LOCALAPPDATA\Programs\cursor\Cursor.exe"Persistent opt-out can be configured at the operating system level by setting CURSOR_RTL_TELEMETRY_OPTOUT=1 for the user or machine environment. CURSOR_RTL_DISABLE_TELEMETRY=1 is also supported.
The loader writes a local debug log to cursor-rtl.log in the user's home directory. It is not sent by telemetry, but it may include local extension paths and workbench URLs, so review it before sharing.
| Issue | Solution |
|---|---|
| Permission denied | Windows: Run Cursor as Administrator. macOS/Linux: Fix file permissions with sudo chown |
| RTL not working after Enable | Make sure to restart Cursor after enabling |
| Patch removed after update | Use "Re-apply After Update" or enable cursorRtl.autoReapply setting |
| Cursor won't start | Run "Disable RTL Support" or manually restore main.js from the backup file |
Apache 2.0 - see LICENSE for details.





