React Native Best Practices
vercel-labs/openreview
A prioritized rule set for React Native and Expo apps covering list performance, animation, navigation, UI patterns, state, rendering, monorepos and configuration.
Query and analyze Metro's perfetto compiler traces to find real hot spots and untraced time.
$ npx skills add ZacSweers/metro --skill analyze-perfetto-trace -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install ZacSweers/metro analyze-perfetto-trace --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/ZacSweers/metro.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/analyze-perfetto-trace .claude/skills/analyze-perfetto-trace && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "analyze-perfetto-trace" agent skill from https://github.com/ZacSweers/metro/tree/main/.agents/skills/analyze-perfetto-trace into .claude/skills/analyze-perfetto-trace/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "analyze-perfetto-trace", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/ZacSweers/metro/tree/main/.agents/skills/analyze-perfetto-traceType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add ZacSweers/metro --skill analyze-perfetto-trace -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install ZacSweers/metro analyze-perfetto-trace --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ZacSweers/metro.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/analyze-perfetto-trace .agents/skills/analyze-perfetto-trace && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "analyze-perfetto-trace" agent skill from https://github.com/ZacSweers/metro/tree/main/.agents/skills/analyze-perfetto-trace into .agents/skills/analyze-perfetto-trace/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "analyze-perfetto-trace", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ZacSweers/metro --skill analyze-perfetto-trace -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install ZacSweers/metro analyze-perfetto-trace --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ZacSweers/metro.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/analyze-perfetto-trace .cursor/skills/analyze-perfetto-trace && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "analyze-perfetto-trace" agent skill from https://github.com/ZacSweers/metro/tree/main/.agents/skills/analyze-perfetto-trace into .cursor/skills/analyze-perfetto-trace/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "analyze-perfetto-trace", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/ZacSweers/metro.git --path .agents/skills/analyze-perfetto-trace--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add ZacSweers/metro --skill analyze-perfetto-trace -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install ZacSweers/metro analyze-perfetto-trace --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ZacSweers/metro.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/analyze-perfetto-trace .gemini/skills/analyze-perfetto-trace && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "analyze-perfetto-trace" agent skill from https://github.com/ZacSweers/metro/tree/main/.agents/skills/analyze-perfetto-trace into .gemini/skills/analyze-perfetto-trace/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "analyze-perfetto-trace", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install ZacSweers/metro analyze-perfetto-traceInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add ZacSweers/metro --skill analyze-perfetto-trace -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/ZacSweers/metro.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/analyze-perfetto-trace .github/skills/analyze-perfetto-trace && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "analyze-perfetto-trace" agent skill from https://github.com/ZacSweers/metro/tree/main/.agents/skills/analyze-perfetto-trace into .github/skills/analyze-perfetto-trace/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "analyze-perfetto-trace", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ZacSweers/metro --skill analyze-perfetto-trace -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install ZacSweers/metro analyze-perfetto-trace --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ZacSweers/metro.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/analyze-perfetto-trace .opencode/skills/analyze-perfetto-trace && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "analyze-perfetto-trace" agent skill from https://github.com/ZacSweers/metro/tree/main/.agents/skills/analyze-perfetto-trace into .opencode/skills/analyze-perfetto-trace/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "analyze-perfetto-trace", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
analyze-perfetto-traceQuery and analyze Metro's perfetto compiler traces to find real hot spots and untraced time.
Analyze Perfetto Trace is an agent skill from ZacSweers/metro. Query and analyze Metro's perfetto compiler traces to find real hot spots and untraced time. Use whenever the user asks about metro compile-time perf, where time is going in a trace, or shares a perfetto screenshot.
Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Mobile. The repository describes itself as: A multiplatform, compile-time dependency injection framework for Kotlin. The licence is Apache-2.0.
6 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit ba2f45f. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
python3pipbrewFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use pip, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Analyze Perfetto Trace loads about 2.7k tokens when it runs. Until then it costs about 60 tokens; SKILL.md has 1,128 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from ZacSweers/metro at commit ba2f45f, republished under its Apache-2.0 licence (© ZacSweers). 1,128 words, ~2,674 tokens.
.claude/skills/analyze-perfetto-trace/SKILL.md (or your agent's skills folder)..perfetto-trace) or a perfetto UI screenshot.Metro writes perfetto traces into the configured traceDestination directory. As of the FIR + IR tracing rework, one compilation produces multiple files — one per FIR session and one per IR module fragment — all sharing a common id prefix:
<traceDestination>/<id>-<phase>-<moduleName>.perfetto-trace<id> is a yyMMdd-HHmmss timestamp generated once per compilation. Every file from the same compilation invocation shares it, so you can group them by prefix.<phase> is fir or ir.<moduleName> is the FIR session name (commonMain, jvmMain, etc.) or the IR IrModuleFragment.name (often main). Filesystem-unsafe characters in module names are replaced with _.Examples: 260505-133503-fir-commonMain.perfetto-trace, 260505-133503-ir-main.perfetto-trace.
When asked "look at the trace", first decide which phase the user is asking about. FIR-side time (checkers, generators, supertype computation) lives in the fir-* files; IR-side time (graph processing, transformers) lives in the ir-* files. They are separate timelines — not a unified trace — so you cannot directly compare durations across files. If multiple older invocations exist in the directory, pick the freshest <id> group unless the user points at a specific file.
Use ./metrow trace (or the underlying scripts/trace-project.sh directly). It publishes Metro to mavenLocal, bumps the target project's metro version in gradle/libs.versions.toml, runs the given compile task with -Pmetro.traceDestination=metro/trace --rerun, locates the freshest .perfetto-trace (variant subdir varies by task), and copies it into tmp/traces/<timestamp>-<version>_<task>.perfetto-trace. The path is also written to tmp/traces/LATEST so you can chain with TRACE=$(cat tmp/traces/LATEST) in analysis.
./metrow trace <project-dir> <gradle-task> [version]
./metrow trace ~/dev/android/personal/CatchUp :app-scaffold:compileDebugKotlinPass --open-in-browser (or --open) to additionally launch the trace in ui.perfetto.dev — the script fetches Google's open_trace_in_ui helper once (cached at tmp/open_trace_in_ui) and fires it in the background so the UI can keep streaming the file:
./metrow trace --open-in-browser ~/dev/android/personal/CatchUp :app-scaffold:compileDebugKotlinEquivalent direct call:
scripts/trace-project.sh [--open-in-browser] <project-dir> <gradle-task> [version]Use this when the user asks for a "fresh trace" / "re-profile" / has just made a Metro change they want profiled against a real-world project.
For raw-perf iteration on a large generated project (no external repo needed), use benchmark/trace_compile.sh. It runs gradle-profiler against a fresh :app:component:compileKotlin --rerun of the benchmark project, with Metro's perfetto tracing enabled, and picks the iteration whose duration is closest to the measured-mean — so a single representative trace lands in tmp/traces/ (and tmp/traces/LATEST is updated).
benchmark/trace_compile.sh # run + pick + copy
benchmark/trace_compile.sh --open-in-browser # also open in ui.perfetto.dev
TRACE=$(cat tmp/traces/LATEST) # chain into analysisPrereqs: the benchmark project must be generated for metro mode (cd benchmark && kotlin generate-projects.main.kts --mode metro). gradle-profiler is auto-installed on first run. Use this for "raw compile perf on a 500-module project" iteration loops where you don't need a real-world app like CatchUp.
Use the perfetto python library. It's available via pip but installed against a specific python — on this machine it's Python 3.13, not the default 3.14:
/opt/homebrew/opt/python@3.13/bin/python3.13 -c "from perfetto.trace_processor import TraceProcessor; print('ok')"If python3 -c "import perfetto.trace_processor" fails with ModuleNotFoundError, switch to the 3.13 binary above. pip install perfetto installs against whatever python3 on PATH points to, which may not be the one actually invoked.
Do not try brew install perfetto — there is no homebrew cask/formula for it.
Always wrap the Python in a single -c invocation so it stays self-contained. The boilerplate:
/opt/homebrew/opt/python@3.13/bin/python3.13 -c "
from perfetto.trace_processor import TraceProcessor
tp = TraceProcessor(trace='<ABSOLUTE_PATH>')
r = list(tp.query('''
<SQL>
'''))
for row in r:
print(f'{row.dur/1e6:6.2f}ms {row.name}')
tp.close()
"Notes:
trace= must be an absolute path.dur is in nanoseconds — divide by 1e6 for ms.tp.query() returns a rows iterator; wrap in list() if you'll iterate more than once.tp.close() at the end.slice tableThat's the one you'll use 95% of the time. Relevant columns:
| column | meaning |
|---|---|
id | slice id (primary key) |
name | trace span name (e.g. "Build GraphNode") |
dur | duration in nanoseconds |
parent_id | parent slice id (or NULL at top level) |
ts | start timestamp (nanoseconds since trace start) |
SELECT name, dur FROM slice ORDER BY dur DESC LIMIT 30Gives an ordered view of the biggest spans. Start here.
SELECT name, SUM(dur) AS total_dur, COUNT(*) AS cnt
FROM slice GROUP BY name ORDER BY total_dur DESC LIMIT 30Useful for per-class spans like "Visit X" that fire hundreds of times.
WITH parent AS (SELECT id FROM slice WHERE name = 'Build binding graph' LIMIT 1)
SELECT name, dur FROM slice
WHERE parent_id = (SELECT id FROM parent)
ORDER BY dur DESCThis is the most important query for finding gaps. Compare the summed children to the parent duration:
total_child = sum(row.dur for row in r)
print(f'children sum: {total_child/1e6:.2f}ms parent: <parent dur>ms gap: <diff>ms')A large gap means there's untraced work inside the parent. That's where to add instrumentation or investigate.
SELECT name, dur FROM slice
WHERE parent_id = (SELECT id FROM slice WHERE name = 'Core transformers' LIMIT 1)
AND dur > 1e6 -- >1ms
ORDER BY dur DESCSELECT name, dur FROM slice ORDER BY dur DESC LIMIT 1If you want "all time spent under parent X including grandchildren":
WITH RECURSIVE descendants(id) AS (
SELECT id FROM slice WHERE name = 'Core transformers'
UNION
SELECT s.id FROM slice s JOIN descendants d ON s.parent_id = d.id
)
SELECT SUM(dur) FROM slice WHERE id IN (SELECT id FROM descendants)Note: summing descendants double-counts time (parent dur already includes children). Use this for "total CPU in this subtree" questions, not for gap math.
This is the workflow you'll use most often when someone says "X looks slow but it's a black box":
SELECT dur FROM slice WHERE name = '<phase>' LIMIT 1.durs.trace("...") blocks in that phase, and add trace("...") around them.Worked example: on a 161ms catchup build, "Build binding graph" was 11.3ms but direct children summed to 4.2ms. The 7ms gap was construction of BindingLookup/IrBindingGraph/IrBindingStack at the top of generate(), which had no trace. Wrapping that in trace("Construct lookup & graph") surfaced it.
"Metro compiler").cnt in the sum-by-name query tells you whether to optimize per-call work (high cnt, small per-call) or one-shot cost (cnt=1, big dur).name = X?SELECT dur FROM slice WHERE name = '<name>' ORDER BY dur DESC LIMIT 5Get the id first (SELECT id FROM slice WHERE name = '<name>' ORDER BY dur DESC LIMIT 1), then:
SELECT name, dur FROM slice WHERE parent_id = <id> ORDER BY dur DESCSELECT thread.name, SUM(slice.dur) AS total
FROM slice JOIN thread_track ON slice.track_id = thread_track.id
JOIN thread ON thread_track.utid = thread.utid
GROUP BY thread.name ORDER BY total DESC© ZacSweers, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/analyze-perfetto-trace of ZacSweers/metro.
Open the folder on GitHubat commit ba2f45f
Analyze Perfetto Trace next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Analyze Perfetto Trace this skillZacSweers/metro | 1.4k | — | ~2.7k | Automated safety check: Pass | Apache-2.0 | |
| React Native Best Practicesvercel-labs/openreview | 1.7k | 17 repos | ~1.1k | Automated safety check: Pass | MIT | |
| Swiftui Protwostraws/SwiftUI-Agent-Skill | 5.6k | 2 repos | ~1.5k | Automated safety check: Pass | MIT | |
| Kortix Brandkortix-ai/suna | 20k | — | ~4k | Automated safety check: Pass | Custom licence | |
| Ip As LogoKartikLabhshetwar/better-shot | 2.4k | 1 repos | ~4.3k | Automated safety check: Pass | MIT | |
| Compose Multiplatform Patternsmonta-app/ocpp-emulator | 180 | 5 repos | ~2k | Automated safety check: Pass | Apache-2.0 |
vercel-labs/openreview
A prioritized rule set for React Native and Expo apps covering list performance, animation, navigation, UI patterns, state, rendering, monorepos and configuration.
twostraws/SwiftUI-Agent-Skill
Comprehensively reviews SwiftUI code for best practices on modern APIs, maintainability, and performance.
kortix-ai/suna
Load FIRST for anything that carries the Kortix look or voice: product or mobile UI, copy of any kind, decks, social, images, email, CLI output, anything with the logo, and reviews of these.
KartikLabhshetwar/better-shot
Generate extremely simple, cute, personified square character images with rounded heavy forms, two purposeful character colors, one solid background color, and a dominant lower-corner composition.
monta-app/ocpp-emulator
Compose Multiplatform and Jetpack Compose patterns for KMP projects — state management, navigation, theming, performance, and platform-specific UI.
adamlyttleapps/claude-skill-aso-appstore-screenshots
Generate high-converting App Store screenshots by analyzing your app's codebase, discovering core benefits, and creating ASO-optimized screenshot images using Nano Banana Pro.
ZacSweers/metro
Run Metro's IDE plugin from source in a sandboxed local IDE against a consumer project.
ZacSweers/metro
Publish the current Metro checkout to Maven Local and verify it in an external consumer or reproducer.
ZacSweers/metro
Adds a new compiler option to Metro.
Categories
Query and analyze Metro's perfetto compiler traces to find real hot spots and untraced time. Analyze Perfetto Trace is an agent skill from ZacSweers/metro. Query and analyze Metro's perfetto compiler traces to find real hot spots and untraced time.
Analyze Perfetto Trace fits situations like: the user asks about metro compile-time perf; where time is going in a trace; shares a perfetto screenshot.
Run `npx skills add ZacSweers/metro --skill analyze-perfetto-trace -a claude-code`. Or copy the skill folder (.agents/skills/analyze-perfetto-trace in ZacSweers/metro) into .claude/skills/analyze-perfetto-trace in your project. Claude Code loads it when a task matches its description.
Run `npx skills add ZacSweers/metro --skill analyze-perfetto-trace -a codex`. Or copy the skill folder (.agents/skills/analyze-perfetto-trace in ZacSweers/metro) into .agents/skills/analyze-perfetto-trace in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ZacSweers/metro --skill analyze-perfetto-trace -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/analyze-perfetto-trace, .gemini/skills/analyze-perfetto-trace, .github/skills/analyze-perfetto-trace and .opencode/skills/analyze-perfetto-trace in your project.
Going by SKILL.md and its folder, Analyze Perfetto Trace needs the command-line tools its instructions call (python3, pip and brew). Our summary lists: Python 3.
SKILL.md contains no URLs. Its commands use pip, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Analyze Perfetto Trace is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Analyze Perfetto Trace: React Native Best Practices (vercel-labs/openreview, 1.7k stars), Swiftui Pro (twostraws/SwiftUI-Agent-Skill, 5.6k stars), Kortix Brand (kortix-ai/suna, 20k stars) and Ip As Logo (KartikLabhshetwar/better-shot, 2.4k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
ZacSweers (a GitHub user) maintains it in ZacSweers/metro, which has 1,408 GitHub stars. The repository holds 4 skills in this directory. The repository was last updated on October 11, 2026.
Source: ZacSweers/metro on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.