A lightweight task planner for kids and parents with a browser UI and a small Node.js backend for Webcal syncing.
- Login with username/password (stored locally)
- Parent (owner) and child roles
- Tasks can be created by parents and assigned to children
- Daily / weekly calendar views
- Shared and per-child Webcal sync
- Read-only lock indicator for imported Webcal appointments
- English and German UI
To run TiMiPlanner on your own server, you need:
- Node.js 20.x
- npm 10.x or newer
- A Linux server, macOS server, or Windows server with shell access
- Write permission in the project directory for the SQLite database file
- Open TCP port for the app, or a reverse proxy such as Nginx/Caddy in front of it
Project runtime dependencies:
- express
- sqlite3
- cors
- body-parser
Optional but recommended for production:
- Nginx or Caddy as reverse proxy
- systemd, pm2, or another process manager
- TLS certificate for HTTPS
- Regular backup of
timiplanner.db
The following example installs the required runtime on Debian 12.
sudo apt update
sudo apt upgrade -ysudo apt install -y curl ca-certificates gnupg git build-essential sqlite3curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejsnode -v
npm -v
sqlite3 --versionOptional for production with reverse proxy:
sudo apt install -y nginxOptional for TLS with Let's Encrypt:
sudo apt install -y certbot python3-certbot-nginx- Install dependencies:
npm install
- Start the app server:
npm run dev
- Open
http://localhost:5500 - Log in with one of the demo users:
- Parent:
parent/parent - Child (Lina):
lina/lina - Child (Max):
max/max
- Parent:
Install Node.js 20 and npm.
For Debian, you can use the commands from the section above.
Check versions:
node -v
npm -vDownload the project from GitHub:
cd /opt
sudo git clone https://github.com/HJS72/TiMiPlanner.git timiplanner
sudo chown -R $USER:$USER /opt/timiplannerIf Git is not installed yet:
sudo apt install -y gitcd /opt/timiplanner
npm installcd /opt/timiplanner
PORT=5500 npm startThe application will then be reachable at:
http://<server-ip>:5500
TiMiPlanner stores its live data in:
timiplanner.db
Important:
- The SQLite file is created and updated in the project directory.
- The application user must have read/write permissions for this file.
- Back up
timiplanner.dbregularly if you want to preserve tasks, bonuses, users, and calendar sync state.
Recommended setup:
- TiMiPlanner runs locally on port
5500 - Nginx or Caddy exposes the app on port
80/443
Example Nginx config:
server {
listen 80;
server_name your-domain.example;
location / {
proxy_pass http://127.0.0.1:5500;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Example systemd unit:
[Unit]
Description=TiMiPlanner
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/timiplanner
ExecStart=/usr/bin/npm start
Environment=PORT=5500
Restart=always
RestartSec=5
User=timiplanner
Group=timiplanner
[Install]
WantedBy=multi-user.targetThen:
sudo systemctl daemon-reload
sudo systemctl enable timiplanner
sudo systemctl start timiplanner
sudo systemctl status timiplannerIf you use the systemd service above, enable autostart once:
sudo systemctl enable timiplannerVerify autostart is active:
sudo systemctl is-enabled timiplannerExpected output:
enabled
Optional reboot test:
sudo rebootAfter reconnecting to the server:
sudo systemctl status timiplannerIf needed, inspect logs:
journalctl -u timiplanner -n 100 --no-pager- Default demo users are active until you replace them in the application.
- Authentication is simple username/password storage in the application state and is not hardened for internet-facing production use.
- If the app is exposed publicly, place it behind HTTPS.
- Webcal imports are fetched by the backend server, so the server must have outbound HTTP/HTTPS access.
- Port is controlled by the
PORTenvironment variable. Default is5500.
Parents can now open the Settings page and use the new update section to:
- store the GitHub repository URL
- optionally set a restart command such as
sudo systemctl restart timiplanner - check the latest GitHub Release
- install the latest release ZIP automatically
- upload a repository ZIP manually
The updater preserves these files by default during installation:
timiplanner.dbtimiplanner.db-shmtimiplanner.db-walupdater-config.jsonupdater-status.json
If the app is managed by systemd or another supervisor, configure the restart command in Settings so the updater can restart the service correctly after npm install completes.
To update the application from GitHub on your server:
At minimum, back up the database before updating:
cd /opt/timiplanner
cp timiplanner.db timiplanner.db.backup-$(date +%Y%m%d-%H%M%S)sudo systemctl stop timiplannercd /opt/timiplanner
git fetch --all
git pullcd /opt/timiplanner
npm installIf native modules such as sqlite3 cause problems after an update, rebuild them directly on the server:
cd /opt/timiplanner
rm -rf node_modules package-lock.json
npm installsudo chown -R timiplanner:timiplanner /opt/timiplannersudo systemctl start timiplannersudo systemctl status timiplanner
journalctl -u timiplanner -n 100 --no-pagerOptional check that the service is still enabled after reboot:
sudo systemctl is-enabled timiplannerBefore and after updates, pay special attention to:
timiplanner.dbnode_modulesbeing rebuilt on the target server- the
timiplannerservice logs if startup fails
- Live data is stored in SQLite in
timiplanner.db. - Webcal fetches are proxied through the backend endpoint at /api/webcal/fetch.
- Imported Webcal events are read-only tasks.
- Settings show a Webcal connection light:
- Green = working
- Red = not working
- Gray = no source configured
- Replace localStorage with a real backend (e.g., Node/Express, Supabase, Firebase).
- Add proper authentication and password hashing.
- Add permission rules so children cannot access other children's tasks.
- Enhance calendar view with drag & drop and recurring task support.
Powered by your local browser (no build step required).