PlanPad is a self-hosted personal planning and self-development platform. It brings routines, habits, life goals, a week-based timeline, cost management, a backlog kanban, ideas, nested markdown pages, a calendar overview and a life dashboard together in one app that runs from a single Docker container.
It is a single-user app with optional Google Authenticator (TOTP) two-factor login. Your data lives in one SQLite file on your own machine.
- Dashboard with a live age counter (years, months, days, hours, minutes, seconds) and a 100-circle lifespan grid, plus activity stats.
- Routines as reusable schemas with per-day time slots (start/end time per day of week). Assign one action to several days at once, clone an item into another table, or duplicate a whole table. The done/not state is tracked per week, not on the schema. A Google-Calendar-style week view lets you drag events to move or resize them, including across days.
- Habits: tables of daily-checked habits that each track a start-to-end date range, unfolding into weekly grids, with dashboard analytics (completion rate, streaks, trend across tables).
- Goals: life goals with a start date, an estimation (days / weeks / months / years) and a progress percentage. A time-based roadmap draws every goal as a dot on its target date; reaching 100% moves it to the Achievements list.
- Costs: cost categories and groups in EUR/USD, monthly planning mapped onto the timeline, predicted vs actual tracking down to individual purchases, and charts on the calendar and dashboard. Currencies are never converted or mixed.
- Timeline of weeks grouped year to month to week. Generate weeks for any date range and see routine completion per week, month and year.
- Week detail with routine assignment, a checklist grouped by day of week, a completion report and per-day markdown notes.
- Backlog kanban (To Do / Done) with drag and drop. A card's date automatically links it to the matching week.
- Ideas list with title, description, why it is a good idea, a proposed date and a created date.
- Reminders with a severity level (critical / medium / low) and open / done sections. The sidebar shows a pulsing severity dot (red / orange / green) for the highest open level, and a post-login alert warns when critical reminders are open.
- Burnout log: a 0–10 level bar, a colour (red / orange / green), a description, a reason, and selectable factor tiles, each with its own icon.
- Fun log: a 0–10 level bar and a description for the moments you enjoyed.
- Health section for tracking health notes alongside the rest of your life.
- Pages: nested markdown pages and sub-pages with a live editor. Folders
collapse/expand, selecting a folder shows an overview (item / sub-folder / page
counts) in the main panel, pages can be dragged to re-parent them, and you can
import from a Trilium
.zipexport (preserving the original hierarchy and order). - Sticky note: a floating, dockable, resizable note window that follows you across pages and is editable in place.
- Calendar: an activity heatmap for the year with a daily-progress chart and a monthly predicted-vs-actual cost chart. Click any day to drill into that day's routine items below the calendar.
- Search and order-by on the backlog, routines and ideas (searching title and content), plus search on pages.
- Settings: change password, profile (username, picture, date of birth), export / import the database, a purge danger zone, and 2FA setup.
- Candlelit Planner theme (warm amber-on-ink) with a dark / light toggle in the top bar, persisted across sessions.
- Security section: a login-activity log (IP, time, browser/OS, device, region), failed-attempt visibility, and IP management — manually add or remove IPs from the blacklist. After 3 failed login attempts an IP is auto-blocked for 15 minutes.
- Configurable session timeout (10 minutes – 2 hours) in Settings.
- Customisable sidebar: file pages into your own collapsible categories; the layout is stored server-side so it follows your account across browsers.
The docs/ folder explains every part of the app — what each feature is
for, how it works and how to use it. Start with
Getting started, or
Architecture if you want to work on the code.
Login ![]() |
Dashboard ![]() |
Routines ![]() |
Timeline ![]() |
Week detail ![]() |
Backlog ![]() |
Ideas ![]() |
Pages ![]() |
Calendar ![]() |
Settings ![]() |
A light theme is available via the toggle in the top bar — see screenshots/light/.
- Frontend: Angular 20 (standalone components, signals) + Angular Material.
- Backend: Node.js + Express + TypeScript.
- Database: SQLite (via better-sqlite3).
- Auth: JWT sessions, bcrypt password hashing, TOTP 2FA (otplib).
- Packaging: a single Docker image where the API also serves the built Angular app.
- Tests: end-to-end tests with Testcontainers + Vitest.
planpad/
apps/
api/ Express + SQLite backend (TypeScript)
web/ Angular 20 + Material frontend
libs/
shared/ Shared TypeScript types/contract used by api and web
e2e/ Testcontainers end-to-end tests
Dockerfile
docker-compose.yml
.env / .env.template
cp .env.template .env # then edit JWT_SECRET etc.
docker compose up -d --buildOpen http://localhost:3000 and sign in with the default credentials admin / admin.
Change the password in Settings right away.
The SQLite database is stored in the planpad-data Docker volume so it survives restarts.
Requires Node.js 22.
npm run install:all # install api, web and e2e dependencies
npm run dev # API on :3000, Angular dev server on :4200 (proxies /api)Other scripts:
npm run build # build api bundle + Angular app
npm run typecheck # type-check the API
npm run test:e2e # run the Testcontainers end-to-end suite (needs Docker)Copy .env.template to .env. Available variables:
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Port the server listens on. |
DATABASE_PATH |
./data/planpad.sqlite |
SQLite file location. |
JWT_SECRET |
(change me) | Secret used to sign session tokens. |
JWT_EXPIRES_IN |
7d |
Session lifetime. |
DEFAULT_USERNAME |
admin |
Bootstrap username (first run only). |
DEFAULT_PASSWORD |
admin |
Bootstrap password (first run only). |
TOTP_ISSUER |
PlanPad |
Label shown in Google Authenticator. |
DATE_OF_BIRTH |
1990-01-01 |
Seeds the dashboard age counter (first run). |
Security notes: set
JWT_SECRETto a long random string before exposing the app anywhere, change the default password on first login, and treat database exports as sensitive — the export file contains your password hash and TOTP secret.
End-to-end tests build the Docker image, start the container and exercise the full API (login, routines, weeks, checks, backlog, ideas, pages, notes, dashboard, calendar, export/import/purge):
npm run test:e2eIssues and pull requests are welcome. The architecture doc explains the codebase layout and how a feature is typically added; please keep changes small and focused.









