Skip to content
anomalycoPublic

About

Measure and explain performance: web pages, Electron apps, Bun/Node, any process. Agent-native CLI + MCP.

Resources

Stars

152 stars

Watchers

1 watching

Forks

Repository files navigation

strobe

The referee for a performance claim in a pull request. "This makes it faster" becomes a verdict: strobe runs the old and the new side in alternating pairs on CPUs of their own, and says which side won and by how much, with a confidence interval, or that it cannot tell yet. A number it cannot defend, it refuses.

Compare two commands, from any folder, with nothing installed but Bun:

bunx @hona/strobe run --base "<command on main>" --head "<command on your branch>"

Each run starts the command and waits for it to exit; strobe compares their CPU time (cpu.work) and also shows wall time, peak memory and I/O. From an empty folder on a 1-core Linux VM, the first run took about 8 s: 0.6 s to fetch strobe, 7 s for 8 pairs. --check --head "<command>" runs it once to see that it works.

44% less CPU time, 78.0% less memory, better in 8 of 8 pairs; before 7,052 µs, this PR 3,904 µs

In your project

From the project's folder:

bun add -d @hona/strobe                                            # pins strobe for the project
bunx strobe init                                                   # strobe.json and a runnable perf/smoke.bench.ts
bunx strobe bench perf/smoke.bench.ts --head . --check             # each case once: does it work?
bunx strobe bench perf/smoke.bench.ts --base origin/main --head .  # did the branch help? (timed)
bunx strobe report experiment <exp_…> --format pr --update-pr 42   # the card above, in the pull request

strobe init reads your package.json, Cargo.toml or index.html and writes a bench for a web app, a library, a server, a native app, an Electron app, a terminal program or a command-line tool (--target picks one). It never replaces a file without --force, and prints what to run next. On the same VM, init took 45 ms and the first check of a page 12 s.

Then make the cases what your users do:

// perf/scroll.bench.ts
import { bench, web } from "@hona/strobe"

export default bench({
  targets: { app: web() }, // each variant's build, served as strobe.json's build and serve say
  cases: {
    scroll: {
      primary: "main.work",
      run: ({ page }) => page.scroll("main", { by: 4000 }),
      reset: ({ page }) => page.scroll("main", { by: -4000 }),
    },
  },
})

When a number moves

bunx strobe query <exp_…> insights                      # what changed, the suspects, the next command
bunx strobe record --bench perf/scroll.bench.ts#scroll  # one case under the profilers
bunx strobe query rec_3f9a..rec_7c1d hotspots           # what got slower between two recordings
bunx strobe open rec_3f9a                               # the whole recording in Perfetto

Times print in microseconds (18,309,038 µs); --unit ms or "unit": "ms" in strobe.json to change it.

bunx strobe status says what this machine can measure, which permission is missing, and how much disk strobe's files take; bunx strobe prune frees what nothing uses. Web, Electron and native apps, terminal programs, servers, libraries and commands, on Windows, macOS and Linux.

Agents: read skill/SKILL.md. bunx strobe up installs strobe on your PATH, the skill as the strobe skill, and registers strobe's MCP server.

CI: the GitHub Action runs each case once on every pull request and holds exact counters (requests, bytes, DOM nodes, your own count.*) to the base commit's; it never times on a shared runner. Inputs: action.yml; design: SPEC.md §26.

Changes: each release's notes are on GitHub Releases.

Packages for Windows (x64, Arm64), macOS (Apple silicon, Intel) and Linux (x64, arm64). Design: SPEC.md.

About

Measure and explain performance: web pages, Electron apps, Bun/Node, any process. Agent-native CLI + MCP.

Resources

Stars

152 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages