Agent skill

Perf

by shift-editor in shift-editor/shift

How to find and fix performance problems in Shift's desktop app.

Apache-2.0Auto-check passed

Install Perf

skills CLI
$ npx skills add shift-editor/shift --skill perf -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install shift-editor/shift perf --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/shift-editor/shift.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.codex/skills/perf .claude/skills/perf && rm -rf skills-src

Use ~/.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/

Facts

Skill name
perf
GitHub stars
350
Token cost
~1.8k tokens
SKILL.md length
959 words
Files
1
Skills in repo
16
Repo updated
First seen
Licence
Apache-2.0

At a glance

How to find and fix performance problems in Shift's desktop app.

  • Works in 4 steps: Measure a packaged production build → Frontend: find what started each render → Backend: the workspace process and the… → …
  • Something is slow
  • SKILL.md covers 1. Measure a packaged…, 2. Frontend: find what started…, 3. Backend: the workspace… and 4. Prove it
  • Calls pnpm and nix

What it does

Perf is an agent skill from shift-editor/shift. How to find and fix performance problems in Shift's desktop app. Use when something is slow, choppy, janky, or laggy (scrubbing, dragging, editing, undo, opening fonts), when profiling or measuring, when adding or reviewing perf tests, and before claiming a change made something faster.

Its SKILL.md is about 1.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It works with Linux. The repository describes itself as: A cross-platform font editor built in Rust and TypeScript. The licence is Apache-2.0.

When your agent uses it

  • Something is slow
  • Laggy (scrubbing
  • Reviewing perf tests
  • Before claiming a change made something faster

Example prompts

  • “/perf”

Workflow steps

4 steps, taken from the step headings in SKILL.md.

  1. Measure a packaged production build
  2. Frontend: find what started each render
  3. Backend: the workspace process and the store
  4. Prove it

What it can do on your machine

Read from SKILL.md and the folder at commit 4077a4e. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    Shell commands in SKILL.md call:

    • pnpm
    • nix

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use pnpm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Perf loads about 1.8k tokens when it runs. Until then it costs about 73 tokens; SKILL.md has 959 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~73
When it runs · the whole SKILL.md, loaded when a task matches
~1.8k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from shift-editor/shift at commit 4077a4e, republished under its Apache-2.0 licence (© shift-editor). 959 words, ~1,756 tokens.

Download SKILL.mdSave it as .claude/skills/perf/SKILL.md (or your agent's skills folder).
name
perf
description
How to find and fix performance problems in Shift's desktop app. Use when something is slow, choppy, janky, or laggy (scrubbing, dragging, editing, undo, opening fonts), when profiling or measuring, when adding or reviewing perf tests, and before claiming a change made something faster.

/perf — Measuring and fixing slowness in Shift

Measure the build users run, find what started the work, fix that, and measure again with the same command. A guess that "this looks expensive" has been wrong more often than right here; a number with a cause attached has not.

1. Measure a packaged production build

Never draw conclusions from pnpm dev. React's development build adds jsxDEV, prop validation, and render logging that made up about half of every dev profile and pointed at the wrong code.

sh
pnpm profile:build      # native bridge (release) + renderer minified like a release, with source maps and component names (~1 min warm)
pnpm profile:desktop --font <path> [--glyph A] [--scenario scrub] [--axis Weight] [--seconds 8] [--cpu out.cpuprofile]

profile:desktop launches the packaged app with a throwaway profile, opens the font and glyph, drives the scenario with real pointer input, and prints:

  • Frame times (p50/p90/p99, frames over 33 ms) — the number the user feels.
  • React renders per commit, and for each re-rendered subtree the component and the hook slot or context that started it. This is what tells you what to fix.
  • A source-mapped CPU profile — busy time, top self time, top inclusive time in Shift code. Open the saved .cpuprofile in Chrome DevTools for flame charts.

Notes:

  • The packaged app is in apps/desktop/out/<platform>-<arch>/ (linux-unpacked/shift on Linux). Older out/Shift-* directories are stale Electron Forge output; ignore them.
  • Packaged builds disable Node's inspector fuse, so Playwright's _electron.launch cannot attach. The script uses Chromium's --remote-debugging-port and connectOverCDP instead.
  • On a remote or headless Linux session the app needs the desktop's environment (DISPLAY/WAYLAND_DISPLAY, XDG_RUNTIME_DIR, DBUS_SESSION_BUS_ADDRESS), and must not inherit a Nix LD_LIBRARY_PATH.
  • Linux needs Chromium's Vulkan feature for WebGPU; without a GPU adapter the glyph grid falls back and the numbers mean nothing.
  • Add a scenario to scripts/profile-desktop.mjs rather than writing a one-off script, so the next person can rerun your measurement.

2. Frontend: find what started each render

Read the "Renders started by" list top-down:

  • hook#N — hook slot N in that component changed. useSignalState (and useSyncExternalStore) take two slots each, useContext takes none, so count use* calls to map a slot to a line.
  • context {…} — a context value changed; the keys identify which one. A context built from a high-frequency signal re-renders every consumer on every change.
  • A component starting the same number of renders as there were commits is subscribed to the thing being scrubbed or dragged. Ask whether it shows that value. If not, it's the bug.

Patterns that caused real regressions (rules in /signals):

  • Re-doing work on every change that a signal already tracks — the catalog re-opened the editor's glyph on every location change although its render model follows the location signal. This re-rendered the whole editor.
  • New-but-equal values — new Set(...) written each step to a signal compared by Object.is. Give the signal an equals.
  • Wide contexts — Editor read the catalog context just for openedGlyph. Narrow it to its own context or read the specific cell.
  • Hidden but mounted views — the home grid stays mounted behind the editor to keep its WebGPU atlas, and kept re-laying out on every scrub step. Hold its inputs while hidden.
  • Subscribing for a value used only on an event — read cell.peek() in the handler.
  • Main-process pushes that resend unchanged data — the menu bar was re-sent after every command. Compare before sending.

A healthy weight scrub on Inter Italic (Ryzen 5 5500U, Linux): p99 frame ≈ 16.8 ms, about 60 component renders per commit, main thread about 25% busy. Use that as a reference for "fixed".

Show full SKILL.md (412 more words)Show less

3. Backend: the workspace process and the store

Edits, undo, glyph loads, and atlas preparation run in the workspace utility process through the Rust bridge. pnpm profile:desktop --scenario open prints main's per-phase atlas timings (SHIFT_PROFILE_SLUG_ATLAS); --scenario undo times edit-coordinator round trips. pnpm build does not rebuild the native bridge — profile:build does, and a Rust change measured without it is measuring the old code.

A .shift document opens with a recovery overlay: every table is read through a temp view that UNION ALLs the recovery rows with the canonical rows, filtered by tombstones, replacement markers, and parent visibility (crates/shift-store/src/recovery/views.rs). SQLite pushes WHERE terms into those views, so a key lookup searches each arm by index; it does not push join terms. So in store queries:

  • Never join two store tables on a key. Express the second table as col IN (SELECT …). referenced_glyph_ids_for_glyphs took 117 ms as a join and 14 ms as an IN subquery on Inter; dependent_glyph_ids_for_layers, which runs after every edit, undo, and redo, took 172 ms and 8 ms.
  • Compare a query against main.<table> to see what the overlay costs. A large gap means the view is being scanned rather than searched; EXPLAIN QUERY PLAN shows it as CO-ROUTINE <view> followed by AUTOMATIC COVERING INDEX.
  • nix develop --command sqlite3 -readonly <file>.shift runs queries and EXPLAIN QUERY PLAN against a real document; the recovery views only exist inside the app's connection, so compare the canonical query there and the merged one through a store test.
  • Store tests use canonical tables, so they will not catch this. Measure on a real document opened with recovery.

4. Prove it

  • Rerun the exact same profile:desktop command and report before/after numbers in the commit message.
  • A React re-render regression gets a budget in apps/desktop/e2e/render-budget.spec.ts (visual project, so it runs in CI without a GPU). It counts mean component renders per commit during a weight scrub and a marquee with the same counter as profile:desktop (e2e/fixtures/renderCounter.mts); a failure lists what started the renders. Budgets sit about 15% over the measured value, so a new subscription on those paths must raise one on purpose.
  • If the problem can regress silently, add or extend a spec in apps/desktop/e2e/perf.spec.ts (pnpm --filter @shift/desktop test:e2e:perf, run through the shift-remote-e2e skill rather than on a user's desktop). It records p50/p95 against perf-baseline.json.
  • Note in the commit which platform you measured on; Linux and Windows can be several times slower than macOS for the same code, so "fast on my Mac" proves nothing.

© shift-editor, 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

Files

Just SKILL.md in .codex/skills/perf of shift-editor/shift.

Open the folder on GitHubat commit 4077a4e

Compare with similar skills

Perf 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.

Perf compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Perf this skillshift-editor/shift350—~1.8kAutomated safety check: PassApache-2.0
Configuring Horizoncoollabsio/coolify63k4 repos~898Automated safety check: PassMIT
Model Usageopenclaw/openclaw392k1 repos~637Automated safety check: PassMIT
Engine Whats Newflutter/flutter180k—~978Automated safety check: PassBSD-3-Clause
Openclaw Live Updateropenclaw/openclaw392k—~3.7kAutomated safety check: PassMIT
Upgrade Browserflutter/flutter180k—~1.1kAutomated safety check: PassBSD-3-Clause

Similar skills

  • Configuring Horizon

    coollabsio/coolify

    A skill your agent uses whenever the user mentions Horizon by name in a Laravel context.

    63k GitHub starsUsed in 4 repos~898 tokens
    Backend & APIsAuto-check passed
  • Model Usage

    openclaw/openclaw

    Summarize CodexBar local cost logs by model for Codex or Claude, including current or full breakdowns.

    392k GitHub starsUsed in 1 repo~637 tokens
    Auto-check passed
  • Engine Whats New

    flutter/flutter

    Generates the "what's new" release summary and diff file for changes in the Flutter engine (//engine/src/flutter) between two releases (e.g., 3.47 vs 3.44).

    180k GitHub stars~978 tokensUpdated today
    MobileAuto-check passed
  • Openclaw Live Updater

    openclaw/openclaw

    Maintain the canonical live OpenClaw main checkout, macOS LaunchAgent-managed Gateway, local macOS app, exact-head main CI, and recurring full release validation.

    392k GitHub stars~3.7k tokensUpdated today
    DevOps & CloudAuto-check passed
  • Upgrade Browser

    flutter/flutter

    Upgrade browser versions (Chrome or Firefox) in the Flutter Web Engine and/or Framework tests.

    180k GitHub stars~1.1k tokensUpdated today
    MobileAuto-check passed
  • K8s Security Policies

    Cybereason-Public/owLSM

    Comprehensive guide for implementing NetworkPolicy, PodSecurityPolicy, RBAC, and Pod Security Standards in Kubernetes.

    280 GitHub starsUsed in 12 repos~2k tokens
    Backend & APIsAuto-check passed

More from shift-editor/shift

All 16 skills in this repo
  • Shift Commit Rules

    shift-editor/shift

    Rules for writing git commits in the Shift font editor repo: Conventional Commits subjects, user-facing changelog wording, concise subjects and logical commit boundaries.

    350 GitHub stars~1.4k tokensUpdated yesterday
    Auto-check: notes
  • Dead Code Removal with Knip

    shift-editor/shift

    Finds unused files, exports and class members with Knip, then verifies each candidate through reference tracing before removing anything, never using knip --fix.

    350 GitHub stars~1.8k tokensUpdated yesterday
    Auto-check passed
  • Shift Subsystem Docs

    shift-editor/shift

    Updates or creates DOCS.md files for Shift subsystems, recording the architecture invariants and constraints that cannot be learned from reading the source.

    350 GitHub stars~1.9k tokensUpdated yesterday
    Auto-check passed
  • Adversarial Docs Audit

    shift-editor/shift

    Fact-checks DOCS.md files against the source code, testing each concrete claim and sorting it as true, false, stale or unverifiable.

    350 GitHub stars~818 tokensUpdated yesterday
    Auto-check passed
  • Shift Issue Writer

    shift-editor/shift

    Sets the rules for finding, writing and updating Shift GitHub issues: search for duplicates first, use outcome-focused titles and testable acceptance criteria.

    350 GitHub stars~1.4k tokensUpdated yesterday
    Auto-check passed
  • Shift JSDoc Contracts

    shift-editor/shift

    Guides writing JSDoc for Shift exported APIs as a stable caller contract, covering ownership, lifetime, side effects and nullability that TypeScript types cannot express.

    350 GitHub stars~3.7k tokensUpdated yesterday
    Auto-check passed

Works with

Questions about Perf

What does Perf do?

How to find and fix performance problems in Shift's desktop app. Perf is an agent skill from shift-editor/shift. How to find and fix performance problems in Shift's desktop app.

When should I use Perf?

Perf fits situations like: something is slow; laggy (scrubbing; reviewing perf tests; before claiming a change made something faster.

How do I install Perf in Claude Code?

Run `npx skills add shift-editor/shift --skill perf -a claude-code`. Or copy the skill folder (.codex/skills/perf in shift-editor/shift) into .claude/skills/perf in your project. Claude Code loads it when a task matches its description.

How do I install Perf in Codex?

Run `npx skills add shift-editor/shift --skill perf -a codex`. Or copy the skill folder (.codex/skills/perf in shift-editor/shift) into .agents/skills/perf in your project. Codex loads it when a task matches its description.

Can I use Perf in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add shift-editor/shift --skill perf -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/perf, .gemini/skills/perf, .github/skills/perf and .opencode/skills/perf in your project.

What does Perf need to run?

Going by SKILL.md and its folder, Perf needs the command-line tools its instructions call (pnpm and nix).

Does Perf access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Perf safe to install?

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.

What licence does Perf use?

Perf 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.

How many tokens does Perf use?

About 1.8k tokens (SKILL.md is roughly 7k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Perf?

Skills that share tags, products or a category with Perf: Configuring Horizon (coollabsio/coolify, 63k stars), Model Usage (openclaw/openclaw, 392k stars), Engine Whats New (flutter/flutter, 180k stars) and Openclaw Live Updater (openclaw/openclaw, 392k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Perf?

shift-editor (a GitHub organization) maintains it in shift-editor/shift, which has 350 GitHub stars. The repository holds 16 skills in this directory. The repository was last updated on October 10, 2026.

Source: shift-editor/shift on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.