A modern macOS RSS Reader app built with SwiftUI
✅ Three-Panel Layout
- Left panel: Feed list with unread counts
- Middle panel: Article list with sorting and filtering
- Right panel: Article viewer with integrated WebKit
✅ Feed Management
- Add feeds by URL with auto-discovery
- Refresh individual or all feeds
- Delete feeds with context menu
- Visual feed icons and unread badges
- Folder organization for feeds
- Multi-select for bulk operations (move, delete)
✅ Article Reading
- Clean WebKit-based article rendering
- Automatic read status tracking
- Manual mark as read/unread
- Share and open in browser
- Dark mode support
✅ Data Persistence
- SwiftData for local storage
- Efficient relationship management
- Automatic cascading deletes
✅ User Experience
- Keyboard shortcuts (⌘N, ⌘R, ⌘O, j/k/u)
- Context menus for quick actions
- Sorting (newest/oldest/title)
- Filter by unread status
- Relative timestamps
✅ Smart Folders
- All Feeds - View all articles across feeds
- Unread - Quick access to unread articles
- Starred - Saved articles for later reference
- Recent - Articles from last 1 day, 7 days, or custom date range
✅ Full-Text Search
- Search across article titles, content, summaries, and authors
- Real-time filtering as you type
- Works with all views (feeds, smart folders)
✅ Auto-Refresh
- Configurable automatic refresh intervals
- Settings window with enable/disable toggle
- Choose refresh frequency (5, 15, 30, 60 minutes)
- Background timer-based refresh
✅ Enhanced Menu Bar & Keyboard Shortcuts
- File Menu: ⌘N (Add Feed), ⇧⌘N (Add Folder), ⌥⌘I (Import OPML), ⌥⌘E (Export OPML)
- Edit Menu: ⌘A (Select All), ⌘D (Deselect All)
- View Menu: ⌘1-4 (Smart Folders), ⌘F (Focus Search)
- Article Menu: ⌘U (Toggle Read), ⌘S (Toggle Star), ⇧⌘M (Mark All Read), ⌘O (Open in Browser), ⇧⌘C (Copy Link), ⇧⌘S (Share)
- Feed Menu: ⌘R (Refresh All), ⇧⌘R (Refresh Selected), ⌘E (Edit Feed), ⌘⌫ (Delete Feed)
- Full native macOS menu bar with keyboard-driven navigation
- Arrow keys for article navigation
✅ OPML Import/Export
- Import feeds from other RSS readers
- Export your feed collection
- Preserves folder structure
- Non-blocking background import
- Security-scoped file access
Sources/
├── SourcesApp.swift # App entry point
├── Models/
│ ├── Feed.swift # RSS feed model
│ ├── Article.swift # Article model with starred status
│ ├── Folder.swift # Feed folder organization
│ ├── AppSettings.swift # User preferences & cache settings
│ └── OPMLDocument.swift # OPML file document
├── ViewModels/
│ ├── FeedListViewModel.swift # Feed management, OPML, folders
│ └── ArticleListViewModel.swift # Article list, search, smart folders
├── Views/
│ ├── ContentView.swift # Main 3-panel layout
│ ├── SidebarView.swift # Feed list with smart folders
│ ├── ArticleListView.swift # Article list with search
│ ├── ArticleDetailView.swift # Article viewer (Panel 3)
│ └── SettingsView.swift # App preferences window
└── Services/
├── FeedParser.swift # RSS/Atom XML parsing
├── FeedFetcher.swift # Network fetching
├── OPMLParser.swift # OPML import parser
├── OPMLExporter.swift # OPML export generator
└── CacheManager.swift # Article cache with LRU eviction
- macOS 14.0 or later
- Xcode 15.0 or later
- Swift 5.9 or later
- Open
Sources.xcodeprojin Xcode - Select your development team in the project settings (if needed)
- Build and run (⌘R)
- Click the + button in the sidebar or press ⌘N
- Enter a feed URL or website URL (auto-discovery will find the feed)
- Click Add
Example feeds to try:
https://daringfireball.net/feeds/mainhttps://blog.swift.org/feed.xmlhttps://www.theverge.com/rss/index.xml
- Add Folder: Click + → Add Folder or press ⇧⌘N
- View Folder Contents: Click on folder name to see unified list of all articles from contained feeds
- Move to Folder: Right-click feed → Move to Folder
- Collapse Folders: Click disclosure triangle to collapse/expand folders (state persists across app launches)
- Multi-Select: Click + → Select Feeds, then ⌘-click to select multiple
- Bulk Move/Delete: Select multiple feeds, right-click for bulk actions
- Mark All as Read: Right-click on folders, feeds, or smart folders for bulk mark as read
- Refresh: Right-click feed → Refresh, or ⌘R for all feeds
- Delete: Right-click → Delete
- All Feeds: View all articles from all feeds
- Unread: Quick access to unread articles
- Starred: View all starred/saved articles
- Recent: Filter by date range with segmented tabs (1 day, 7 days, or custom date range)
- Star/Unstar: Click star button in toolbar or press
s - Starred Folder: Access all starred articles from smart folders
- Star Badge: Yellow star indicator on starred articles in list
- Starred status is independent of read/unread
- Use the search bar at the top of the article list
- Searches across titles, content, summaries, and authors
- Works with feeds and smart folders
- Debounced search (300ms) for optimal performance
- Click on any article in the middle panel to view it
- Articles are automatically marked as read when viewed
- Use toolbar buttons to toggle read/unread, star, share, or open in browser
- Navigate with arrow keys or use keyboard shortcuts: ⌘U (toggle read), ⌘S (toggle star)
- Sort: Click sort icon in toolbar to choose newest first, oldest first, or by title
- Unread Filter: Click circle icon in toolbar to toggle unread-only view (turns blue when active)
- Mark All Read: Click checkmark icon in toolbar
- Date Grouping: Articles automatically grouped by "Today", "Yesterday", and specific dates
- Import: Click + → Import OPML (⌘O)
- Export: Click + → Export OPML
- Preserves folder structure and organization
- Access via Sources → Settings or ⌘,
- Auto-Refresh: Enable auto-refresh and set interval (5-60 minutes)
- Cache Management:
- Set cache size limits (50MB - 1GB or unlimited)
- Set cache age limits (7-90 days or never expire)
- View cache statistics (size, article count, last cleanup)
- Clear cache manually with confirmation
- Automatic cache cleanup on app startup and settings changes
- Article List Appearance:
- Set excerpt length (None, 1 line, or 2 lines of preview text)
- Settings persist across app launches
SwiftUI + SwiftData: Modern declarative UI with efficient data persistence
MVVM Pattern: Clear separation between views and business logic
Async/Await: Native Swift concurrency for network operations
RSS/Atom Support: Custom XML parser supporting both feed formats
Performance Optimizations: Database-level predicates, search debouncing, query limits, optimized image loading
- Starred/favorite articles
- Article cache management
- Enhanced macOS Menu Bar support
- Performance optimizations for large feeds
- Collapsible folders with persistent state
- Clickable folders for unified article view
- Mark All as Read (folders, feeds, smart folders)
- Enhanced article list UI (date grouping, exposed filters, feed names)
- Customizable excerpt length
- Feed update notifications
- Custom themes and appearance options
- macOS integration (Spotlight, Handoff)
- iCloud sync
- Database-level predicate filtering for efficient queries
- 300ms search debouncing to reduce query load while typing
- Fetch limit of 1000 articles per view for optimal memory usage
- Optimized image loading with proper phase handling and fallbacks
- Unique constraint on Article IDs to prevent duplicates
- No podcast/audio enclosure support yet
- No iCloud sync
- Article images still require network (only HTML content is cached)
- Smart folder counts update on app restart
- Text search uses in-memory filtering (database can't efficiently do case-insensitive contains)
See LICENSE file for details.
