Easy-to-manage touch screens
Free, open-source touch screens. Guided USB setup, a drag-and-drop editor and local control. Made for Home Assistant.
Every morning, something fun and a little smart waits for your kid on paper. Parents configure modules; kids get a 58mm thermal strip — no kid accounts.
LifestyleTypeScript · PythonGitHub @jon-tompkinsOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
Every morning, something fun and a little smart waits for your kid on paper.
Tearaway is the parent web app for a kitchen strip (58mm thermal today; US Letter / N80 next). Parents configure a kid profile (name, age band, paper size → slots, print time, weather, watchlist, calendar). Kids never log in — they are profiles, not accounts (COPPA).
This MVP is a local demo: no auth, no Stripe, no secrets, no real printer. Config lives in data/store.json (seeded from data/store.sample.json).
Open http://localhost:3000.Read the full README ↗Every morning, something fun and a little smart waits for your kid on paper.
Tearaway is the parent web app for a kitchen strip (58mm thermal today; US Letter / N80 next). Parents configure a kid profile (name, age band, paper size → slots, print time, weather, watchlist, calendar). Kids never log in — they are profiles, not accounts (COPPA).
This MVP is a local demo: no auth, no Stripe, no secrets, no real printer. Config lives in data/store.json (seeded from data/store.sample.json).
cd /workspace/tearaway-app
npm install
npm run dev
Open http://localhost:3000.
Production build:
npm run build
npm start
| Path | What |
|---|---|
/ | Marketing home |
/app | Dashboard — live strip/letter preview, Generate new strip, recent preview history, Print now |
/app/setup | Create a kid (name + age band + paper size + starter modules) |
/app/modules | Paper size → fixed slots; add modules into slots; in-order / random when a slot has 2+ |
/app/settings | Timezone / print time, weather, watchlist, calendar; tier stub (modulePoolLimit) |
Aliases that redirect: /dashboard → /app, /setup → /app/setup, /modules → /app/modules, /settings → /app/settings.
paperSize and slots live on each kid (not global kitchen settings). Kitchen settings.paperSize is only the default for newly created kids.
| Paper size | Slots | Preview |
|---|---|---|
strip58 | 4 | Classic ~384px thermal strip |
letter | 7 | Wider ~612px letter-ish page (2-column body) |
Flow on /app/modules:
Empty slots are skipped at generate time; save requires at least one filled slot.
single) → that modulein_order → moduleIds[cursor % length]; cursor advances after each successful Generate / Print now (persisted in store.json)random → seeded RNG from date + kid first name + nonce + slotId (reshuffle changes outcome)Legacy flat kid.modules: ModuleId[] is still written (unique pool across slots) and migrated into slots on read if slots is missing.
On /app, Generate new strip bumps the per-kid nonce, regenerates the preview (random slots reshuffle; in-order slots use the current cursor then advance), and keeps the last 3–5 previews for comparison. Print now saves a job using the current seed and slot picks, then advances in-order cursors. Refresh preview reloads without bumping the seed or cursors.
settings.modulePoolLimit: number | null — null unlocks all first-party modules (MVP). Later tiers can cap how many unique modules sit in a kid’s pool. No Stripe / payments in this build. Settings shows a short note.
The parent UI is not required for printing. Later firmware (ESP32 + Oreilet 58mm) can HTTP-fetch today’s strip.
| URL | What |
|---|---|
GET /api/render?kid=<id> | HTML of today’s strip (default format=html) |
GET /api/render?kid=<id>&format=png | PNG preview (strip width today) |
GET /api/render?kid=<id>&format=json | Structured PrintJob (sections + meta; no HTML) |
GET /strip/<id> | Same HTML strip in a page (iframe preview) |
GET /api/print-jobs/preview | Generate for the active kid (no persist; no cursor advance) |
POST /api/print-jobs/reshuffle | Bump nonce + preview + advance in-order cursors |
POST /api/print-jobs/print-now | Generate + save queued job + advance in-order cursors |
GET /api/print-jobs/latest | Last queued job for the active kid |
GET / PUT /api/store | Read / patch JSON store |
GET /api/weather | Open-Meteo snapshot (falls back to mock offline) |
Query params for /api/render
kid (required) — profile id, e.g. demo-samdate (optional) — YYYY-MM-DD. Default: today in the kid’s timezoneformat (optional) — html | png | jsonExample: /api/render?kid=demo-sam&date=2026-09-16&format=png
No ESC/POS yet. No talk to a real printer. HTML/PNG/JSON is the handoff.
Content is seeded by date + kid first name + nonce. Same inputs → same strip. Bumping the nonce (Generate new strip) reshuffles without changing the day. Multi-module slots add another layer of pick resolution (above).
| Module | Notes |
|---|---|
| Maze | Perfect maze; size by age band |
| Word Find | Tiny word-search (6×6–8×8) that fits 58mm |
| Connect the Dots | Funny numbered dots + silly caption (SVG) |
| Riddle | Question + answer on the strip (think first) |
| Number Puzzle | 4×4 / 6×6 / easy 9×9; parent key on-screen only |
| Module | Notes |
|---|---|
| Word of the Day | Age-banded definition + example |
| Poem of the Day | Short printable poem |
| Breakfast Joke | Age-banded groaners; kid-safe, no mean stuff |
| Spanish Word | Spanish + phonetic + English + try-it line |
| Module | Notes |
|---|---|
| This Day in History | Kid-appropriate local catalog |
| Fun Fact | Curated sample copy |
Wonder + discovery tone. No violence / politics anxiety. City news is generic “hometown” style (no geo API yet).
| Module | Notes |
|---|---|
| World News | Animals, space, discoveries |
| National News | Parks, science fairs, kindness |
| Hometown News | Library, playground, neighbors |
| Tech News | Robots, code, gadgets |
| Gamer News | Games, makers, fair play |
| Module | Notes |
|---|---|
| Weather | Open-Meteo + Zippopotam (no API key); mock if offline |
| Stock Watchlist | Mocked prices — not live market data |
| Calendar | Local events you edit in Settings |
| Module | Notes |
|---|---|
| Tiny Doodle | 30-second drawing prompt for the strip margin |
| Would You Rather | Two choices + a tiny debate nudge |
Demo kid (data/store.sample.json): strip58 with four slots — word · joke/riddle (in order) · doodle/wyr/poem (random) · maze/spanish (in order).
Space Week, Scorecard, Gratitude Note, Tongue Twister — shown in the modules UI as “coming soon.” First-party modules above are not duplicated here. No payments or pack install yet.
data/store.json (gitignored)data/store.sample.json (committed)kid.paperSize: "strip58" | "letter"
kid.slots: Array<{
id: string
moduleIds: ModuleId[]
mode: "single" | "in_order" | "random"
cursor?: number // in_order only
}>
settings.modulePoolLimit: number | null // null = all unlocked
Next.js (App Router) · TypeScript · Tailwind CSS · local JSON store
Private prototype — dad + kid project.
All animal line art is from OpenMoji, © OpenMoji contributors, licensed CC BY-SA 4.0. See src/lib/puzzles/animal-art.ts.