npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

miraat

v0.8.0

Published

Find & fix the RTL mistakes AI code tools keep making — for Arabic, Hebrew, Syriac, Thaana, N’Ko & Adlam. AST-verified logical CSS, mirrored Tailwind utilities, an MCP server, and an AI-rules file so your agent stops reintroducing them. (formerly rtlint)

Readme

Miraat (مرآة)

Find & fix the RTL mistakes AI code tools keep making — for every right-to-left script.

Formerly rtlint. Miraat (مرآة) is Arabic for "mirror" — mirroring left↔right is the whole job. The rtlint command and the rtlint_* MCP tools still work as aliases.

AI now writes most of the UI code in the world — and it is quietly, consistently bad at right-to-left. It reaches for ml-4, text-left, padding-right, hard-codes dir="ltr", and never mirrors an icon. It looks fine in English and breaks the moment a real Arabic, Hebrew, Syriac, Thaana, N'Ko or Adlam user opens it.

miraat scans your React / Next / Tailwind / CSS, auto-fixes the mechanical RTL mistakes, flags the ones that need a human eye, and writes an AI-rules file so your agent (Cursor, Claude, Copilot) stops reintroducing them. It's script-aware: physical→logical, dir and mirrored-icon guidance fire for all RTL scripts, while script-specific checks (like Western digits in a native-numeral script) fire only where they're actually wrong — Arabic/Thaana/N'Ko/Adlam carry their own numerals; Hebrew and Syriac use Western digits, so those are never falsely flagged.

npx miraat .            # scan and report
npx miraat . --fix      # apply the safe fixes (physical → logical)
npx miraat . --check    # report only, exit non-zero if anything is found (CI)
npx miraat . --dry-run  # show what --fix would change, but write nothing
npx miraat . --init-rules   # write RTL-RULES.md for your AI agent

Runs straight from the repo, no install: npx github:Otto-OttoSpace/miraat . --fix

Zero-corruption by design

miraat parses your code with a real AST (Babel for JS/TS/JSX/TSX, PostCSS for CSS) — it does not regex over raw text. Only high-confidence, mechanically-safe edits are auto-applied, and they're written as surgical splices into the original source, so formatting is preserved to the byte. Custom class names (left-sidebar, pl-PL), CSS selectors/comments/custom-properties, and JS identifiers/params/types that merely look physical are never touched. Everything ambiguous is reported, never rewritten. Re-running --fix is always a no-op.

Every RTL script, not just Arabic

miraat carries a Unicode scripts table (lib/scripts.js) so it reasons about each right-to-left script correctly instead of hard-coding Arabic:

| Script | dir | Own numerals? | Western digits flagged? | |--------|-----|---------------|--------------------------| | Arabic, N'Ko, Adlam, Thaana | rtl | yes | yes — use native / locale-aware numerals | | Hebrew, Syriac | rtl | no (use Western) | no — never falsely flagged |

Physical→logical, dir handling and mirrored-icon flags apply to all of them; the numeral check keys off the table so it only fires where a script has its own digits.

What it catches

| # | Pattern | miraat | |---|---------|--------| | 1 | Physical CSS (margin-left, padding-right, border-left, text-align: left) | auto-fix → logical (margin-inline-start, …) | | 2 | Physical Tailwind (ml-, pr-, left-, text-right, rounded-l, border-r) — incl. inside cn()/clsx()/cva() | auto-fix → logical (ms-, pe-, start-, text-end, rounded-s, border-e) | | 3 | Hard-coded dir="ltr" / dir={"ltr"} / direction: "ltr" / setAttribute('dir','ltr') (and "rtl") | flag — make it dynamic | | 4 | Un-mirrored directional icons (ChevronLeft, BsChevronLeft, ArrowLeftIcon, MdKeyboardArrowRight, …) | flag — mirror for RTL | | 5 | Inline JS physical styles (marginLeft, textAlign: 'left', el.style.marginLeft = …) | auto-fix → logical | | 6 | Script-blind font stacks (no RTL-capable fallback) | flag — add a script-capable font | | 7 | Western numerals inside a native-numeral RTL script (السعر 1234 درهم) | flag — use native / locale-aware numerals |

Before → after

- <div dir="ltr" className="ml-4 pr-2 text-left border-l rounded-l-lg">
+ <div dir="ltr" className="ms-4 pe-2 text-start border-s rounded-s-lg">
- margin-left: 16px; padding-right: 8px; text-align: left;
+ margin-inline-start: 16px; padding-inline-end: 8px; text-align: start;

Why the flags aren't auto-fixed

The mechanical half of RTL — logical properties, mirrored utilities — is now commodity (shadcn and Tailwind ship it). miraat gives you that for free. But the half that actually makes an RTL script feel right — mirroring the correct icons, typographic scale and font pairing per script, bidi edge-cases, native numerals, cultural correctness — takes native judgment. miraat flags those; it doesn't guess. That judgment is a service, not a regex — see the roadmap.

Use it in your AI agent (MCP)

miraat ships an MCP server, so Cursor / Claude / Windsurf can call it while they write code — the bug never ships:

{
  "mcpServers": {
    "miraat": { "command": "npx", "args": ["-y", "-p", "github:Otto-OttoSpace/miraat", "miraat-mcp"] }
  }
}

Tools: miraat_scan (scan a path) and miraat_check_code (send a snippet → get the fixed code back). The rtlint_* and legacy rtl_* tool names still resolve to the same handlers.

Use it in CI (GitHub Action)

- uses: Otto-OttoSpace/miraat@main
  with:
    path: .
    # fix: true   # optionally apply fixes

Roadmap → Miraat Pro

  • Hosted audit — paste a repo or URL, get a full Arabic-RTL report + fixes (a designer-in-the-loop pass, not just the mechanical ones).
  • CI GitHub Action — fail the PR when new physical RTL bugs land.
  • Arabic design layer — drop-in typography / font-pairing / numeral / bidi tokens that are actually correct.

Author

Built by an Arabic-RTL Design Engineer — Western-quality product design + RTL-correct code, in Arabic, French & English. The free handbook "Arabic-RTL for the AI era" is the companion to this tool.

MIT © 2026

💛 Support & commercial use

The Miraat suite is free and open-source (MIT). If it helps you ship correct Arabic/RTL, please consider sponsoring on GitHub — it funds maintenance and new rules.

Using it in a commercial product, in CI, or need the private DGA compliance rule pack? A Miraat Pro commercial licence — commercial use, a hosted CI audit that gates PRs (miraat-action), and priority support — is available. Email [email protected] and we'll set you up.