out

/baʊt/ — a stretch of focused,
unbroken work

macOS 14+ · Free · $4.99 for Pro

$ start a bout

Hotkey and type a duration, a time, a label — in any order. Bout figures it out. Or tap a custom preset and go.

  • 25m lunch 25 min timer
  • @3pm standup until 3pm
  • 1h30m design review 90 min timer
  • tomorrow 9am deploy until tomorrow
  • 2d sourdough starter 2 day timer

$ built for the maker's schedule

Parallel timers.

Run a timer for every context, keep every plate spinning.

Customize your presets.

Named presets for your workflow. One click to start.

Drag to adjust.

Hover and drag. Second precision near zero, minutes further out.

Pause when needed.

Freeze any bout. Pick up exactly where you left off.

Survives everything.

Survives quit, sleep, and reboot. 3pm bell rings at 3pm, always.

Detailed logs.

Every bout logged as JSONL. Grep it. Pipe it to jq for insights & analytics.

$ UI, hotkeys, and API

You control it. Your tools orchestrate it.

Global hotkey (⌃⌥T) for you. URL scheme for your scripts. The same API works for your agent — start timers, pause by name, query what's running. No plugin. Just open "bout://..." and cat timers.json.

Give your agent the playbook: bout.dev/skill.md

URL commands

  • bout://start?duration=25m&name=focus
  • bout://pause current bout
  • bout://pause?label=deploy by name
  • bout://resume
  • bout://stop?all=true stop all
  • bout://status
# start a 25m bout open "bout://start?duration=25m&name=deep+work" # pause a specific bout by name open "bout://pause?label=deploy" # resume all paused bouts open "bout://resume" # stop everything open "bout://stop?all=true" # check what's running open "bout://status"
Global Hotkey Shortcuts Siri Terminal Raycast Alfred Claude Codex Gemini

$ your bout log, your analytics

Six event types — start, stop, expired, pause, resume, dismiss — each with full context: duration, label, source, timestamps, timer UUID. Append-only JSONL on your disk, ready to be piped to jq.

completed bouts this week
jq '[select(.event == "expired")] | length' \ events.jsonl # 47
total focus hours
jq '[select(.event == "expired") | .elapsed] | add / 3600' events.jsonl # 31.5
average bout before stopping early
jq '[select(.event == "stop") | .elapsed] | (add / length / 60)' events.jsonl # 18.3 minutes
how bouts are started
jq 'select(.event == "start") | .source' \ events.jsonl | sort | uniq -c # 29 popover, 11 url, 5 shortcut, 2 preset

Free single timer · $4.99 one-time for Pro

Native Swift · Scriptable · Private