- TypeScript 98.9%
- CSS 0.8%
- JavaScript 0.1%
- Dockerfile 0.1%
| client | ||
| server | ||
| .env.example | ||
| .gitignore | ||
| CHANGELOG.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| GETTING_STARTED.md | ||
| package.json | ||
| README.md | ||
| TABBED_WIDGETS_GUIDE.md | ||
| THEMES.md | ||
| WIDGET_GUIDE.md | ||
Personal Homepage
A customizable personal homepage with monitoring widgets and integrations.
Features
Widgets
- 📚 Bookmarks - Organized bookmark management with categories
- 🐳 Docker Monitoring - Real-time container status and control
- 🖥️ Home Lab Monitoring - Comprehensive system stats: CPU, memory, swap, network traffic, disk I/O, load average, processes, and all storage devices
- 🎬 Jellyfin Integration - Now playing widget with media information
- ⏰ Time - Local time display with 12h/24h format
- 🌤️ Weather - Current weather with temperature in C/F
- 📱 Reddit Feeds - Monitor multiple subreddit feeds with load more pagination
- 🔍 Search - Integrated search (Google, DuckDuckGo, or custom SearXNG instance)
- 📡 RSS Feeds - Aggregate and display RSS feeds from multiple sources
- 📅 Calendar - Monthly calendar view with navigation
- ✅ Todo List - Task management with completion tracking and reordering
- 📑 Tabbed Widgets - Group multiple widgets into tabbed layouts
- 🖼️ Image - Bing Image of the Day, custom images, or slideshows with auto-advance
- 📰 FreshRSS - Monitor unread article counts by category from your FreshRSS instance
- 🏈 Sports - Live scores for NFL, NBA, and MLB with favorite team filtering
- 📈 Stocks - Real-time stock quotes and market indices via Finnhub API
- 🎵 Last.fm - Recent scrobbles, now playing, and listening stats
- 🗞️ News - Aggregated top stories from NPR, NYT, BBC, The Guardian, and Reuters
- 📺 YouTube - Channel subscriber count, views, and video count
- 🚀 Speedtest - Recent speedtest results from Speedtest Tracker with run test button
- 🏆 Sports News - Latest sports news from ESPN for your favorite leagues
- 🔖 Linkding - Recent bookmarks from your Linkding instance with read/archive actions
- 🤖 Claude Usage - API usage statistics and costs from Anthropic Claude
- 📊 Umami Analytics - Multi-website analytics dashboard with metrics and percentage changes
- 🎵 Navidrome - Now playing widget showing currently playing music from Navidrome/OpenSubsonic
- 🐘 Mastodon - Full-featured Mastodon client with timeline, mentions, compose, and interactions
Customization
- 🎨 Theme System - 40+ built-in color schemes plus custom theme creator
- 🖌️ Custom Theme Creator - Create, edit, and delete your own themes with visual color pickers for all 8 theme colors
- 🔍 Global Search - Quick search modal (Ctrl+K) that inherits your search widget settings
- 📐 Flexible Layout - Drag-and-drop widget arrangement with 24-column grid for precise positioning
- 🎯 Header Widgets - Add compact widgets to header (4 slots: left, middle, center, right)
- 🏷️ Custom Homepage Title - Personalize your homepage title and username
- 📏 Compact Header - Optional reduced padding and text size for header
- ⚙️ Widget Configuration - Configure widget settings even when hidden or grouped
- 👁️ Show/Hide Widgets - Toggle widget visibility with persistent state
- 📱 Responsive Design - Multi-breakpoint layouts with intelligent widget arrangement (2-column layout on medium screens, auto-stacking on mobile)
- 🔄 Collapsible Widgets - Collapse widgets to save space, with "default collapsed" option
- 🎨 Custom Icons - Choose from 1000+ Lucide icons or upload custom images for widgets and bookmarks
- ⌨️ Keyboard Shortcuts - Configurable keybindings (? for settings, E for edit mode, B for add bookmark, T for add task, D to clear completed tasks, Ctrl+K for search)
- 💾 Export/Import - Complete backup of all settings, widgets, bookmarks, and keybindings
- 🔄 Auto Backup - Scheduled server-side backups with one-click restore
- ➕ Quick Add Bookmark - Header button and keyboard shortcut for fast bookmark creation
Quick Start
Development
# Install dependencies
npm install
# Start development servers (client + server)
npm run dev
The client will be available at http://localhost:3000 and the server at http://localhost:3001.
Production (Docker)
# Copy environment variables
cp .env.example .env
# Edit .env with your configuration
nano .env
# Build and run with Docker Compose
docker-compose up -d
Access your homepage at http://localhost:3001
Configuration
Environment Variables
See .env.example for required environment variables:
- JELLYFIN_URL: Your Jellyfin server URL
- JELLYFIN_API_KEY: Jellyfin API key
- WEATHER_API_KEY: OpenWeatherMap API key
- WEATHER_LOCATION: Your location for weather
Widget Configuration
All widget settings, bookmarks, and layout can be configured through the web UI. Settings are persisted to a SQLite database.
Managing Widgets
Access the Settings panel (gear icon in header) with 5 organized tabs:
Preferences Tab
- Set clock format (12h/24h) and temperature unit (C/F)
- Configure homepage title and username
- Customize header widgets (4 positions available)
- Toggle compact header mode
- Select bookmark category color
Widgets Tab
- Enable/disable widgets to show/hide on your homepage
- Configure widget-specific options:
- Bookmarks: Add, edit, and delete bookmarks with categories
- RSS: Manage feed URLs
- Search: Choose search engine (Google/DuckDuckGo/SearXNG), customize placeholder, toggle new tab behavior
- Reddit: Add/remove subreddits to monitor
- And all other widget settings
Groups Tab
- Create widget groups to combine multiple widgets into tabbed layouts
- Reorder tabs within groups
- Manage grouped widgets
Keys Tab
- View and customize all keyboard shortcuts
- Configure keybindings for quick actions
- Reset keybindings to defaults
Backup Tab
- Configure automatic backups (interval, retention)
- Create manual backups
- View, restore, download, and delete server-side backups
- Export/import all data or individual components (bookmarks, layout, todos)
Layout Management
- Edit Mode: Click "Edit Layout" to enter drag-and-drop mode
- Move Widgets: Drag widgets by their header (or grip icon if header is hidden)
- Resize Widgets: Drag corners to resize in edit mode
- Auto-Compaction: Widgets automatically flow and fill gaps when rearranged
- Save: Click "Save Layout" when done (or layout saves automatically on drag/resize)
Widget Details
Search Widget
- Support for multiple search engines (Google, DuckDuckGo, SearXNG)
- Custom SearXNG instance support for privacy-focused search
- Configurable placeholder text
- Option to open searches in new tab or same tab
- Can be added to header for quick access
RSS Widget
- Aggregate feeds from multiple RSS sources
- Auto-refresh every 5 minutes
- Displays article titles, sources, and publish times
- Sorts articles by date (newest first)
- Manual refresh button
- Manage feeds through Settings panel
Calendar Widget
- Monthly calendar view
- Navigate between months
- "Today" quick navigation button
- Highlights current day
- Shows full week grid with dates from adjacent months
Todo Widget
- Add, edit, and delete tasks
- Mark tasks as complete/incomplete
- Completed tasks automatically sink to bottom
- Subtasks with expand/collapse
- Reorder tasks with drag handles
- Progress indicator showing completion percentage (optional)
- Clear completed tasks button
- Persist todos to database
- Quick Add: Press
Tto open task modal with subtask support - Offline support: Changes saved locally, syncs when server returns
- Configurable settings:
- Show/hide progress bar
- Sort order (manual, newest, oldest, alphabetical)
- Enable/disable subtasks
- Auto-expand tasks with subtasks
Image Widget
- Multiple image sources:
- Bing Image of the Day - Daily featured images
- NASA APOD - Astronomy Picture of the Day (free API)
- Unsplash Random - High-quality photos (requires free key)
- Custom Image - Upload from device
- Custom Slideshow - Multiple uploaded images
- Support for 1-8 images with auto-slideshow
- Configurable slideshow interval
- Image title and copyright display
- Configurable object fit (contain, cover, fill)
- Images persist in database as base64
FreshRSS Widget
- Connect to your FreshRSS instance
- Display total unread article count
- Show unread counts by category/label
- Auto-refresh every minute
- Manual refresh button
- Configure via Settings with URL, username, and API password
Sports Widget
- Live scores for NFL, NBA, MLB, and college sports
- Uses ESPN's free API (no authentication needed)
- Filter to show only your favorite team's games
- Team logos and game status
- Live games highlighted
- Auto-refresh every minute
- Drag to reorder leagues in Settings
- Configure leagues and favorite teams in Settings
Tabbed Widgets
- Combine any widgets into tabbed groups
- Custom tab labels
- Reorder tabs
- Drag handle for moving the entire group
- Widgets in groups remain configurable
Header Widgets
- 4 Positions Available: Left (next to title), Middle (center), Center, Right (before buttons)
- Compact Widgets: Time, Weather, Search, Stock Ticker, FreshRSS, Navidrome
- Time: Shows current time, respects 12h/24h preference
- Weather: Shows temperature, respects C/F preference
- Search: Mini search bar, inherits search engine from main Search widget settings
- Stock Ticker: Scrolling ticker with market indices and stocks
- FreshRSS: Unread article count
- Navidrome: Currently playing track name and artist
- Configure via Settings > Preferences > Header Widgets
Stocks Widget
- Real-time stock quotes via Finnhub API
- Market indices (S&P 500, Dow Jones, NASDAQ, etc.)
- Custom watchlist with add/remove symbols
- Price, change, and percentage display
- Auto-refresh every 3 minutes
- Requires free Finnhub API key from finnhub.io
- Configure API key, symbols, and markets in Settings
Last.fm Widget
- Recent scrobbles with album art
- "Now Playing" indicator for live listening
- Lifetime stats (total scrobbles, artists, tracks, albums)
- Optional top artists and tracks sections
- Requires Last.fm API key and username
News Widget
- Aggregated top stories from multiple sources
- Sources: NPR, NYT, BBC, The Guardian, Reuters
- Auto-refresh every 5 minutes
- Source badges and timestamps
- Click to open articles in new tab
YouTube Widget
- Support for up to 3 channels with single API key
- Display channel statistics (subscribers, views, videos)
- Compact list view for multiple channels
- Expanded stats grid when widget is large enough
- Channel reordering in settings
- Click to view channel on YouTube
- Requires YouTube Data API v3 key
- Get API key from Google Cloud Console
- Auto-refresh every 5 minutes
Speedtest Widget
- Shows 5 most recent speedtest results
- Download/upload speeds in Mbps
- Ping and server information
- Run new speedtest button in header
- Most recent test highlighted with ring
- Requires Speedtest Tracker instance URL
- API token with "Read Results" permission (generate at /admin/api-tokens)
- "Run Speedtest" permission needed for run button
Sports News Widget
- Latest sports news articles from ESPN RSS feeds
- Support for all major leagues (NFL, NBA, MLB, NCAAF, NCAAM, NCAAW)
- League badges for easy identification
- Article title, excerpt, and publish date
- Click to open full article in new tab
- Configurable maximum articles (5-50)
- Auto-refresh every 5 minutes
- No API key required
Linkding Widget
- Display recent bookmarks from self-hosted Linkding instance
- Mark bookmarks as read/unread with one click
- Archive bookmarks directly from widget
- Load more pagination for browsing entire bookmark list
- Visual indicator for unread bookmarks
- Tag display (up to 3 tags shown)
- Description and title preview
- Requires Linkding URL and API token
- Configurable initial load count (5-50)
Claude Usage Widget
- Real-time Claude API usage statistics
- Total tokens used and estimated costs
- Usage breakdown by model (Opus, Sonnet, Haiku, etc.)
- Input/output token counts per model
- Percentage changes for metrics
- Auto-refresh every 5 minutes
- Requires Admin API key (starts with sk-ant-admin...)
- Organization ID from Claude Console
Umami Analytics Widget
- Multi-website support: Track multiple Umami websites in one widget
- Website selector dropdown (selection persists across reloads)
- Key metrics: Page views, Visitors, Visits, Average time
- Percentage changes comparing to previous period
- Top 5 pages with view counts
- Auto-refresh every 5 minutes
- Works with self-hosted Umami or Umami Cloud
- Each website has its own URL, Website ID, username, and password
- Add/remove websites through widget settings
Home Lab Widget
- Comprehensive system monitoring with 10+ metrics
- CPU: Usage percentage, core count, temperature
- Memory: Usage with total/used/free breakdown
- Swap: Usage (only shown if configured)
- Network: Real-time download/upload speeds (MB/s)
- Disk I/O: Real-time read/write speeds
- Load Average: 1, 5, and 15-minute system load
- Processes: Total, running, and sleeping process counts
- Storage: All mounted disks with individual usage bars
- System Info: Hostname, OS distribution, release, kernel
- Uptime: System uptime display
- Auto-refresh every 5 seconds
- Background refresh with no loading spinners
- Color-coded status indicators (green/yellow/red based on usage)
Navidrome Widget
- Connect to Navidrome or any OpenSubsonic-compatible server
- Display currently playing music with album art
- Shows track title, artist, album, year, and genre
- User information and playback time
- Auto-refresh every 10 seconds
- Configure via Settings with server URL, username, and password
- Available as both full widget and compact header widget
- Mini header widget shows track name and artist
Mastodon Widget
A comprehensive Mastodon client built into your homepage with full social media capabilities:
Features
- Dual Timeline Views:
- Home timeline - posts from people you follow
- Mentions - notifications when you're mentioned
- Internal Tabs: Tab navigation works seamlessly in widget groups
- Unread Mention Tracking: Red notification badge shows unread mention count
- Compose Toots: Full-featured post composer with:
- 500-character limit with live counter
- Media uploads (up to 4 images, 10MB each)
- Alt text for accessibility
- Content warnings (spoiler text)
- Visibility options (Public, Unlisted, Followers only, Direct)
- Post Interactions:
- ❤️ Favorite/unfavorite (heart/unheart)
- 🔄 Boost/unboost (reblog)
- 💬 Reply to toots
- 🔗 View on Mastodon instance
- Real-time Updates: Optimistic UI updates with instant visual feedback
- Smart Caching: 3-minute refresh with 1-minute server-side cache to prevent rate limiting
Configuration
Requires Mastodon access token with the following scopes:
read:statuses- View timelinesread:notifications- View mentionswrite:statuses- Post toots and replieswrite:media- Upload media attachmentswrite:favourites- Like/unlike posts
How to get an access token:
- Go to your Mastodon instance (e.g., mastodon.social, fosstodon.org)
- Settings → Development → New Application
- Name it (e.g., "Homepage Widget")
- Select the scopes listed above
- Click Submit and copy the access token
- Paste into widget settings in Settings → Widgets → Mastodon
Usage
- Auto-refreshes every 3 minutes
- Click Compose button to create new posts
- Click on any post's interaction buttons to favorite, boost, or reply
- Mention badge automatically clears when you view the Mentions tab
- Works seamlessly in tabbed widget groups with persistent tab state
Global Search
A quick-access search modal that lets you search from anywhere on your homepage:
- Keyboard Shortcut: Press
Ctrl+K(orCmd+Kon Mac) to open instantly - Header Button: Click the search icon in the header (between Edit and Theme buttons)
- Floating Interface: Clean, centered modal with backdrop blur effect
- Inherits Settings: Automatically uses your Search widget configuration:
- Search engine (Google, DuckDuckGo, or SearXNG)
- Custom SearXNG instance URL
- Open in new tab preference
- Custom placeholder text
- Keyboard Navigation: Press
Enterto search,Escto close - Auto-focus: Input field automatically focused when opened
- Customizable: Change the keyboard shortcut in Settings → Keys
Custom Theme Creator
Create your own personalized themes with full control over all colors:
Features
- Visual Color Pickers: Edit all 8 theme colors with live preview
- Color Options:
- Primary (accent color)
- Primary Hover (hover state)
- Background (main background)
- Background Secondary (widget backgrounds)
- Background Tertiary (subtle backgrounds)
- Text Primary (main text)
- Text Secondary (muted text)
- Border (dividers and outlines)
- Dual Input: Visual color picker + manual hex code entry for each color
- Dark/Light Mode: Toggle to mark your theme as dark or light
- Live Preview: See color swatches update in real-time
- Smart Initialization: New themes start with your current theme's colors
Organization
- Built-in Themes Tab: Browse and activate 40+ pre-made themes
- Custom Themes Tab: Manage your created themes
- View all custom themes in a grid
- Use/activate any custom theme
- Edit existing themes
- Delete themes you no longer need
- See which theme is currently active
- Theme Editor Tab: Create new themes or edit existing ones
- Full color customization interface
- Save or cancel changes
- Name your themes
Protection
- Built-in themes are read-only (cannot be edited or deleted)
- Only custom themes can be modified or removed
- Automatic fallback to a default theme if you delete the active one
- All custom themes are included in backups and exports
Tech Stack
- Frontend: React + TypeScript + Tailwind CSS + Vite
- Backend: Node.js + Express + TypeScript
- Database: SQLite
- Layout: react-grid-layout for drag-and-drop
- Icons: Lucide React
- Containerization: Docker
Development
# Install dependencies
npm install
# Run client only
npm run dev:client
# Run server only
npm run dev:server
# Build for production
npm run build
License
MIT