A few side projects I build for myself — small enough to ship, useful enough to keep using. Each one solves a specific problem in my household or workflow.
User-facing things — phones, browsers, on-screen taps. Each is a real product I or someone in the family uses.
A small web app for practising Modern Greek — verbs, articles, nouns, pronouns, time, numbers.

I needed the kind of focused drill that textbooks gesture at but apps don't actually deliver: short sessions, narrow scope, no streak gamification or push notifications. Built for myself, hosted at greek.42b.eu; if it's useful for anyone else learning Greek, even better.
greek.42b.eu, no install needed.A native Android companion that surfaces local-life essentials in Slovenia — locations, transport, topics, membership cards — with offline-first fallbacks.




The web version catch-up already has the structure I want; this app is its native Android twin, sized to fit a phone home screen. It opens straight to whatever I actually need at 8 am: where to go, how to get there, what's happening today, and which loyalty card to pull up at the till.
scripts/fetch-store-anchors-overpass.sh); no Google call when within ~25 km of any anchor or library.arriva-slovenia-android project's tile path).catch-up web hook.A field app for electricians (and their customers) — work orders, photo evidence, in-person or remote sign-off. Working name Storjeno (Slovenian: "done").
Tradespeople in Slovenia still document jobs on paper, lose photos in WhatsApp threads, and chase signatures across postal mail. Storjeno is the smallest possible app that captures all three: a work order with checklist + photos, a sign-off (live or via emailed link), and an offline-first sync so it works in basements and rural sites with no signal.
image/*, in-app camera FAB (context-aware: home asks for client, client-detail preselects, active order goes straight on), and email deep links of the form https://storjeno.app/o/{orderId}?t={token} with single-use, time-bound, scoped tokens.SL · HR · SR · BS · MK (default SL).AndroidLockScreen0
Single-APK parental control launcher with a hard split between a "parent" and "child" phone — and the freedom to switch between them.

Off-the-shelf parental controls (Qustodio, Family Link, etc.) are heavy, locked into someone else's cloud, and treat the whole family as a fleet. Guardian is the opposite: one APK, both devices run it, and the role is flipped from a single "Mark as Parent" toggle. The child phone enforces a daily screen-time budget; the parent phone reads usage, grants extra time remotely, and chats with the child. Lent the parent phone to a sibling for an afternoon? Switch to Child mode, lock it, hand it over.
onTaskRemoved + always-restart keepalive.screen_on / app_closed:<pkg> beacons; parent home shows "Child active — closed youtube, 12s ago".+15min rows.rotors-service-game
A small browser tycoon: run a service clinic, manage reputation, and order spare parts before the queue gets out of hand.
A weekend prototype that grew tabs. You play a clinic operator juggling a reputation stat, a level counter, and a supplier ordering terminal split into Spare Parts, Tools, and Delivery — three modal tabs that quietly turn the game into a logistics puzzle. Pure HTML/CSS/JS, no build step, runs by opening index.html.
index.html, no build, no server.Reusable building blocks — drop-in widgets and self-hosted infrastructure for the web stack.
SSOsimple
A reusable, drop-in identity widget — profile picture, language, sharing, AI chat — built as a self-contained web component with Shadow DOM.
I wanted a single, framework-agnostic widget I could drop into any of my apps to handle the boring identity stuff: who am I, in which language, with what shared data, and a "ping me" surface. Built with vanilla JS so it works the same in React, in static HTML, and inside a Bolt prototype.
A tiny, self-owned file storage and CDN with strong client-side auth — built on the Cloudflare free tier, with zero egress fees.

I wanted somewhere to put renders, build artifacts, and one-off uploads from agents and CLIs without paying egress, without depending on someone else's auth, and without running a server. Cloudflare R2 + a Worker plus an ECDSA-keyed client gets close to "free, fast, mine" — and the URL format is content-hash-based so caching and cache-busting just work.
filespot init, upload (file or URL), ls, whoami.uk)./builder/{category}/{filename}?ch={5-char hash}&uk={fp} for free cache-busting on edits.--webp conversion; threshold of ≥2% or ≥2KB savings before keeping the optimized version.ffmpeg command for WebM conversion rather than re-encoding inline.filespot requests approve <fp>.mcp/filespot-mcp.mjs compiles into a single binary so agents can upload directly.deploy:42b, deploy:lc for separate workers per project.An IDE-style command center for running, managing, and monitoring LLM agents and tasks across multiple projects and workspaces.

A unified workspace for juggling different projects, epics/themes, and independent tasks — all with live agent monitoring. Projects and tasks are organised in colour-coded "bands" that group related work visually. Each band contains ongoing chat sessions with agents, a history of completed actions, and live previews of running sub-agents. The UI shell is intentionally hardcoded for stability — the system can self-modify runtime, skills, and agent configurations, but the layout stays fixed.
<hr> separators.Smaller pieces that the apps lean on — prototypes, plumbing, and notifications.
A small password vault that lives entirely behind a hash-and-name URL — share the link, share access; nothing on a server to ask.
A Bolt-generated Vite + React + TypeScript prototype where the URL itself is the access mechanism: no login screen, no server-side session — just a vault routed by the path you visit. Useful as a sketch for "what if a vault were a link?" and a sandbox for trying browser-native crypto without dragging in a backend.
/v/:hash/:name opens a vault entry; /vault/:id opens a saved view.VaultProvider context holding unlocked state for the session.webauthn.passwordless.id.Reclaim Google Photos and Drive space by re-encoding large images and videos to WebP / WebM — without ever touching free legacy items.
Google quietly stopped giving everyone unlimited "high quality" Photos storage; meanwhile years of HEIC bursts and 4K clips were happily eating my paid plan. This CLI scans newest-first, respects an upload-cutoff so legacy free-tier items stay untouched, re-encodes the rest, and keeps a state file in Drive root so cumulative savings and processed-item ids survive reinstalls.
credentials.json in the working dir or via GSS_CREDENTIALS.doctor — verifies cwebp and ffmpeg are on PATH before any work runs.sync — reconciles gphotos-space-saver-state.txt in Drive root with a local .local.txt mirror; first thing you run after OAuth.src/reusable/ — pieces lifted out for use in other personal projects.AGENTS.md + FEATURES.md so coding agents can extend the tool without re-reading the whole codebase.A small Cloudflare Worker that turns an HTTP POST from one of my own apps into a Discord message — without anyone else's app being able to use it.
Every personal project eventually wants to ping me when something happens — a build finishes, a job errors, an alert fires. Rather than embedding webhook URLs into each app, this Worker holds the secret once and accepts POSTs only from origins I trust.
405 with proper CORS headers.localhost on any port, plus lynx-craft.com and any subdomain — everyone else is rejected at the CORS layer.