Skip to content

Repository files navigation

Limb

LicenseReactNodeDockerReleaseBuy Me a Coffee

A self-hosted iOS springboard-style dashboard for your home services. Organize apps, bookmarks and widgets on a paginated grid with drag-and-drop, search and full JSON persistence.

ReactViteExpressDocker

imageimage

Features

  • Paginated grid - swipe or arrow-key between pages, free-placement coordinate layout.
  • Drag & drop - reorder apps across pages with live drop preview.
  • Search - full-screen instant search overlay.
  • App management - add, edit, delete apps from the web UI. Drop an external URL onto the grid to auto-create an app with its favicon.
  • Folders - group apps into folders via a modal overlay.
  • Widgets - load custom widgets from the gallery/ directory. Supports JSON and TSX widget formats, rendered in shadow DOM.
  • Uploads - custom icons and wallpapers uploaded through the settings panel.
  • Themes - glassmorphism UI, icon shape selection (square, rounded, circle), adjustable grid spacing.
  • Weather chip - optional weather display with city-based lookup (toggleable).
  • Localization - persistent EN / FR switch.
  • PWA - installable on iPhone / Android home screen with proper icons and manifest.
  • Backup - full export / import with base64-encoded assets and automatic daily snapshots (retention: 10).
  • Dashboard branding - customizable dashboard name, page title, and favicon.

Tech Stack

LayerTechnology
FrontendReact 18, Vite 5
BackendExpress 4, Node.js 20+
PersistenceJSON file (data/dashboard.json)
UploadsMulter → public/uploads/
WidgetsShadow DOM runtime, TSX/JSON

Project Structure

home_dashboard/
├── server/
│ ├── index.js # Express API + static file serving
│ └── storage.js # JSON persistence, backup, gallery management
├── src/
│ ├── App.jsx # Main dashboard state & rendering
│ ├── i18n.js # EN/FR translations
│ ├── lib/
│ │ └── api.js # Client-side API wrappers
│ └── components/
│ ├── AppTile.jsx
│ ├── FolderOverlay.jsx
│ ├── FolderTile.jsx
│ ├── SearchOverlay.jsx
│ ├── SettingsModal.jsx
│ └── ShadowWidget.jsx
├── gallery/ # Widget source files (JSON, TSX)
├── public/
│ ├── icons/ # PWA icons
│ ├── uploads/ # User-uploaded icons & wallpapers
│ ├── manifest.webmanifest
│ └── sw.js # Service worker (app shell only)
├── data/
│ └── dashboard.json # Persisted dashboard state
├── backups/ # Automatic daily snapshots
├── Dockerfile
├── docker-compose.yml
├── vite.config.js
├── package.json
└── index.html

Getting Started

Docker (recommended)

No need to clone the repository. Just create a docker-compose.yml anywhere on your machine:

services:
limb:
image: ghcr.io/infinition/limb:latestcontainer_name: limbrestart: unless-stoppedports:
- "8090:3001"volumes:
- ./data:/app/data
- ./backups:/app/backups
- ./gallery:/app/gallery
- ./uploads:/app/public/uploadsenvironment:
- NODE_ENV=production
- PORT=3001

Then run:

docker compose up -d

That's it. The dashboard is accessible at http://<host>:8090.

To update to the latest version:

docker compose pull && docker compose up -d
Optional: automatic updates with Watchtower

Add this service to your docker-compose.yml to automatically pull new versions every 5 minutes:

watchtower:
image: containrrr/watchtowercontainer_name: watchtower-limbrestart: unless-stoppedvolumes:
- /var/run/docker.sock:/var/run/docker.sockenvironment:
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_POLL_INTERVAL=300command: limb
NAS / custom volume paths

If your data directory is elsewhere (e.g. Synology NAS), adjust the volume paths:

volumes:
- /volume1/docker/limb/data:/app/data
- /volume1/docker/limb/backups:/app/backups
- /volume1/docker/limb/gallery:/app/gallery
- /volume1/docker/limb/uploads:/app/public/uploads

Local Development

For contributors who want to work on the code:

git clone https://github.com/infinition/limb.git
cd limb
npm install
npm run dev

This starts both the Express API on http://localhost:3001 and the Vite dev server on http://localhost:5173.

Environment Variables

VariableDefaultDescription
PORT3001Server listening port
NODE_ENV-Set to production for optimized serving

API

MethodEndpointDescription
GET/api/dashboardFetch dashboard state + widget library + assets
PUT/api/dashboardSave dashboard state
POST/api/upload/iconUpload an icon
POST/api/upload/wallpaperUpload a wallpaper
DELETE/api/upload/icon/:nameDelete an icon
DELETE/api/upload/wallpaper/:nameDelete a wallpaper
GET/api/widgets/galleryList available widgets
POST/api/widgets/gallerySave a widget to the gallery
POST/api/widgets/importImport a widget file
DELETE/api/widgets/gallery/:fileDelete a widget
PUT/api/widgets/:id/stateSave widget instance state
GET/api/backup/exportDownload full backup bundle
POST/api/backup/importRestore from a backup bundle

Adding Widgets

Place a .json or .tsx file in the gallery/ directory.

JSON format:

{
"name": "My Widget",
"description": "A simple counter",
"defaultW": 2,
"defaultH": 2,
"html": "<div id=\"root\">0</div>",
"css": "#root { font-size: 2rem; text-align: center; }",
"js": "let c=0; document.getElementById('root').onclick=()=>{document.getElementById('root').textContent=++c;}"
}

Widgets can also be imported directly from the Settings panel.

License

MIT

Star History

Star History Chart

About

A self-hosted iOS springboard-style dashboard for your home services. Organize apps, bookmarks and widgets on a paginated grid with drag-and-drop, search and full JSON persistence.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages