Skip to content
warmboPublic

About

A lean, self-hosted new tab page with glassmorphic + skeuomorphic styling. Card-based layout with multi-page support, fully customizable from the UI.

Resources

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Latest commit

 

History

72 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚔️ WarTab — Self-Hosted New Tab Page

A fast, self-hosted personal startpage, command palette, bookmark manager, and service dashboard. Card-based, multi-page, keyboard-friendly, and configurable without a production build step. Entirely self-contained — no external network required once loaded.

🌐 GitHub:  https://github.com/warmbo/wartab
🌐 Forgejo: https://forgejo.example.com/cody/wartab   (replace with your instance)
http://localhost:8081   or   http://<your-ip>:8081

Features

Multi-Page Dashboard

  • Create, rename, and delete pages via the page bar
  • Each page has its own set of cards, icon, and custom title
  • Keyboard-driven page switching with Ctrl+Tab
  • Empty pages show a helpful placeholder with an add-card prompt

Command Palette

Press Ctrl+K or Ctrl+P for a Spotlight-style launcher: fuzzy-search every page, link, and app action (new card, new page, arrange, settings, shortcuts) and run it with Enter. Type-ahead ranks results, highlights matches, and opens links in a new tab or switches pages in place.

PWA & Offline

WarTab is installable as a real app (manifest + icons + service worker). The app shell and immutable assets are cached offline-first, so repeat loads are near-instant and the dashboard works with no network after first load.

Unified Site Context Menu

Right-click anywhere in WarTab for a single target-aware menu rendered above every panel and overlay. Links get open/copy/edit/delete actions; cards get edit, arrange, duplicate, JSON export, and delete; page chrome and blank space expose Command, Add Card, Arrange, Pages, Settings, and Reload. Native cut/copy/paste remains available inside text inputs and Notes editors.

Personal Command Deck

The shell now centers daily actions around a visible Command trigger, prominent Add button, compact telemetry disclosure, undo/redo, and a single overflow menu. Cards render as one of five semantic visual roles: Launcher, Metric, Canvas, Feed, or Ambient.

  • Card Gallery — search and filter all modules, see purpose/setup/manual-size guidance, or apply a first-run page template.
  • Edit Mode — select cards directly and open common or advanced editing tools.
  • Layout Studio — preview manual width, height, mobile visibility, and mobile order changes; nothing mutates until Apply layout.
  • Experience Presets — Command Center, Dense Homelab, Calm Minimal, Ambient Glass, and Mobile First; presets never move or resize cards.
  • Mobile profiles — explicit per-card hide/order controls independent of desktop geometry.

Command accepts bookmarks, pages, cards, actions, direct URLs/IPs, and scoped input:

  • g proxmox clustering, yt home server build, ddg privacy tools
  • @server plex to search service/bookmark targets
  • > settings to restrict results to actions
  • 192.168.1.100 or a hostname to open a direct address

Operational cards use shared healthy/warning/degraded/offline/unknown states, concise latency context, expandable details, and checked/stale timestamps. Weather includes condition, high, low, precipitation probability, forecast, and freshness without becoming a full weather application.

Card Sections (24 types)

Section Description
Links Icon grid — auto-fill columns, per-link icons with Lucide/library/upload/emoji support
Link List Single-column inline link rows
Search Inline search bar with per-section engine selector (Google, DuckDuckGo, Bing, etc.)
Clock Live time (12/24h) + date + optional calendar
Weather Cached Open-Meteo conditions, high/low, precipitation, wind, and forecast — no API key
Iframe Embed any self-hosted app (Home Assistant, Jellyfin, Grafana)
Notes Inline editing directly on the card (click to type, Esc to finish)
Quotes User-defined quotes with author attribution. Click to cycle.
Timer Hours/minutes dropdown-set countdown with Start/Reset
API Poller Fetch JSON from any endpoint, extract a value via dot-path, auto-refresh
RSS Feed Render recent RSS/Atom headlines through the server proxy
Agenda Read a public iCal feed and list upcoming events
Service Status Monitor HTTP services with summary health, latency, detail, and freshness
Network Check gateway, DNS, and internet reachability with summary latency
Markdown Render safe static Markdown content
Smart Links Local-only most-used or recently-used dashboard links

Icon System — 2,000+ Icons

  • Lucide SVG — 2,000+ vector icons, color-matched to your theme
  • Selfh.st service icons — 350+ self-hosted app logos (Jellyfin, Home Assistant, Portainer, etc.) — organized in a searchable Services tab
  • Emoji — 500+ system emoji in the Icons tab
  • Upload — upload custom icon images (auto-resized to 256×256)
  • CDN Discovery — preview icons from the selfh.st CDN before downloading locally

All icons — card titles, link items, page tabs, and branding — use the same unified picker.

Manual Card Arrangement

  • Quick Arrange provides keyboard/touch directional movement.
  • Layout Studio stages width, height, mobile visibility, and mobile order.
  • Geometry changes apply only after explicit confirmation and can be undone.
  • WarTab never automatically resizes, spans, packs, or reorders a user's cards.

Edit Panel (per-card)

A slide-out right panel for editing individual cards:

  • Title — editable text field
  • Icon — unified picker (Lucide + Services + Emoji + Upload), Change/Clear buttons with live preview
  • Color — color picker + hex input, sets the card's accent bar
  • Width/Height — slider controls, height up to 2 rows
  • Sections — add, reorder (drag), delete. Each section has inline label + type selector
  • Module-specific editors — tailored fields per section type (link table, clock checkboxes, weather API config, etc.)
  • Save / Discard / Delete footer with confirmation modal and undo toast

Config Panel (global)

A slide-out right panel organized into card-like sections:

Section Controls
Page Title, icon
Background Type (gradient/solid/image), value/URL, upload, previous images, random rotation toggle
Appearance Card style (dark/light), card transparency, accent color, glass blur (px), animations toggle, accent bar toggle
Typography Font color, font size (small/medium/large), font family — 30 Google Fonts, all pre-loaded
Status Bar Enable/disable, source (local/Glances/custom URL), refresh interval, items selector (hostname/CPU/memory/disk/uptime)
Layout Columns (1–6), card gap (px), page width (full/3/4/half), page height (full/compact)
Data Export (download JSON), Import (file upload), Reset (with confirm + undo toast)
API Keys Reference info for OpenWeatherMap and other services

Keyboard Shortcuts

Key Action
Ctrl+K or Ctrl+P Open command palette (search pages, links, actions)
Ctrl+L Focus first search bar
Ctrl+Shift+C Toggle config panel
Ctrl+N New card
Ctrl+Shift+N New page
Ctrl+Tab Cycle to next page
Escape Close any open panel (config/edit/icon picker/palette)

System Stats Endpoint

Built-in /api/stats endpoint — CPU, memory, disk, uptime, load — all from /proc with zero Python dependencies (no psutil). Returns JSON for the status bar widget.

Offline Capable — After First Setup

All assets can be shipped with the repo or downloaded on demand:

  • Lucide icon library — 602KB (/static/lucide.min.js), included in repo
  • Inter font — weights 200–700 (/static/fonts/), included in repo
  • Service icons — 350+ SVG icons downloaded from selfh.st CDN during setup (python3 download_icons.sh)
  • Quotes — user-defined only, no network calls

Only the Font Family's non-Inter options require network (Google Fonts), and external integration endpoints; built-in weather uses Open-Meteo without a key.


Project documentation

Distribution note: WarTab does not yet include a selected open-source license. Do not assume redistribution rights until the maintainers add one.


Quick Start

Option 1: One-Command Install (Debian)

Works on a clean Debian install — installs everything automatically:

curl -sL https://github.com/warmbo/wartab/raw/main/setup.sh | bash

This single command:

  • Installs Python 3, git, Pillow, and Avahi/mDNS
  • Clones WarTab to /opt/wartab
  • Creates an initial config.json from defaults
  • Downloads service icons from selfh.st
  • Starts WarTab as a systemd user service with mDNS advertising
  • Enables linger (keeps running after logout)

Result: WarTab is live at http://localhost:8081.

Option 2: Docker

# Build and run
docker build -t wartab .
docker run -d \
  --name wartab \
  -p 8081:8081 \
  -v "$(pwd)/wartab-data/config.json:/app/config.json" \
  -v "$(pwd)/wartab-data/notes:/app/notes" \
  -v "$(pwd)/wartab-data/uploads:/app/uploads" \
  wartab

# Or with Docker Compose
docker compose up -d

Data files appear in wartab-data/ for easy editing.

Option 3: Manual (Python)

Zero dependencies beyond Python stdlib:

git clone https://github.com/warmbo/wartab.git
cd wartab
cp config.example.json config.json          # optional — server falls back to defaults
python3 server.py --port 8081 --open         # --open opens browser automatically
# python3 server.py --port 8081 --mdns       # advertise via mDNS (install avahi-utils)

The server works even without config.json — it serves built-in defaults on first run.

Browser Extension

WarTab also ships as a browser extension for Chrome, Edge, and Firefox. See extension/INSTALL.md for installation instructions.


Post-Install: Access & Setup

From the Machine Itself

http://localhost:8081

From Any Device on Your LAN

If you installed with Option 1 (setup.sh), mDNS is already configured:

http://<hostname>.local:8081

If you installed manually, install Avahi and run the server with --mdns:

sudo apt install avahi-utils
python3 server.py --port 8081 --mdns

Setting as Your Browser's New Tab

Browser Method
Firefox Install "New Tab Override" → set URL to http://<hostname>.local:8081
Chrome/Edge/Brave Install "New Tab Redirect" → set URL to http://<hostname>.local:8081

Run as a Systemd Service (persistent background)

systemctl --user daemon-reload
systemctl --user enable --now wartab.service
journalctl --user -u wartab.service -f    # follow logs

If you used Option 1, this is already done for you.


Configuration

Config is stored server-side in config.json via the /api/config endpoint. Changes made in the UI are saved automatically with navigator.sendBeacon. Export, import, and reset are available from the config panel's Data section.

Multi-device: point multiple browsers to the same WarTab server to share config.


File Structure

wartab/
├── index.html         # App shell
├── style.css          # Glass + skeuomorphic styles
├── app.js             # All logic: render, pages, config, drag-drop, widgets
├── storage.js         # Storage adapter (server or browser extension)
├── server.py          # Python HTTP server (zero deps)
├── Dockerfile         # Container build
├── docker-compose.yml # Container orchestration
├── download_icons.sh  # Fetches service icons from selfh.st CDN
├── setup.sh           # Debian install script
├── manifest.json      # Chrome extension manifest
├── config.json        # Server-side config (auto-managed)
├── icons/             # 2,363 SVG service icons (selfhst/icons) + extension icons
├── static/
│   ├── lucide.min.js  # Lucide icon library (local copy, 602KB)
│   └── fonts/         # Inter font files + CSS
├── modules/           # Pluggable card section modules
├── notes/             # Notes saved as .md files
├── uploads/           # User-uploaded background images
├── extension/         # Browser extension build files and manifests
├── PLAN.md            # Architecture design document
├── HIERARCHY.md       # Component tree & class naming reference
└── README.md          # This file

Single-page app — no framework, no build step, no node_modules. Just open and go.


Architecture

  • Storage: Server-side config.json via REST API (/api/config). No database. Fire-and-forget saves via navigator.sendBeacon. Config syncs across devices.
  • Server: Python http.server — single file, no pip deps. Handles static files, config CRUD, image upload/resize (PIL optional), stats endpoint, and icon saving.
  • Icons: Lucide SVGs (2,000+) + selfhst/icons SVGs (350+) + system emoji (500+). Dynamic lucide.icons detection — always uses the complete runtime set.
  • Card System: CARD_MODULES registry — each section type owns { defaults, render, editor }. Add new types without touching core rendering.
  • Pages: Config is organized into config.pages with config.pageOrder and config.currentPage. Cards live per-page. Zero-touch repointing of config.cards.
  • Theming: CSS custom properties for accent, glass blur, font, card style — all togglable from the UI. Dark/light modes with dynamic opacity blending.
  • Drag & Drop: Pointer Events API, simGrid CSS Grid auto-placement simulation, FLIP animations, column-snap logic with grab-offset tracking.

For a deeper look at the component hierarchy and data model, see HIERARCHY.md and PLAN.md.


Development

Dual-Remote Push

Every commit must be pushed to both remotes:

git push github <branch>
git push origin <branch>   # Forgejo
Alias Target
github github.com/warmbo/wartab
origin self-hosted Forgejo remote (e.g. forgejo.example.com/cody/wartab)

Versioning & Cache Busting

All <script src> and <link rel="stylesheet"> tags in index.html use ?v=BUILD as a placeholder. The server (server.py) automatically replaces BUILD with the current git describe --always --tags --dirty output at serve time.

This means:

  • Every deploy automatically gets a unique cache-busting version
  • No manual version string updates needed
  • Browsers always fetch fresh assets after a server restart
  • The footer displays the same git hash as the build version

The server reads GIT_VERSION at startup from git describe. If git is unavailable, the fallback is 'dev'.

Adding a Module

  1. Create modules/<type>.js with a registerModule('type', { defaults, render, editor }) call
  2. Add the type to both picker lists in app.js:
    • Section editor type selector (around line 760)
    • New card modal (around line 2140)
  3. Add a <script src="modules/<type>.js?v=BUILD" defer> to index.html
  4. Commit and dual-push to both remotes

Branches

Branch Purpose
main Self-hosted server version (current)
extension Browser extension variant — rewrites storage.js for chrome.storage, patches proxy-based fetches to direct fetch, stubs server-only features

See extension/PLAN.md for the full extension implementation plan.

About

A lean, self-hosted new tab page with glassmorphic + skeuomorphic styling. Card-based layout with multi-page support, fully customizable from the UI.

Resources

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages