Skim v1.0.16 β€” "Are You Still There?" πŸ‘»

byβ€’

The one where Skim stops impersonating a corpse.

A self-update could relaunch Skim into a window with a titlebar and… nothing. Restarts didn't help. Reinstalling didn't help. Then, hours later, it just came back β€” which is somehow more unsettling than staying broken. 🫠

Turns out nothing was broken. The whole UI was waiting on the first mailbox query, that query was politely queued behind the catch-up sync, and the app had no way to say "hang on, I'm reading" β€” so it said nothing at all. For hours. In an empty window. Cool. πŸ™ƒ

πŸ› Fixed

  • The window shows up first, the mail follows. The app now draws itself as soon as it knows which mailboxes you have. Folders and messages arrive into a live window instead of holding the door shut. πŸšͺ

  • A slow start looks slow, not dead. If the mailbox hasn't answered in 2 seconds, the shell appears anyway. If it fails outright, you get an error β€” not a blank rectangle and a shrug. ⏱️

  • No more "welcome to Skim!" for people who've been using Skim for months. Onboarding waits until we actually know your account list is empty. πŸ‘‹

🧹 Under the hood

  • Reads got their own database connection. Everything you're actively waiting on β€” folder lists, message lists, threads, search β€” now goes through a second, read-only SQLite connection. WAL lets it read while the sync writes, so opening the app no longer means standing in line behind it. Writers and the entire sync engine are untouched. 🚦

  • Two new places to look when things go weird. Slow reads (>1s) land in skim-slow.log with the query name, and frontend crashes finally leave a trace in skim-frontend.log β€” both in %APPDATA%\\. Previously the frontend could fall over in complete silence, because a windowed release build has no console to complain to. πŸ”¦

Nothing you have to do. Update, and the next cold start should look like an email client rather than a haunted picture frame. πŸ–ΌοΈ

Get it here:

58 views

Add a comment

Replies

Best

Love the humor in the release notes. They made a pretty technical change enjoyable to read instead of feeling like a changelog.

The read only connection with WAL is a clever touch. I enjoy posts that explain why a fix works instead of only announcing that it's fixed.

Add Add one mre item:β˜•keep cofee and snacks nearbyβ€”you'll barely leave your desk. πŸ˜„

Β I tell the guy who writes release notes (you know him - same guy who writes code, mr. C.) πŸ˜„

Nice release. are you planning to expose any startup timing metrics in the future, or are the logs mainly intended for debugging when something goes wrong?

Β Debugging only. Skim is local and open-source β€” nothing phones home, and I'd rather not start. skim-slow.log is there so that when someone says "it hung on launch," they can send me a file instead of a feeling.

I never realized a missing loading state could make an app feel completely dead. this feels like a great reminder that perception matters just as much as performance.

These kinds of infrastructure updates dont get enough appreciation. They are usually invisible but they make every future release better.

Haunted picture frame is probably the best bug description I have read this week. Out of curiosity, how did you finally track it down to the mailbox query instead of thinking it was a rendering issue?

Β Honestly, I didn't β€” not while it was happening. That's the actual embarrassment: a windowed release build has no stderr, so the frontend was falling over (or not) in complete silence. What gave it away was that it came back on its own after a few hours. A rendering bug doesn't heal itself on a timer; a queue draining does. From there it was just reading the boot path: ready gated the whole UI on boot(), and boot() waited for folders and the first page of mail β€” all through the single SQLite connection the catch-up sync was hammering. The logs in this release exist so next time I don't have to reason it out from "it fixed itself."

Gotta second the format / humour and the β€œwhy” of it all. Pro software is hard to write not because the app is hard - but because real life happens - all these millions of things that come at you out of left field. Good work on keeping up a sense of feel and flow (from what I can tell).

The 2-second shell fallback is the detail that actually fixes the problem, not just hides it. Splitting reads onto their own WAL connection instead of slapping a spinner on top is the right call, most teams would've stopped at the spinner.

The root cause here is more interesting than the bug. The app had no way to say "I do not know yet", so it asserted something instead. An empty window is not neutral. It reads as no mail. I have hit that exact shape three times today in completely unrelated products. A monitor that falls back to a cached default reads as a real reading. A widget that keeps showing its last good value reads as current. Same failure every time: no representation for unknown, so the interface quietly picks a lie and looks confident doing it. Arash is right that the shell fallback fixes rather than hides, and the reason is that it is the only version where the app states its own uncertainty out loud. Cheap generalisation while you are already in there: is there anywhere else in Skim where absent data renders identically to a real answer? That is where the next one of these is hiding.

Β That's exactly the shape of it β€” an empty window isn't neutral, it's an assertion. The message list had the same bug in miniature: "folder is empty" and "folder hasn't answered yet" rendered identically, which is why the list now holds a loading state instead of an empty one. Going hunting for the rest is a good use of an afternoon.

12
Next