Mode d’emploi
- Copiez la commande et examinez le paquet avant de l’installer dans votre environnement agent.
- Consultez le document original pour les outils, identifiants et environnements requis.
- Décrivez les entrées et le livrable souhaité ; comparez la sortie aux sources.
npx skills add https://github.com/samuadda/rtl-skill --skill rtlAvant de commencer
- L’installation n’inclut ni abonnement au modèle, ni quota API, ni accès aux fichiers.
- Étoiles et installations reflètent l’activité, pas un test indépendant de qualité ou de sécurité.
Rendu depuis le dépôt source en conservant titres, exemples, code, tableaux, liens et images.
RTL Skill — Arabic UI
This skill makes you RTL-first. Not RTL-aware. RTL-first.
Before generating any component, run the Start/End Axis Test:
"Does this element have a start and an end? If yes — it needs a conscious RTL decision."
The Three Categories
Every element in every component falls into one of these:
| Category | Rule | Examples |
|---|---|---|
| Always mirror | Flip in RTL, no exceptions | Layout, flex direction, padding, margin, positioning, chevrons, arrows, progress bars, sliders, breadcrumbs |
| Never mirror | Stay LTR always | Numbers, currency, phone numbers, URLs, code blocks, email addresses, mathematical expressions |
| Context-dependent | Requires judgment | Images with people, decorative illustrations, brand logos |
When in doubt: mirror it. It's easier to un-mirror than to discover it was wrong in production.
Forbidden Workarounds
Violating the letter of these rules is violating the spirit. If you're rationalizing an exception, you're wrong.
Under pressure, agents reach for shortcuts that ship the change without solving the RTL problem. Don't. For each forbidden pattern below, the correct substitute is named — use it.
1. Don't match existing physical-property style "for consistency"
Forbidden:
.card { margin-left: 16px; } /* matches the rest of the file */Do instead: Convert as you go. The codebase migrates one file at a time.
.card { margin-inline-start: 16px; }2. Don't add !important to override RTL bugs
Forbidden:
.sidebar { left: 0 !important; } /* force-pin to "fix" RTL */Do instead: Fix the underlying property.
.sidebar { inset-inline-start: 0; }3. Don't wrap sections in direction: ltr to dodge mirroring decisions
Forbidden:
<section style={{ direction: 'ltr' }}>{/* whole feature */}</section>Do instead: Mark only the specific LTR island — a number, code snippet, or URL.
<p>الرصيد: <span dir="ltr" style={{display: 'inline-block'}}>$1,250.00</span></p>4. Don't use transform: scaleX(-1) on text
Forbidden:
[dir="rtl"] .heading { transform: scaleX(-1); } /* mirrors the glyphs */Do instead: scaleX(-1) is for directional icons only. For layout, use logical properties; for text alignment, use text-align: start/end.
5. Don't manipulate Arabic strings by character index
Forbidden:
const initial = name.charAt(0); // breaks combined letterforms and tashkeelDo instead: Use grapheme-aware APIs.
const initial = [...new Intl.Segmenter('ar', { granularity: 'grapheme' }).segment(name)][0]?.segment;6. Don't set positive letter-spacing on Arabic — ever
Forbidden:
.brand { letter-spacing: 0.05em; } /* "for design reasons" */Do instead: Always 0 on Arabic text. If the design needs visual emphasis, use weight, size, or color — not spacing. Arabic is cursive; spacing breaks letter connections.
.brand { letter-spacing: 0; font-weight: 700; }7. Don't skip root dir="rtl" and set direction per-component
Forbidden:
<html><body>
<Header dir="rtl" /><Main dir="rtl" /><Footer dir="rtl" />
</body></html>Do instead: Set direction once on the root. Per-component dir is reserved for LTR islands inside an RTL document.
<html lang="ar" dir="rtl"><body>
<Header /><Main /><Footer />
</body></html>8. Don't fork a third-party library to flip one icon
Forbidden:
// Copy-paste react-day-picker's source into the repo just to add
// rtl:rotate-180 to one chevron. Now you own the maintenance forever.
import { DayPicker } from './forked/day-picker' // forked from npmDo instead: Use Tailwind's arbitrary-deep variant to flip the descendant from a wrapper you own. No fork, no maintenance burden. See frameworks/tailwind.md → "Arbitrary-deep RTL variants" for the full pattern.
import { DayPicker } from 'react-day-picker' // npm, untouched
<DayPicker className="rtl:**:[.rdp-button_next>svg]:rotate-180
rtl:**:[.rdp-button_previous>svg]:rotate-180" />Commands
See workflows.md for full command definitions.
| Command | Trigger phrases | What it does |
|---|---|---|
/rtl-init | "start an RTL project", "new Arabic app", "setup RTL" | Scaffold a new project with RTL baked in |
/rtl-audit | "audit for RTL", "check RTL issues", "scan this project" | Scan existing code and produce rtl-audit-report.md |
/rtl-convert | "rtlize this", "convert to RTL", "make this RTL" | Convert a specific component to RTL-aware |
/rtl-check | "check this component", "rtl review" | Quick golden checklist pass on a single component |
The Golden Checklist
Run this on every component before considering it done:
□ No physical left/right properties — use logical (inline-start/end)
□ Flex/grid directions explicitly handled for RTL
□ Every icon classified: directional (flip) or neutral (don't flip)
□ Animations respect RTL axis (slide directions, progress fills)
□ Numbers, code, URLs are marked as LTR islands
□ Form inputs: text aligned correctly, labels on correct side
□ letter-spacing: 0 on all Arabic text
□ Line-height: minimum 1.6 on Arabic text
□ dir="rtl" present on root or component wrapper
□ Component mentally tested in both LTR and RTLFramework Detection
Run these checks from the repo root before loading any framework file. Each check is mechanical — no judgment. Multiple checks may pass; load every framework file that matches.
| Framework | Check (any one passes → match) | ||
|---|---|---|---|
| Tailwind | grep -E '"tailwindcss"\s*:' package.json returns a line, OR ls tailwind.config.js tailwind.config.ts tailwind.config.cjs tailwind.config.mjs 2>/dev/null lists any file | ||
| CSS-in-JS | `grep -E '"(styled-components\ | @emotion/react\ | @emotion/styled)"\s*:' package.json` returns a line |
| React Native | grep -E '"react-native"\s*:' package.json returns a line. The dep react-native-web alone does NOT match — it's web-only. Require the bare "react-native": key | ||
| Plain CSS / SCSS | Fallback when none of the above match, OR repo contains .css/.scss/.sass files outside node_modules (`find . -type f \( -name '.css' -o -name '.scss' -o -name '.sass' \) -not -path '/node_modules/*' \ | head -1`) used for non-framework styles |
Concrete decision flow:
- Read
package.jsononce. Cache the dependency list. - Run each check above against that list (and the file checks for Tailwind).
- Build a set of matched frameworks. Load every matching file from
## Framework Rulesbelow. - If the set is empty, default to
frameworks/css.md.
A Next.js + Tailwind + styled-components project loads three files: tailwind.md, css-in-js.md, and css.md (for any unscoped global styles).
Framework Rules
Load the file(s) selected by detection above:
- Tailwind CSS → frameworks/tailwind.md
- Plain CSS / SCSS → frameworks/css.md
- styled-components / emotion / CSS-in-JS → frameworks/css-in-js.md
- React Native → frameworks/react-native.md
Common Mistakes
Before generating, scan anti-patterns.md for patterns to avoid. Especially relevant when working on existing code — most anti-patterns survive code review because nothing fails loudly.
Full Rules Reference
For deep rules on each concern area → reference.md
Covers: Layout, Typography, Components, Icons, Animations, Forms, Data & Tables.

