Skip to content

Bruce Hart

Coding AI Codex Productivity Tools

Web Tools: my tiny-tool factory on Cloudflare Workers

Portrait of Bruce Hart Bruce Hart
6 min read
webtools headerpng

I wanted a place where "I need a little tool" goes to live.

Not a startup. Not a framework demo. Just a personal shelf of small, sharp web tools I can build quickly with Codex and deploy in one place: Cloudflare Workers.

The project is here: https://github.com/brucehart/web-tools And it runs here: https://web-tools.bruce-hart.workers.dev

A "tools shelf" beats a pile of one-off repos

Every time I made a tiny tool as a one-off, it would die the same way: no home for it, no easy deploy story, no place to iterate, no consistent UI, and no "add one more" muscle memory.

So I made one Worker that can host a bunch of micro-tools, with a boringly consistent pattern: each tool is basically one HTML file plus whatever client-side JS it needs.

When a tool needs server help (OAuth, database, fetching), the Worker adds a small API route.

The tools so far are deliberately mismatched

They're not a product suite. They're the stuff I keep bumping into.

Markdown Preview (/markdown): GitHub-flavored Markdown rendering with sanitization, MathJax for inline $...$ and display $$...$$, a dual-pane editor/preview with tabs saved locally, syntax highlighting, and a "copy rendered HTML" button.

Euler Preview (/euler): A Project Euler forum post previewer (BBCode + TeX) that handles a bunch of PE-specific tags and code-block flavors, with tabs, syntax highlighting, and MathJax.

Pastebin (/pastebin): Create/share snippets as public or unlisted. If you're signed in and allowed, entries are stored in D1; if not, it falls back to local-only storage (still useful, just not shareable across devices).

LLM Cost Calculator (/llm-cost): Paste token usage dumps, compute totals, and compare price profiles, with pricing profiles stored locally so it stays personal and fast.

Actuary Calculator (/actuary): Quick mortality-window estimates using the Social Security actuarial tables.

TIFF Viewer (/tiff-viewer): Decode TIFFs locally (bundled UTIF.js), including multi-channel. Turn channels on/off, set per-channel colors, and zoom/fit-to-width. I made this to help debug an image-based machine learning model I'm working on.

YouTube Transcript (/yt-transcript): Fetch transcripts for public videos (and translations when available), view segments, toggle timestamps, and copy results. I use this to help generate summaries using an LLM. Unfortunately YouTube blocks traffic from Cloudflare Workers most of the time so this tool isn't very useful.

Date Calculator (/date): Small "date math" helper with a clean UI and theme toggle.

Daily Goals (/goals): A minimal calendar-style goal tracker with cloud persistence (via D1).

To-Do (/todo): A simple todo app with priority/category/due dates and cloud sync (via D1).

That mix is the point: the shelf is allowed to be weird.

One Worker, two halves: static tools + tiny APIs

The architecture is intentionally blunt: a single Worker entrypoint routes requests, static assets are served from public/ via the Workers ASSETS binding, some tools are pure front-end (localStorage), and some tools get an API + D1 tables.

In practice, this means adding a new tool is often: create public/my-tool.html, add a pretty route mapping (/my-tool -> /my-tool.html), add an index tile on /, and deploy.

No build step required for most changes. It feels more like "editing a good README" than "shipping a web app".

OAuth is a bolt-on, not the center of the universe

For Pastebin (and the tools that need persistence), I didn't want a whole auth system. I wanted Google sign-in, a session cookie, a DB row to hang stuff off of, and done.

So the Worker implements a small OAuth flow: GET /auth/google/login redirects to Google with a random state, GET /auth/google/callback verifies state, exchanges code for a token, fetches user info, the user is upserted into D1, and a random session token is stored in D1 and set as an HttpOnly cookie.

There's also an "allowed user" gate (right now, an email allowlist) because this is mostly a personal toolbox, not a public SaaS. Public paste links can still be shared, but creation/editing stays constrained.

That pattern will probably repeat: start private-by-default, then selectively open doors.

D1 is the boring persistence layer I wanted

When a tool graduates from "local-only" to "actually persistent", D1 is perfect: SQL tables, trivial queries, nothing exotic to operate, and deploys with the Worker.

Pastebin's schema is exactly what you'd expect: users, sessions, pastes. Goals and todos follow the same "user_id -> rows" vibe.

The mental model is: local-first until it hurts, then D1.

Local-first with an escape hatch is the right default for tiny tools

Most small tools don't need accounts.

So the default is to store preferences and working state in localStorage, keep the UI fast, keep the code obvious, and avoid auth and DB until there's a real reason.

Pastebin is the nice hybrid: if you're not logged in, it still works as a personal scratchpad. If you are logged in, it becomes shareable and durable.

That's the kind of progressive enhancement I want everywhere: not "features behind login", but "extra powers when you opt in".

Codex is the multiplier, not the product

The real unlock for me has been using Codex like a scaffolding generator: spin up a new tool UI quickly, iterate on the annoying parts (parsing, edge cases, styling), and keep everything in one repo so improvements compound.

The important part is the constraint: "one Worker, one shelf".

Constraints make it easy to ship.

A Model Testing Chamber

Web-Tools also gives me a low-risk way to test out new models without much risk. I can add a new tool to the set and not worry too much about breaking anything. When I want to test OpenCode, GLM 4.7 or MiniMax M2, I'll have it generate a small tool here to put it through it's paces before turning on to a more substantial repo.

What I want next (and what I'm unsure about)

A few directions I'm actively thinking about: a consistent "tool template" (header, theme toggle, persistence helpers) that still lets tools be weird, better permissioning than a single allowed email (maybe an invite list stored in D1), and a lightweight pattern for tools that need background jobs (cron triggers) without turning the repo into infrastructure soup.

Also: I'm not sure how public I want this to be. Some tools are inherently public (viewer/calculators). Others are "me tools" that happen to have a URL. I like that ambiguity, but it affects how much polish is worth doing.

If you end up building something similar, I'd love to compare notes. What's on your "tiny tools I wish existed" list?