Skip to content

Updates

tmnl pings GitHub at launch to see whether you’re on the latest version. The check is best-effort, runs in the background, and never blocks startup.

On every launch, a short-lived background thread issues a single blocking GET to https://api.github.com/repos/chris-mclennan/tmnl/releases/latest, compares the response’s tag_name against the running CARGO_PKG_VERSION, and — if the remote is newer — prints a one-liner to stderr:

tmnl: v0.1.6 available — https://github.com/chris-mclennan/tmnl/releases/tag/v0.1.6

Where you see this depends on how you launched. From a terminal, the line shows up in the parent shell alongside any other output tmnl emits. From the dock or open target/tmnl.app, the stderr stream ends up in Console.app on macOS (filter by process name “tmnl”). A toast inside the focused tmnl window is planned but not yet wired (v2 plan below).

The implementation lives in src/update_check.rs. It uses ureq (the small blocking HTTP client) instead of an async crate so the check drops directly into tmnl’s winit + wgpu setup without dragging in a runtime.

The check runs once per process launch — no in-process polling, no file-based cache. If you keep tmnl running for days, you won’t see fresh release announcements until you relaunch.

This is intentional. Update checks belong at the natural “start of session” boundary, not interleaved with day-to-day work. There’s no caching layer beyond what the OS does for the HTTPS connection itself, so the next launch re-asks GitHub from scratch.

The check is wrapped in best-effort error handling — every failure mode leaves tmnl running normally with no user-visible noise:

What goes wrongWhat you see
Offline / no DNSSilent — no announcement
GitHub API down or rate-limited (HTTP 5xx/429)Silent
Malformed JSON in the responseSilent
Local clock skewed past TLS cert validitySilent
You’re already on the latestSilent (the common case)
You’re on a newer-than-released dev buildSilent (version compare)

There is no retry logic. If GitHub rejects this launch’s request, tmnl waits until the next launch to try again.

Set check_updates = false under the [ui] table in ~/.config/tmnl/config.toml:

[ui]
check_updates = false

The change takes effect on the next launch. There’s no Settings-overlay row for this knob yet — it stays TOML-only.

Skipping the check has no functional consequence beyond suppressing the “newer release available” announcement. You’ll still know about new releases through the GitHub releases page, the project README, or cargo install tmnl-rs (which always pulls the latest version on crates.io).

The request is what ureq’s default User-Agent ships — ureq/<version> — plus the standard Accept: */* headers. It contains no telemetry, no identifying token, no auth header, and no payload. GitHub’s anonymous-API rate limit (60 requests per hour per IP) covers the use case comfortably for single-user laptops; an environment that launches tmnl thousands of times an hour would hit the cap and silently fall into the failure path above.

mnml and mixr ship the same update_check shape against their own repositories — same [ui] check_updates toggle, same once-per-launch cadence, same silent failure modes. If you have all three installed, each one announces its own updates independently against its own GitHub repo.

That means setting check_updates = false in one app’s config doesn’t affect the others; they each read their own ~/.config/<name>/config.toml. Set it in all three configs if you want a fully-quiet launch experience across the family.

The read APIs (update_check::latest() and update_check::take_pending_announcement()) are already wired but dead_code-gated until the integration lands. The plan is for the welcome overlay (the centered modal you see on a bare launch when ~/.config/tmnl/recents.toml has entries) to surface “new version available” as a non-blocking chip in the corner — same affordance as the stderr line today, but discoverable without having to scan a parent terminal or open Console.app.

There’s no ETA, and the stderr behaviour will stay even after v2 ships — it’s useful for launches from a terminal where the welcome screen never appears.