Skip to content
Development
Skill

/mobile-accessibility

Make a mobile app driveable AND auditable through the accessibility tree, the shared dependency behind every tap-by-label interaction. One tree, two consumers reading different fields: driving reads the stable handle (testID -> accessibilityIdentifier); auditing reads the

From plugin
simiancraft-skills
823 skills4 agents

Claude Code

$ npx -y skills add simiancraft/simiancraft-skills --skill mobile-accessibility --agent claude-code

SKILL.md

mobile-accessibility.SKILL.md
name: mobile-accessibility
description: >-
  Make a mobile app driveable AND auditable through the accessibility tree, the
  shared dependency behind every tap-by-label interaction. One tree, two consumers
  reading different fields: driving reads the stable handle (testID ->
  accessibilityIdentifier); auditing reads the user-facing semantics (label, role,
  state, focus order). Covers iOS-native (UIAccessibility) and React Native / Expo
  (accessibilityLabel/role/state/accessible + testID) and how RN maps to the native
  tree. Prefer accessibility over coordinates. Referenced by ios-simulator and
  expo-ios-simulator for driving, and by the auditing skills for completeness.
status: complete
sources:
  - https://reactnative.dev/docs/accessibility (the React Native accessibility props)
  - https://reactnative.dev/docs/view (testID: "Used to locate this view in end-to-end tests")
  - https://developer.apple.com/documentation/uikit/uiaccessibilityidentification/accessibilityidentifier (the automation handle, distinct from the label)
  - https://developer.apple.com/documentation/uikit/uiaccessibilityelement/accessibilitylabel (the user-facing name)

Mobile Accessibility (the shared trunk)

Why its own skill: the same tags serve two consumers (driving vs auditing); owning them here keeps both DRY. Driving skills read the handle; auditing skills read the semantics.

The model: one tree, two readers

An accessible app exposes an **accessibility tree**: a hierarchy of elements that assistive technology (VoiceOver) navigates, and that an automation driver (AXe) reads to find and tap things. Every element can carry a few fields. Two of them matter most, and they exist for **different** reasons:

| Field (iOS) | React Native prop | Who reads it | What it is for | |---|---|---|---| | `accessibilityIdentifier` | `testID` | the **driver** | a stable **handle** to find an element in a script | | `accessibilityLabel` | `accessibilityLabel` | the **human** (VoiceOver) and the **auditor** | the element's **name**, spoken aloud |

Apple draws this line itself: an identifier lets a script *"uniquely identify an element"* and thereby *"avoid inappropriately setting or accessing an element's accessibility label"* (`accessibilityIdentifier` docs). React Native's `testID` is the same idea from the other side: *"Used to locate this view in end-to-end tests."* The label, by contrast, is *"a string that succinctly identifies the accessibility element"* for a user; Apple's example is "Save," not "Save button."

So:

  • **Driving** wants the handle. Prefer `testID` -> `accessibilityIdentifier`; it does not

change when copy, locale, or layout changes. Tapping by visible label is the fallback when no handle exists. Coordinates are the last resort (brittle; see **ios-simulator** `references/driving.md`).

  • **Auditing** wants the semantics: is there a label at all, is the role right, is the

state (disabled, selected, checked) correct, is the focus order sane.

Where to go

  • iOS-native fields and how they surface to a driver: `references/ios-native.md`.
  • React Native / Expo props and the RN -> native mapping: `references/react-native-expo.md`.
  • The auditing lens (completeness, correctness): `references/auditing.md`.

Rules

  • Prefer the **handle** (`testID`) for driving; fall back to the label; avoid coordinates.
  • A label names; an identifier handles. Do not overload one for the other (Apple's own warning).
  • Every factual claim here and in the references cites a primary source (Apple, React

Native, or AXe's own help); a prior-art skill is never a source.

Out of scope

Web a11y -> future web-accessibility. Cross-platform auditing -> future accessibility. Android specifics -> android-emulator-harness lineage.

Read more
@simiancraft
Ships withsimiancraft-skills

Claude Code skills for the full arc of a change: farm to table, with receipts. Curated Claude Code skills and agents from simiancraft. Most skill collections are grab bags. This one has a spine: it carries a change through its whole life.

823 skills4 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
8
Star history of simiancraft/simiancraft-skills on GitHub, a chart by star-history.com

Other skills on simiancraft-skills.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about mobile-accessibility.

Which coding agents can use mobile-accessibility?
mobile-accessibility installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.