A wall-mounted daily assistant for tablets (Fire HD 8, 1280×800 landscape). Displays a daily checklist of medications, supplements, and reminders with progress tracking. Includes a web admin panel to manage items, real-time weather forecast, and intelligent date navigation with auto-reset on idle. Especially useful for people who tend to forget daily routines — like those with ADHD.
![]() Daily checklist |
![]() Progress tracking |
![]() All done! |
![]() Admin panel |
![]() Settings |
![]() Edit item |
- Daily checklist — medications, supplements, reminders with emoji icons
- Progress tracking — visual completion percentage
- Weather forecast — Open-Meteo integration (free, no API key)
- Date navigation — browse past/future days, auto-reset to today after 5 min idle
- Admin panel — password-protected item management and settings
- Responsive design — optimized for 1280×800, works on other sizes
- Configurable — font sizes, colors, weekday scheduling per item
- Follow-up tasks — auto-generate follow-up reminders
- PWA with offline support — service worker for network interruptions
- No build step — vanilla HTML/CSS/JS, runs directly in Node.js
Requires Node.js 20+ and npm.
git clone https://github.com/pedroberaldo87/daily-screen.git
cd daily-screen
# Install dependencies
npm install
# Create .env from template
cp .env.example .env
# Edit .env with your values (at minimum, change ADMIN_PASSWORD)
nano .env
# Run development server
node --watch server.jsOpen http://localhost:3000 in your browser. Admin panel at http://localhost:3000/admin (login with password from .env).
Requires Docker and Docker Compose.
git clone https://github.com/pedroberaldo87/daily-screen.git
cd daily-screen
# Create shared Docker network (required for Caddy reverse proxy)
docker network create shared_web
# Create .env from template
cp docker/.env.example docker/.env
# Edit docker/.env with your values
nano docker/.env
# Start containers
docker compose up -d
# View logs
docker compose logs -f daily-screen-appThe app runs on port 3000 (internal). To expose via HTTPS, use Caddy or your preferred reverse proxy.
The project includes a parametrized deploy script that builds, uploads, and starts the app on a remote server.
DEPLOY_HOST=your-vps-ip DEPLOY_KEY=~/.ssh/your_key ./deploy.shEnvironment variables:
- DEPLOY_HOST (required) — VPS IP or hostname
- DEPLOY_KEY (required) — path to SSH private key
- DEPLOY_USER (optional, default:
root) - DEPLOY_PATH (optional, default:
/opt/daily-screen)
The script:
- Creates a local tarball (excludes
node_modules,.db,.git,.env) - Uploads to
/tmp/daily-screen-deploy.tar.gz - Prunes Docker to free space
- Backs up production
.env - Extracts tarball, restores
.env - Builds and runs containers
- Verifies container health
- Cleans up temporary files
If .env doesn't exist on first deploy, create it manually on the VPS at the deploy path.
- PORT — Express server port (default:
3000) - ADMIN_PASSWORD — Password for admin panel login. Change this to a strong value in production.
- SESSION_SECRET — Secret key for session cookies. Use a random string.
- DATABASE_PATH — Path to SQLite database (default:
./daily-screen.dbfor dev,/data/daily-screen.dbfor Docker) - WEATHER_LAT — Default latitude for weather forecast (default:
-23.55) - WEATHER_LON — Default longitude for weather forecast (default:
-46.63) - WEATHER_TZ — Timezone for weather display (default:
America/Sao_Paulo)
See docker/.env.example for production defaults.
Daily Screen follows a simple server-rendered architecture with no build step.
Backend — Express server handles:
- REST API for tasks, items, weather, settings
- Session-based admin authentication
- SQLite database with automatic migrations
Frontend — Vanilla HTML/CSS/JavaScript:
- display.html — tablet view (4-panel layout: clock, weather, checklist, progress)
- admin.html — admin panel (CRUD, settings, emoji picker)
- sw.js — service worker for offline support and cache management
Database — SQLite with WAL mode:
routine_items— template tasks (title, icon, category, weekday schedule, alerts)daily_tasks— daily instances (lazy-generated from routine_items)settings— key-value store (location, fonts, timezone)sessions— admin session tokens
daily-screen/
server.js # Express entry point
db.js # SQLite schema, queries, migrations
weather.js # Open-Meteo fetch + 30min cache
session-store.js # Custom SQLite session store
Dockerfile # Multi-stage Node 20 Alpine
deploy.sh # VPS deploy script
docker/
docker-compose.yml # Container orchestration
.env.example # Production env template
routes/
display.js # GET / → tablet display
admin.js # POST /admin/login, GET /admin
api.js # REST API endpoints
middleware/
auth.js # Session authentication
public/
style.css # Design system (Ember Night palette)
display.js # Tablet display logic (clock, weather, tasks, date nav)
admin.js # Admin panel logic (CRUD, settings)
icon-picker.js # Emoji picker with PT-BR search
utils.js # Shared utilities (escapeHtml)
sw.js # Service worker (offline + cache strategies)
manifest.json # PWA manifest
views/
display.html # Tablet UI
admin.html # Admin panel UI
login.html # Login page
Lazy task generation — daily_tasks are created on-demand when you call GET /api/tasks?date=YYYY-MM-DD. If tasks exist for that date, they're returned; otherwise, they're generated from routine_items matching the date's weekday.
CSS custom properties — Font sizes are stored in the database and applied as CSS variables. Admin can adjust --fs-clock, --fs-greeting, etc. in real-time.
Emoji icons — Tasks use Unicode emoji stored as text in SQLite. The emoji picker provides searchable selection with Portuguese-Brazilian keywords.
Service worker — Uses cache-first strategy for shell assets (HTML, CSS, JS) and network-first for API calls. After deploy, bump CACHE_NAME in public/sw.js to force browser cache refresh.
All endpoints are prefixed with /api.
Public (no auth required):
GET /api/tasks?date=YYYY-MM-DD— Get tasks for date (lazy-generates if needed)POST /api/tasks/:id/toggle— Mark/unmark task as completeGET /api/items— List all routine itemsGET /api/weather— Weather forecast (cached 30 min)GET /api/geocoding?q=cidade— Search cities (Open-Meteo)GET /api/settings— Get all settings
Auth required (admin session):
POST /api/items— Create routine itemPUT /api/items/:id— Update routine itemDELETE /api/items/:id— Soft delete (deactivate)DELETE /api/items/:id/permanent— Hard deletePUT /api/settings— Update settings (key-value pairs)
For external agents (scripts, cron jobs, other LLM-driven tools), there's a parallel token-authenticated surface at /integration/v1/* with full CRUD coverage of items, protocols, tasks, and settings. Tokens are managed in the admin panel under Tokens (top nav).
See docs/2026-04-20-integration-api.md for the complete guide — includes data models, endpoint reference with curl + Node.js examples, gotchas, and a ready-to-copy skill template for Claude Code.
curl -H "Authorization: Bearer dsk_live_..." \
https://daily.aiworks.app.br/integration/v1/healthFor the best experience on an Android tablet (e.g., Fire HD 8), use Open Kiosk — a lightweight kiosk browser that locks the tablet to a single URL in fullscreen mode. Just point it to your Daily Screen instance and mount the tablet on the wall.
![]() Playlist & Sleep settings |
![]() Kiosk & Language settings |
Found a bug? Have a feature idea? Contributions are welcome.
- Fork the repo
- Create a feature branch (
git checkout -b feature/my-feature) - Make your changes
- Test locally
- Commit and push
- Open a pull request
Please follow the existing code style (CommonJS imports, no TypeScript, vanilla JS). For major changes, open an issue first to discuss.
See CONTRIBUTING.md for guidelines.
This project is licensed under the GNU General Public License v3.0. See LICENSE file for details.
Built for daily routines you can't afford to forget. Works offline. No tracking. Open source.







