Engineering Notes
Why the engineering decisions were made. The reasoning, the trade-offs, and the failures that taught us each lesson. We collected them over decades in different shapes and forms, starting with Post-It notes and the latest maintained in our own Markdown Notes Manager connected to Github repo.
The Reepolee Approach summarizes the principles. These notes preserve the arguments, tradeoffs, and implementation decisions behind them.
Read Our ApproachThe Database Is Probably Permanent
Why most teams never replace their primary database engine, and why designing for portability costs more than it returns. Covers stored procedures, views, triggers, DDL tooling, codegen as an ORM alternative, and the generator pattern behind Reepolee.
Localized URLs for Pages, Not for Apps
The two distinct URL strategies for multilingual software: fully localized slugs for content that needs to be indexed and shared, language-agnostic URLs for apps where language is a user property. Covers hreflang, the locale-prefix plus translated-slug hybrid, and the subdomain split for products that are both.
Why Scripting?
Why Reepolee builds with plain TypeScript scripts: they let platform quirks be absorbed into readable code you own, in one place, rather than leaking into configuration, plugins, or setup instructions.
We Make Our App Fail Loudly on Missing Environment Variables
On startup validation, silent fallbacks, and the principle that a process that won't start with bad config is safer than one that runs quietly with it. Covers Bun's env handling and a simple pattern for making misconfiguration impossible to miss.
Light, Dark, Do Both
On implementing light and dark mode correctly - system preference as the default, per-site user override, and why both are needed.
Why Bun's SQL Dies in CLI Scripts (and How to Fix It)
How Bun's internal SQL connection pool interacts with the event loop in CLI scripts, why idle connections fail to keep the process alive, and two fixes: reserve() for transaction-scoped connection affinity, setInterval() for fire-and-forget scripts. Both disappear inside Bun.serve().
Why We Use Bun and TypeScript Over Rust
On cognitive overhead, one-language stacks, and Bun's build-free TypeScript execution - why Rust's strengths don't translate to typical web application work, and why LLM-generated code needs to be readable by the team that maintains it.
The Dunning-Kruger Curve Has a Sweet Spot - and It's Hiring You Mid-Level Engineers
On the engineering talent market, why mid-level engineers compound faster than the extremes, and how AI tools specifically reward developers who are competent enough to direct them but curious enough not to trust them blindly.
Boring UI Wins
On why standardized, predictable UI wins over the life of a product - covering component learning curves, layout conventions, browser-native features, accessibility, maintenance debt, and why the best interface is the one nobody notices.
Quality Doesn't Matter ... Until It Does
Why quality standards must differ between social apps and enterprise software - and how investor pressure, low barriers to entry, and AI are driving a visible decline in the software that actually runs businesses.