Source-available, self-hosted digital signage for the places people gather.
Restaurants, churches, schools, event venues, and community spaces.
DisplayGrid gives you full control over your screens without a cloud subscription, recurring fees, or vendor lock-in.
Native installers are published automatically on each release via GitHub Actions.
The Server App is fully self-contained: on first launch it creates its database automatically and opens the dashboard in a native window — no Node.js, terminal, or manual setup required.
| Platform | Download |
|---|---|
| Windows | DisplayGrid-Server-Setup.exe |
| macOS (Universal) | DisplayGrid-Server.dmg |
| Linux x64 AppImage | DisplayGrid-Server-x86_64.AppImage |
| Linux x64 Debian | DisplayGrid-Server-amd64.deb |
| Platform | Download |
|---|---|
| Windows | DisplayGrid-Kiosk-Setup.exe |
| macOS (Universal) | DisplayGrid-Kiosk.dmg |
| Linux x64 AppImage | DisplayGrid-Kiosk-x86_64.AppImage |
| Linux x64 Debian | DisplayGrid-Kiosk-amd64.deb |
Raspberry Pi: See the Raspberry Pi Setup Guide to run the kiosk using Chromium in kiosk mode.
| Screens dashboard | Playlist manager |
![]() |
![]() |
| Asset library | Multi-zone layout editor |
![]() |
![]() |
| Display client (kiosk view) | |
![]() |
|
- Multi-screen management: configure resolution, refresh rate, rotation, colour profile, and panel grid per screen
- Zone-based organisation: group screens into named zones (lobby, corridor, reception)
- Playlist builder: drag-and-drop slides with per-slide durations, transitions, and day/time scheduling
- Asset library: upload images, videos, and PDFs with automatic WebP optimisation via Sharp
- Real-time delivery: WebSocket server pushes playlist updates to displays instantly
- Screen health monitoring: live online/offline status, last-seen timestamps, and client IP
- Emergency override: broadcast a full-screen alert to every display simultaneously
- Kiosk lock: PIN-protected overlay with configurable key combo; no browser chrome visible
- Offline resilience: display clients cache their last playlist and keep playing through network outages
- Role-based access: Super Admin, Admin, Operator, Viewer
- LED wall support: define panel grids (e.g. 3×2) for tiled display configurations
- Multi-zone layouts: split a screen into independently controlled regions, each with its own playlist
- Time-based scheduling: restrict slides to specific days and time windows; server re-evaluates every minute
- Standalone apps: native installers for Windows, macOS (Universal), and Linux — the server app opens the dashboard in a native window and keeps running in the background via the system tray and macOS dock when the window is closed; a dedicated kiosk app runs displays fullscreen with no browser configuration required; Raspberry Pi users can follow the RPi setup guide
- NDI source support: stream live video from NDI devices on the network directly to any display
| Layer | Technology |
|---|---|
| Dashboard | Next.js 14 (App Router), Tailwind CSS |
| Database | SQLite · Drizzle ORM · better-sqlite3 |
| Auth | NextAuth v5 (JWT, edge-safe) |
| Real-time | Node.js ws WebSocket server |
| Display client | Vite + React |
| Monorepo | Turborepo + pnpm workspaces |
| Image processing | Sharp (WebP, JPEG, PNG, AVIF) |
- Node.js 18 or 20 LTS
- pnpm 10+
- Chromium or Google Chrome on display client machines
- A machine to act as the server (Raspberry Pi 4/5, mini PC, or any always-on device)
git clone https://github.com/JoeMighty/DisplayGrid.git
cd DisplayGrid
pnpm installConfigure the dashboard:
cp apps/dashboard/.env.example apps/dashboard/.env.localEdit apps/dashboard/.env.local:
NEXTAUTH_SECRET=<node -e "console.log(require('crypto').randomBytes(32).toString('hex'))">
NEXTAUTH_URL=http://localhost:3000
DB_PATH=/absolute/path/to/DisplayGrid/data/displaygrid.dbCreate the database:
mkdir -p data
pnpm db:migrateStart:
# Terminal 1: dashboard (port 3000) + display client (port 5173)
pnpm dev
# Terminal 2: WebSocket server (port 3001)
node apps/dashboard/ws-server.jsOpen http://localhost:3000 and follow the first-run setup wizard.
For a cleaner dev URL (http://displaygrid.test instead of http://localhost:3000):
# Windows: run PowerShell as Administrator
.\scripts\add-hosts.ps1# macOS / Linux
sudo ./scripts/add-hosts.shThen optionally run Caddy for clean URLs without a port number:
caddy run --config CaddyfileSee docs/SETUP.md for the complete setup guide.
DisplayGrid/
├── apps/
│ ├── dashboard/ # Next.js dashboard (port 3000)
│ │ ├── src/app/ # App Router pages and API routes
│ │ └── ws-server.js # WebSocket server (port 3001)
│ └── display-client/ # Vite/React kiosk client (port 5173)
├── packages/
│ ├── db/ # Drizzle schema + SQLite client
│ └── shared/ # Constants shared across apps
├── data/ # SQLite database + uploaded assets (gitignored)
├── docs/ # GitHub Pages site + setup guides
├── scripts/ # Hosts file setup (add-hosts.ps1 / .sh)
└── Caddyfile # Optional reverse proxy for clean URLs
| Minimum | Recommended | |
|---|---|---|
| Device | Raspberry Pi 4 (2 GB) | Raspberry Pi 5 (4 GB+) or mini PC |
| OS | Any Linux, macOS, Windows | Same |
| Storage | 8 GB+ SD / SSD | 32 GB+ SSD |
Any device running Chromium in kiosk mode:
| Device | Suitable for |
|---|---|
| Raspberry Pi 5 | 4K content, smooth video |
| Raspberry Pi 4 | 1080p images and web slides |
| Mini PC / NUC | Any resolution |
| Old laptop or Mac mini | Any resolution |
chromium-browser --kiosk --noerrdialogs --disable-infobars \
http://<server>:5173Add to /etc/xdg/lxsession/LXDE-pi/autostart for boot autostart.
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--kiosk --noerrdialogs --disable-infobars \
http://<server>:5173Add as a Login Item in System Settings → General → Login Items.
Create a shortcut with target:
"C:\Program Files\Google\Chrome\Application\chrome.exe" --kiosk --noerrdialogs --disable-infobars http://<server>:5173
Copy to shell:startup to run on login.
Unlock kiosk: Hold Ctrl+Alt+K for 3 seconds to open the admin panel.
For kiosks on separate machines, point the display client at the server's IP:
# apps/display-client/.env.local
VITE_API_BASE=http://192.168.1.10:3000
VITE_WS_BASE=ws://192.168.1.10:3001
# Pre-configure token to skip the token entry screen
VITE_SCREEN_TOKEN=your-screen-token-hereSee docs/SETUP.md for cross-VLAN and firewall configuration.
| Role | Can do |
|---|---|
| Super Admin | Everything, including deleting users and assigning any role |
| Admin | Manage all content and users (cannot delete users) |
| Operator | Manage screens, playlists, assets (no user management) |
| Viewer | Read-only access to all content pages |
Issues and pull requests are welcome. Please open an issue before starting significant work so we can discuss the approach.
DisplayGrid is designed for community gathering places: restaurants, churches, schools, and event venues.
These aren't just intentions — they are binding license terms. DisplayGrid is licensed under the Hippocratic License 3.0 with the Mass Surveillance, Military Activities, and Law Enforcement modules, which prohibit using it for surveillance programs, military activities, or providing services to law enforcement agencies. Facial recognition and other biometric monitoring fall under the license's privacy and mass-surveillance clauses.
Hippocratic License 3.0 (HL3-LAW-MIL-SV) — free to use, modify, and distribute, including commercially, subject to the ethical conditions above. This makes DisplayGrid source-available rather than OSI open source.
Releases up to and including v1.0.18 were published under the MIT License and remain available under it.
By JoeMighty




