Skip to main content

Boring tech

Every project has a finite "novelty budget." Spend it on the parts that genuinely benefit from a novel approach. For everything else, pick the boring tool — the one with the most documentation, the longest track record, and the highest probability that someone has already solved your weird edge case on Stack Overflow at 2am five years ago.

Drafted from planning · v0.1

The shortest version

SQLite, vanilla JavaScript, plain HTML, fetch(). The novel parts: Cloudflare's edge runtime, single-tenant per shop, in-situ editing, AI-assisted operator support. Everything else is the boring choice and that's the point.

What the novelty budget bought

A short list of where Helm is genuinely novel and why we paid for it:

  • Single-tenant per shop on Cloudflare Workers + D1. Few products do this; almost no POS products do this. The isolation guarantees and trust-at-scale story are worth the slightly-experimental ground.
  • In-situ editing as the primary path. Most software pushes settings to a settings page. Helm inverts. The product differentiation is real.
  • AI-assisted operator support (slice 11) with structured grounding against shop D1. Not a chatbot bolted on; a query layer over the actual operational data. New territory.
  • Vertical slice ship cadence with the audit log as a load-bearing structural piece. Common pattern in finance, novel for retail POS.

Every other choice is boring on purpose.

The boring choices

Boring choiceCould have beenWhy we picked boring
Vanilla JavaScript WorkerHono / Remix / NextLess to debug, less to learn, less to update
Plain HTML + small JS modulesReact / Vue SPAFaster initial render, smaller bundle, fewer abstractions
fetch() for external APIsSDK packagesOne dependency, one API, one mental model
env.DB.prepare(...).bind(...).run()An ORM (Drizzle, Prisma)We know the SQL; the ORM hides what we want to see
Path-pattern routing in a switchA router libraryTrivially understandable; refactor when it crosses 200 endpoints
SQLite (D1)PostgresLess ops, single-file backups, plenty of capacity for the use case
Server-rendered HTML for non-SPA pathsClient-rendered everythingProgressive enhancement guarantees
kebab-case-file-names.mdAuto-numbered slugsPredictable, greppable
Markdown docs in this Docusaurus siteNotion / ConfluenceSource-controlled, diffable, deployable, owned
VitestJest, MochaFaster, ESM-native, Workers compatible
Prettier defaultsCustom style guideNobody argues about formatting

Why this matters at one-person scale

A solo developer cannot maintain expertise across many novel technologies simultaneously. Every novel tool you adopt is a tool you must:

  • Track for security advisories
  • Update across breaking version changes
  • Learn the idiosyncrasies of, then re-learn after a year of disuse
  • Debug at 2am when something goes wrong, often without good Stack Overflow answers because the tool is too new
  • Eventually replace when it's abandoned or surpassed

Boring tools have:

  • A long stable track record (less likely to be abandoned)
  • Vast documentation and community help
  • Predictable upgrade paths
  • Less "the framework changed everything in v3" surprise
  • Better tooling around them (linters, profilers, IDE support)

Boring is not the same as old or bad

Cloudflare Workers is, in tooling-age terms, young. But it's boring in the sense that matters: well-documented, stable runtime, predictable performance characteristics, no rapid breaking changes. The "boring" axis is "predictability and known-quantities," not "release date."

JavaScript itself is old (1995); modern JavaScript with native ES modules, fetch, async/await is essentially a new and pleasant language to write. The runtime is boring, the language is boring, the practice is enjoyable.

When we update the boring choice

The boring tool is the current default, not the permanent choice. We re-evaluate when:

  • The boring choice's costs become non-trivial (e.g., the routing switch hits 500 endpoints)
  • A new tool becomes obviously better and is itself boring (well-documented, stable)
  • The boring tool is abandoned (no commits in 18+ months, security issues unaddressed)
  • A team of contributors with different skills changes the calculus

These re-evaluations happen at slice boundaries, not mid-slice. Mid-slice we ship; between slices we reflect.

Anti-pattern: novelty as a hiring signal

Some teams pick novel tools to attract developers who want to learn them. Helm is one developer; that doesn't apply. When Helm has a team, the criteria stay the same: pick the boring tool unless there's a real product or operational reason for novelty. Smart developers find boring tools attractive too — they want to ship product, not relearn fundamentals.

See also