DEV Community

linou518
linou518

Posted on

How We Built Dashboard Lite for miniPC Bundles (Flask, Zero Dependencies)

How We Built Dashboard Lite for miniPC Bundles (Flask, Zero Dependencies)

Background

TechsFree runs an internal management dashboard — let's call it FullDash. Over time, it grew: task management, node control, family calendar, scheduler... The Flask backend hit 7,000+ lines. The frontend SPA crossed 3,800 lines.

Then came this request:

"When we sell miniPCs, we want to bundle a dashboard as a value-add service. But we don't need internal company features. Keep it simple, generic, and clean."

In other words: strip out all the TechsFree-specific logic and make something any user can run.


What to Keep, What to Cut

We listed every FullDash feature and asked: "Does a random user need this?"

Feature Keep? Reason
Project tasks Generic enough
Node management (local only) Useful for the bundled miniPC
Family calendar Company/personal-specific
Daily work scheduler Internal only
Claude usage display Service-dependent
Timeline view Internal only
Multi-node management Lite version handles only the local machine

Two features survived. Clean.


Rewrite from Scratch vs. Fork-and-Delete

We considered two approaches: copy FullDash and delete what we didn't need, or write fresh.

We chose the rewrite. The reason: FullDash's code wasn't written with deletion in mind. Its conditionals and references are deeply tangled. Cutting one thing risks silently breaking another, and verifying that nothing broke is expensive.

Server side: Flask backend went from 7,000+ lines to under 500 — and still covers all required functionality. Most of the bloat was logic that should have been separated from the start.

Frontend: A single 37KB HTML file. Zero dependencies, no CDN. Since it's meant to be bundled with a physical device, it needed to work offline.


One-Command Install with install.sh

bash install.sh 8099
Enter fullscreen mode Exit fullscreen mode

This runs:

  1. Python and dependency check
  2. systemd service file generation
  3. Service enable and start
  4. Startup verification

A user who receives the miniPC opens a terminal, runs this command, and the dashboard starts automatically on every boot. Service name: dashboard-lite. Logs: journalctl -u dashboard-lite.

The service file is generated dynamically inside the script, using realpath to avoid hardcoded paths:

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SERVICE_FILE="/etc/systemd/system/dashboard-lite.service"

cat > "$SERVICE_FILE" << EOF
[Unit]
Description=OpenClaw Dashboard Lite
After=network.target

[Service]
ExecStart=/usr/bin/python3 $SCRIPT_DIR/server.py
WorkingDirectory=$SCRIPT_DIR
Restart=always
Environment=LITE_PORT=$PORT

[Install]
WantedBy=multi-user.target
EOF
Enter fullscreen mode Exit fullscreen mode

Auto-Detecting OC_PATH

The node management feature reads OpenClaw's local config (openclaw.json). The config file location varies by install environment.

def detect_oc_path():
    candidates = [
        os.environ.get("OC_PATH"),
        os.path.expanduser("~/.openclaw"),
        "/home/openclaw/.openclaw",
        "/opt/openclaw",
    ]
    for path in candidates:
        if path and os.path.exists(os.path.join(path, "openclaw.json")):
            return path
    return None
Enter fullscreen mode Exit fullscreen mode

Environment variable takes priority; if not set, candidates are tried in order. Prioritizing "probably works" over requiring precise pre-configuration means the install script stays simpler.


Design: Erasing the "Internal Tool" Feel

FullDash is styled with TechsFree brand colors. Lite needed to feel like a generic product — neutral enough for any customer.

  • Color palette: Deep dark gray + purple accent
  • Font: System font stack (no external loading)
  • Logo: Text only (no SVG or image dependencies)

The zero-dependency constraint ended up shaping the visual design too.


Testing Checklist

Verified on a test server:

  • /api/simple-tasks → returns project list ✓
  • /api/node/status → returns active, OpenClaw v2026.2.26 ✓
  • /api/node/bots → returns local bot list ✓

Frontend: manually tested task add → complete → delete cycle. Gateway log viewer on the node page also confirmed working.


Takeaway

"Deleting" code is unglamorous, but it makes structural debt visible. This project revealed that FullDash's bloat wasn't from feature-over-feature additions — it was over-engineering features that should have been Lite-scale from the beginning.

Next time we revisit FullDash, Lite will serve as a reference for simpler implementation patterns worth back-porting.

Top comments (0)