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. 🚀