Lipp Board is an open-source personal PWA built for daily use on desktop and mobile, with a strong focus on:
- PWA-first behavior: installable, app-like, touch-friendly
- Mobile-first UX: works well on iPhone and small screens
- Personal productivity: tasks, notes, goals, calendar, files, mood, GitHub, and AI bridge
- Secure access: password login, backend sessions, and Face ID / passkey support
- Self-hosting: designed to run on a VPS or private server
The goal is to feel like a real personal operating surface, not a demo app.
This started as my personal board for organizing day-to-day work, but it’s also meant to be a reusable base for anyone who wants a private, mobile-friendly PWA with:
- a real backend
- persistent auth
- offline-friendly app shell
- Face ID / passkey login on iPhone
- a clean, dark interface
The app includes:
- Home dashboard
- GitHub panel
- Tasks
- Thoughts / notes
- Languages tracker
- Calendar
- Goals
- File board
- Mood tracker
- AI command bridge
- Settings with profile, password, Face ID, theme, and maintenance actions
- Frontend: React 19 + Vite
- Backend: Node.js HTTP server
- Database: SQLite (
node:sqlite) - Auth: password + server session + WebAuthn / passkeys
- PWA: service worker, manifest, install prompt, Apple touch icon
- Icons/UI: Lucide React
- Installable on iPhone, Android, and desktop
- App shell that behaves like a native app
- Mobile dock and sidebar optimized for touch
- Safe-area support for notch / home indicator devices
- Service worker and manifest included in the production build
- First-run bootstrap account
- Password login
- Server-side session cookie
- Password change flow
- Face ID / Touch ID via passkeys when available
- Auto Face ID login when a passkey is already registered
- Settings page for profile and appearance
- GitHub token storage for app integrations
- Reset / maintenance actions
- Mobile-friendly layout for daily use
src/
components/ # shell UI and shared controls
modules/ # each app area as a module screen
services/ # backend, PWA, auth, and storage helpers
styles/ # theme and shell styling
server/
index.js # production backend + SQLite + auth APIs
public/
sw.js # service worker source
mcp/
lippboard-mcp.js # MCP bridge for local automation
npm installnpm startnpm test- Local default:
http://localhost:4174 - Production / deployed URL: your domain or reverse proxy
- Open the app.
- Create the first account during the bootstrap screen.
- Log in with password.
- Go to Configurações.
- Register Face ID / passkey on your iPhone.
- Install the PWA from Safari / browser install flow.
- Use the app like a native mobile surface.
On iPhone, Face ID is handled through the browser’s passkey support.
- Open the app over HTTPS
- Use a real domain, not a raw IP, if you want a smoother passkey flow
- Register the passkey once from Configurações
- After that, the app can auto-attempt Face ID on login when a passkey exists
If Face ID is unavailable, the app falls back to password login.
- Open the app in Safari.
- Tap the share button.
- Choose Add to Home Screen.
- Open it from the home screen icon.
- Open the app in a supported browser.
- Use the install prompt or browser menu.
- Launch it as a standalone app.
npm run devThis starts the Vite frontend for development.
npm run build
npm start
npm testnpm run buildgenerates the production PWA bundlenpm startruns the SQLite-backed server that serves the built appnpm testruns a small smoke check against the server
The server listens on:
PORT- or
LIPPBOARD_PORT - optional
LIPPBOARD_DB_PATHfor a custom SQLite file path - default:
4174
Useful production notes:
- Put it behind HTTPS for passkeys / Face ID
- Use a reverse proxy like nginx or Caddy
- Keep the app on a stable domain so the PWA and auth stay consistent
A few useful endpoints:
GET /api/healthGET /api/auth/statusPOST /api/auth/bootstrapPOST /api/auth/loginPOST /api/auth/logoutPOST /api/auth/passwordPOST /api/auth/webauthn/register/optionsPOST /api/auth/webauthn/register/verifyPOST /api/auth/webauthn/login/optionsPOST /api/auth/webauthn/login/verifyGET /api/statePUT /api/statePOST /api/state/reset
Use the settings page reset action when you want to clear stored local state.
Because this is a PWA, stale service-worker cache can make changes look missing. If something looks wrong after a deploy:
- hard refresh
- clear the site data
- reinstall the PWA if needed
- verify the server is serving the latest build
This is a personal project, but contributions are welcome.
If you open a PR:
- keep the diff small
- preserve the PWA-first direction
- avoid adding dependencies unless they clearly reduce complexity
- test on mobile layouts when relevant
These are ideas, not promises:
- more polished onboarding
- better mobile keyboard handling
- richer offline behavior
- more project-specific widgets
- optional theme presets
- extra docs for self-hosting and deployment
MIT — see the LICENSE file.
Filipe Moreira — personal project, open source, PWA-first.