$ show RSSNext/Folo
Folo is a multi-platform RSS reader and content aggregator that lets users subscribe to feeds, manage read state, and consume articles, videos, images, and audio across a single unified timeline. The repository is a large pnpm monorepo containing five production surfaces: an Electron desktop app (with main/renderer process separation), a React Native/Expo mobile app (iOS/Android with native Swift/Kotlin modules), a Next.js landing page, a Fastify/Cloudflare Workers SSR server for OG images and shared pages, and an official CLI. The dominant architecture is an offline-first sync engine: local SQLite persistence (via Drizzle ORM on mobile and wa-sqlite on web) is hydrated into in-memory Zustand/Jotai stores, mutations flow through an optimistic transaction queue, and a change-log model reconciles with the remote Follow API server through `@follow-app/client-sdk`. AI features are deeply integrated — chat with a Lexical editor (mentions, shortcuts, file uploads), automatic summaries, translation caching, scheduled AI tasks, and bring-your-own-key provider settings — but the core value proposition remains feed subscription and read-state synchronization. Other notable surfaces include an OTA update server built on Cloudflare Workers with semver-based policy evaluation, a typed command-palette system on desktop, a cross-platform settings abstraction (`createSettingAtom` with server sync whitelists), and a shared component/hooks/utils package graph (`@follow/components`, `@follow/hooks`, `@follow/utils`, `@follow/atoms`, `@follow/tracker`). The tracker layer abstracts PostHog/Firebase/GA4 behind adapters. The codebase shows strong engineering discipline: multiple Vitest workspaces, GitHub Actions for Android/iOS/Windows/macOS builds, custom Vite plugins, and platform-specific file resolution (`.electron.ts`, `.native.tsx`, `.web.ts`). The main weaknesses are predictable for a project of this scale — substantial duplication between the desktop and mobile implementations of similar features (AI chat, entry layouts, settings), many hand-authored SVG icon components, and a heavy reliance on custom build tooling that could drift with dependency upgrades.
The LLM identified 5 files worth highlighting for reuse:
Defines reusable create/update/delete/toggle mutation strategies that wrap a target function (e.g., API call) with local-store optimistic application and rollback. The strategies are generic over state shape and can be extracted into any TypeScript project needing optimistic UI updates without framework-specific coupling.
Implements a database service for feed entries with a consistent Resetable interface (upsert/patch/delete/clearAll) using Drizzle ORM. The service abstracts raw SQLite operations into versioned, conflict-aware persistence methods that are shared across desktop and mobile, demonstrating a clean data-access pattern reusable for any offline-first local database layer.
A global command registry with typed register/get/run lifecycle, supporting categories, hotkey bindings, and dynamic mutation. It is self-contained, decoupled from React, and provides a generic command-dispatch backbone that could be lifted into any application needing extensible keyboard-driven actions without framework boilerplate.
A custom electron-updater provider that fetches release metadata from a desktop manifest API and maps it to electron-updater's expected feed format. It handles multi-platform artifact resolution and semver-based update checks, demonstrating non-obvious integration skill that is directly reusable for any Electron app needing a custom or self-hosted update channel.
A virtual list hook that combines entry measurement and scroll-state caches keyed by feed/view with LRU eviction, supporting dynamic item heights and cross-session scroll restoration. The caching and virtualization logic is isolated from the feed domain and can be extracted into a generic React hook for long-list rendering with position memory.