The Problem
Users who want a single self‑hosted dashboard for calendars, notes, finances, and habit tracking must stitch together many separate SaaS tools, each with its own login, data export, and UI inconsistencies. Maintaining that ecosystem on‑premises is tedious, especially when UI styles clash across independently built modules.
What This Does
LifeForge is a modular React host that loads feature modules via Webpack Module Federation. The host lives in client/ (entry client/src/App.tsx) and pulls in modules such as the account settings UI (client/src/core/accountSettings/…) and the dashboard widget system (client/src/core/dashboard/…).
The Docker layout (docker/) builds three containers:
docker/client/Dockerfile – bundles the React app with Vite and serves it via Nginx. docker/db/Dockerfile – runs PocketBase (the embedded DB) with an init script (docker/db-init/entrypoint.sh). docker/server/Dockerfile – an Express gateway that proxies API calls to PocketBase.
All containers are orchestrated by docker-compose.yaml, which defines the network, volume mounts for persistence, and environment variables (e.g., POTATODBURL inside the DB container).
A critical architectural note in the README warns that the original Tailwind‑based styling caused cascade‑layer conflicts across federated modules. PR #93 replaces Tailwind with a token‑driven UI library, introducing breaking changes but restoring deterministic styling.
How To Use It
Setup
Install Node tooling for the client (uses pnpm if a lockfile existed; otherwise npm) cd client npm install # reads client/package.json Build the Docker images and start the stack cd .. # repository root docker compose up --build -d
If you prefer a local dev server instead of Docker, run npm run dev inside client/ – the script is defined in client/package.json.
Configuration
PocketBase – the DB expects a POTATODBURL env var (set in docker-compose.yaml). No additional config files are shipped; create a .env at the repo root if you need to override defaults. UI Migration – after PR #93, the host imports the new UI library from client/src/core/personalization/…. Ensure any custom modules you add import the same token set to avoid the previous Tailwind conflict.
Running
Host UI: open http://localhost:3000 (exposed by the Nginx container). API gateway: http://localhost:4000/api (Express server). PocketBase admin UI: http://localhost:8090/_/ (default PocketBase port).
Real‑World Use
A small startup can deploy LifeForge on a single VM to replace separate SaaS dashboards. After bringing up the stack, the team creates a “Finance” module under client/src/modules/finance/ that registers its routes via client/src/federation/loaders/loadModules.ts. The module consumes the shared APIKeyStatusProvider and persists data in PocketBase without additional infrastructure.
// Example: finance module entry point export const registerFinance = () => ({ name: 'finance', route: '/finance', component: lazy(() => import('./FinanceDashboard')), });
Code Health & Issues
Medium – Untested code – No .test. files in the 200‑file codebase; CI (.github/workflows/build.yml) only builds Docker images, no unit/integration tests. Low – Missing lockfile – client/package.json is present but no package-lock.json or pnpm-lock.yaml; reproducible installs rely on the exact state of the npm registry. Medium – Incomplete CI – Build workflow runs on pushes but does not lint, type‑check, or run security scans (e.g., npm audit). Low – Documentation gaps – README explains the Tailwind issue but lacks explicit env‑var definitions for the Express server and PocketBase. Medium – Potential runtime errors – Several modal components (EnableTwoFAModal, QRLoginScannerModal) import hooks that assume a valid QR session; error handling for failed scans is minimal.
The Bottom Line
LifeForge provides a functional, containerized React host with a clear module‑federation architecture, suitable for teams that need a unified self‑hosted dashboard and are comfortable maintaining Docker services. However, the current codebase lacks automated testing, lockfile hygiene, and comprehensive CI checks, which raises maintenance risk. Consider adopting a testing framework and adding a lockfile before using it in production environments.