A minimalist, highly efficient homelab dashboard that provides easy access to all your self-hosted services through a clean, monospace-styled interface. Configure your entire dashboard with a simple JSON file.
- π― JSON Configuration: Configure your entire dashboard with a single JSON file
- π¨ Monospace Aesthetic: Clean, terminal-inspired design based on The Monospace Web
- π Ultra Lightweight: < 50MB memory footprint, < 100KB JavaScript bundle
- π± Responsive Design: Works perfectly on desktop, tablet, and mobile
- π³ Docker Ready: Easy containerized deployment
- β‘ Fast Performance: Built with Bun for maximum efficiency
- π Hot Reload: Configuration changes without restart (when using volume mounts)
- Create your config directory:
mkdir -p config
curl -o config/config.json https://raw.githubusercontent.com/jbassi/dashon/main/public/config.example.json
# Edit config.json with your services
nano config/config.json- Run with Docker:
docker run -d \
--name dashon \
-p 3000:3000 \
-v $(pwd)/config:/app/config \
ghcr.io/jbassi/dashon:latest- Or use docker-compose:
curl -o docker-compose.yml https://raw.githubusercontent.com/jbassi/dashon/main/docker-compose.yml
docker-compose up -dβ¨ Hot Reload: Changes to config/config.json are reflected immediatelyβjust refresh your browser! No container restart needed.
- Install dependencies:
bun install- Create config directory:
mkdir -p config
cp public/config.example.json config/config.json
# Optionally copy icons
cp -r public/icons config/- Build and run:
bun run dev- Visit: http://localhost:3000
Dashon separates built-in files from user configuration:
- Built-in files (HTML, JS, CSS): Served from
/app/public(inside Docker image) - User config: Served from
/app/config(mounted volume)
This design enables hot reloadβedit your config and see changes instantly without restarting!
Your configuration directory should contain:
config.json(required)icons/(optional - override built-in icons)
# Create config structure
mkdir -p config/icons
cp public/config.example.json config/config.json
# Edit with your services
nano config/config.jsonYour config/ directory is automatically ignored by git to keep your configuration private.
{
"title": "My Homelab Dashboard",
"categories": [
{
"name": "Media Services",
"services": [
{
"name": "Plex",
"url": "http://localhost:32400",
"description": "Media streaming server"
}
]
}
],
"uncategorized": [
{
"name": "Router Admin",
"url": "http://192.168.1.1",
"description": "Network router interface"
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
title |
string | Yes | Dashboard title displayed at the top |
categories |
array | No | Grouped services with category names |
uncategorized |
array | No | Services without a category |
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Display name for the service |
url |
string | Yes | URL to link to |
description |
string | No | Brief description shown on tile |
image |
string | No | Path to icon/image (future feature) |
docker build -t dashon .# Create config directory first
mkdir -p config
cp public/config.example.json config/config.json
# Edit config.json with your services
# Run container with config directory mounted
docker run -d \
--name dashon-dashboard \
-p 3000:3000 \
-v $(pwd)/config:/app/config \
dashonversion: '3.8'
services:
dashon:
image: ghcr.io/jbassi/dashon:latest
container_name: dashon-dashboard
ports:
- "3000:3000"
volumes:
- ./config:/app/config # Mount config directory for hot reload
environment:
- PORT=3000
restart: unless-stoppedNote: With directory mounting, config changes are reflected instantlyβjust refresh your browser!
dashon/
βββ src/
β βββ main.ts # Application entry point
β βββ server.ts # Bun server (serves from /app/public and /app/config)
β βββ styles.css # TailwindCSS styles (source)
β βββ components/ # Frontend components
β β βββ Dashboard.ts # Main dashboard logic
β β βββ ThemeManager.ts # Theme switching
β β βββ ScrollManager.ts # Scroll functionality
β βββ types/ # TypeScript type definitions
β βββ config.ts # Configuration types
βββ public/ # Static & built files (baked into image)
β βββ index.html # Main HTML template
β βββ config.example.json # Example configuration
β βββ icons/ # Default service icons
β βββ styles.css # Built CSS (generated)
β βββ app.js # Built JS (generated)
βββ config/ # User config directory (git-ignored, mounted as volume)
β βββ config.json # Your personal configuration
β βββ icons/ # Optional: custom icons
βββ Dockerfile
βββ docker-compose.yml
βββ package.json
Key Directories:
/app/public(in container): Built application files from the Docker image/app/config(in container): User configuration mounted from host (supports hot reload!)
bun run dev- Build and start development serverbun run build- Build CSS and JavaScriptbun run serve- Start production serverbun run watch- Watch CSS changes
- Memory Usage: < 50MB container footprint
- CPU Usage: < 1% during normal operation
- Load Time: < 500ms initial page load
- Bundle Size: < 100KB total JavaScript
The dashboard uses a monospace-inspired design system. You can customize colors and spacing by modifying src/styles.css and tailwind.config.js.
You can override the default icons by placing custom icon files in your config/icons/ directory:
# Copy default icons as a starting point
cp -r public/icons config/
# Add your custom icons
cp my-custom-icon.svg config/icons/Then reference them in your config:
{
"name": "Plex",
"url": "http://localhost:32400",
"image": "/icons/plex.svg"
}Note: The server checks config/icons/ first, then falls back to the built-in icons in public/icons/.
- Fork the repository
- Create a feature branch
- Make your changes
- Test with
bun run dev - Submit a pull request
MIT License - see LICENSE file for details.
- Design inspired by The Monospace Web by Oskar WickstrΓΆm
- Built with Bun for maximum performance
- Styled with TailwindCSS
Dashon - Because your homelab deserves a beautiful, efficient dashboard. π