# native-app-performance

A skill that profiles native macOS and iOS apps with xctrace and Time Profiler. Instruments traces get analyzed from the terminal, no Instruments UI needed.

- skill · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · ★ 336
- Author: harperreed
- License: not stated · policy=link-only · description only; the file stays with the author
- Source: https://github.com/harperreed/dotfiles/tree/HEAD/.claude/skills/native-app-performance/SKILL.md
- Updated: 2026-10-15
- HTML: https://affpapa.org/en/nevibecode/skills/native-app-performance

## What it does

The skill walks the agent through the whole path: capture a Time Profiler run, pull the samples out, symbolicate them, then rank the hottest frames. You can attach to a process that is already running with `--attach <pid>`, or start the binary yourself with `--launch`. From there `scripts/extract_time_samples.py` exports the trace to time-sample XML, and `scripts/top_hotspots.py` turns those samples into a ranked list of app frames.

Three scripts ship with it: `scripts/record_time_profiler.sh` handles recording, `scripts/extract_time_samples.py` does the export, `scripts/top_hotspots.py` symbolicates and ranks. It is macOS-only, since it leans on `xcrun xctrace`, `vmmap` and `atos`. You need either a running process or a binary path, plus the `__TEXT` load address from `vmmap`.

ASLR moves things around on every launch, so the load address has to come from `vmmap` while the app is alive, not from an earlier session. Rebuild the app and the `--binary` path needs updating too, because symbols have to match the trace you are reading. Empty stacks usually mean the capture was short or landed on idle time; raise `--time-limit` and trigger the slow path while recording. Confirm you are profiling the build you think you are — a local one, not the copy sitting in `/Applications`.

## Install

### Claude Code (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add harperreed/dotfiles --skill native-app-performance -a claude-code
```

2. **Manually: put the files in place**
- File: `~/.claude/skills/native-app-performance/SKILL.md` — Copy the whole skill folder; for one project use .claude/skills/native-app-performance/

### Codex

1. **Skills CLI (Vercel)**
```bash
npx skills add harperreed/dotfiles --skill native-app-performance -a codex
```

2. **Manually: put the files in place**
- File: `.agents/skills/native-app-performance/SKILL.md` — For all projects use ~/.agents/skills/

### Cursor

1. **Skills CLI (Vercel)**
```bash
npx skills add harperreed/dotfiles --skill native-app-performance -a cursor
```

2. **Manually: put the files in place**
- File: `.cursor/skills/native-app-performance/SKILL.md` — Cursor also reads .agents/skills/ and .claude/skills/

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install harperreed/dotfiles native-app-performance
```

2. **Manually: put the files in place**
- File: `.github/skills/native-app-performance/SKILL.md`

### Gemini CLI

1. **Skills CLI (Vercel)**
```bash
npx skills add harperreed/dotfiles --skill native-app-performance -a gemini-cli
```

2. **Platform CLI**
```bash
gemini skills install https://github.com/harperreed/dotfiles --path .claude/skills/native-app-performance
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/native-app-performance/SKILL.md` — The legacy .windsurf/skills/ path still works

### OpenCode

**Skills CLI (Vercel)**
```bash
npx skills add harperreed/dotfiles --skill native-app-performance -a opencode
```

### Claude.ai

**Claude.ai**
- Zip the folder and upload it in Settings → Capabilities → Skills

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/harperreed/dotfiles/tree/HEAD/.claude/skills/native-app-performance/SKILL.md

## When to use it
- find hotspots in a native app without opening Instruments
- record a Time Profiler session against a running PID
- analyze an existing `.trace` file from the command line
- symbolicate samples and match them to the right binary
- check that the local build is being profiled, not the `/Applications` copy

## Example prompts
- Record a 90-second Time Profiler run against the running process and save the trace to `/tmp/App.trace`
- Extract the samples from `/tmp/App.trace` and show me the top 30 hotspots
- Symbolicate the samples using `/path/App.app/Contents/MacOS/App` and the load address from `vmmap`

## Similar
- [argent-native-profiler](https://affpapa.org/en/nevibecode/skills/argent-native-profiler.md) — skill · 26300 installs
- [ios-ettrace-performance](https://affpapa.org/en/nevibecode/skills/dpearson2699-ios-ettrace-performance.md) — skill · 1200 installs
- [swiftui-performance-audit](https://affpapa.org/en/nevibecode/skills/swiftui-performance-audit.md) — skill · 109 installs
- [react-native-best-practices](https://affpapa.org/en/nevibecode/skills/react-native-best-practices.md) — skill · 30200 installs
- [expo-react-native-performance](https://affpapa.org/en/nevibecode/skills/expo-react-native-performance.md) — skill · 1500 installs
- [android-performance](https://affpapa.org/en/nevibecode/skills/android-performance.md) — skill · 19 installs

From the same set: [harperreed/dotfiles](https://affpapa.org/en/nevibecode/by/harperreed/dotfiles.md) — 8 cards

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
