RDLTR

Notes from every release

This release adds a Shift+DD summarize-with-LLM shortcut to the browser extension, captures article content on save for future search, and ships an in-process HTML cache with a pre-gzipped anonymous home path. The favicon was redesigned as a circular brand mark with light/dark theme variants. Metadata extraction was moved off the main event loop into a Bun worker thread to prevent reads from stalling under concurrent saves. Secrets management was migrated to 1Password Environments, dependencies were bumped to TypeScript 6, and several smaller UX fixes landed alongside internal tooling and documentation updates.

New

  • Summarize any page with your preferred LLM via Shift+DDThe browser extension now extracts article text via Readability and Turndown, opens your chosen LLM (Claude, ChatGPT, or Perplexity), and auto-pastes and submits the content. A new options page lets you pick your preferred LLM, and a context-menu pair lets you save or summarize any page directly. Falls back to URL-only when content can't be extracted. da98fd4 8851b5b
  • Article content is now captured on save and summarizeWhen you save or summarize a link, the extension extracts the article body and posts it to the server alongside the URL and title. A new POST /api/link/seen endpoint upserts content and marks the link read on summarize. Content is captured for all users; search will be gated separately. 6b2b824
  • In-process HTML cache cuts render overhead for list pagesThe rendered list HTML for / and /:username is now cached in-process and invalidated on writes, skipping link.all() and JSX render on cache hits. The anonymous home page also gets a pre-gzipped full-page cache that bypasses JSX render and the compress middleware entirely on repeated hits. Cache entries are busted in lockstep with SSE notifications. 76f68e1 edebac5

Improved

  • Metadata extraction moved to a Bun worker threadCheerio HTML parsing previously ran on the main event loop, causing an 83% read RPS collapse and 76× p50 latency degradation under concurrent saves. Metadata extraction now runs in a dedicated worker thread via a new jobs dispatch layer, keeping reads unblocked while saves are in flight. b8ff334
  • Favicon redesigned as a circular brand mark with light and dark variantsThe favicon is now a round dark plate with the brand R inside, shared between the site and the extension. Two SVG variants (light and dark) are swapped via matchMedia to avoid Safari's dark-mode plate adornment. Legacy .ico and apple-touch-icon are kept as fallbacks for crawlers and iOS. ad0b454 0273f99 37558a0 7b60d3b
  • Celebration stats show weekly reads, top weekday, and clean-sweep daysThe personal stats panel replaces the always-100% read ratio with three new lines: reads in the last 7 days, the user's most frequent reading weekday, and a count of days where the queue hit zero. b336b5f
  • Secrets managed via 1Password EnvironmentsLocal dev and Kamal deploys now both read secrets from a FIFO managed by 1Password Environments. A preload script drains the FIFO into process.env, and .kamal/secrets is symlinked to .env so Kamal sees the same values. Stripe keys are selected by NODE_ENV; the ephemeral test webhook secret is exported from the Stripe CLI at dev startup. 16bab8c

Fixed

  • Tab restore no longer clobbers selection stateThe visibilitychange listener previously called refresh() unconditionally on every tab return, overwriting chevron selection state and racing with SSE deletes. It now only refreshes when an SSE disconnect was detected, restoring the original guarded behavior. 6e1967b e7e9a7b

This release focuses on UI polish and list interaction improvements. The privacy toggle moved into the menu, sorting options became proper links, link metadata layout was reorganized, and SSE updates now reconnect and preserve selection state without page reloads. Several visual consistency fixes landed across links, underlines, and icons, plus a username length limit and internal tooling updates.

New

  • Stats link added to homepage empty stateThe homepage empty state now includes a link to the stats page, giving new users a quicker path to that section. 8a4f5d6
  • Fine print copy added to the premium pageThe premium page now includes additional explanatory copy in the fine print section. 9b97fb0

Improved

  • Privacy toggle moved into the menu with a keyboard shortcutThe privacy lock toggle is now accessible from the menu (P shortcut) rather than inline. The lock icon is only shown when a list is public, and toggling privacy now reloads the page to reflect the new state. aa060bd 9bcd1b6 51b3338 af509a4
  • Sorting options are now clickable links on desktop and mobileSort controls were refactored into proper anchor links using shared components, making them work consistently across device sizes and easier to maintain. 7228801
  • Link metadata right-aligned with username shown before dateLink metadata in list views is now right-aligned and the display order swapped to show username before date. The first item is also auto-selected when SSE updates arrive. b0cd076
  • Consistent link underline style and hover transitions across the appAll links and the logout menu button now share the same underline thickness and a smooth hover transition, replacing inconsistent per-page styles. c964665 d02c0ee e5945f1 51e1b7e
  • Navigation icons replaced with Lucide user iconsThe triangle indicators in the navigation bar have been replaced with Lucide user icons for a cleaner look. a512da1
  • Usernames are now limited to 15 charactersRegistration enforces a maximum username length of 15 characters. Existing usernames are unaffected, but any new sign-up attempt with a longer name will be rejected. 811ab91

Fixed

  • SSE reconnects without a page reload and preserves chevron selectionThe live-update connection now reconnects in the background when it drops, and the selected item's chevron stays in place when items are prepended or removed via SSE swaps. 6f1f8bd 98571d4