Notes on web technologies, engineering tradeoffs, and front-end architecture.
- Why you should not access browser globals directly Direct access to window, document, navigator and globalThis couples your code to the runtime, makes side effects harder to isolate, and leads to brittle tests.
- Stop adding console.log: use logpoints instead Logpoints let you inspect runtime behavior without changing your code, polluting commits, or pausing execution.
- Why Testing Library is not unit testing Testing Library is useful, but rendering components and testing them through the DOM is integration testing, not unit testing.
- Why you should not ship test IDs to production React Testing Library works best with semantic queries like role and label. Shipping data-testid to production hides accessibility problems and turns test-only markup into an accidental contract.
- Git LFS is useful, but it is not a free storage upgrade Git LFS solves a real problem for large binary files, but it also adds workflow and operational complexity that teams should adopt intentionally.
- Why git bisect is one of Git's most underrated features git bisect helps you find the commit that introduced a regression, but large squash merges remove the history that makes it truly effective.
- Why I do not use enums in TypeScript Enums add runtime behavior, work against modern TypeScript workflows, and have simpler alternatives like string literal unions and const objects.
- High coverage is not enough: mutation testing in TypeScript with Stryker Code coverage shows what your tests execute. Mutation testing shows whether your tests fail when the code is wrong, and where Stryker fits.
- Avoid truthy and falsy checks in TypeScript Truthy and falsy checks in TypeScript hide intent and can introduce bugs. Prefer explicit checks for the values you actually care about.
- Prefer Task over Promise in TypeScript Promises hide failure in an untyped rejection path. Task from true-myth makes asynchronous success and failure explicit in TypeScript.
- Avoid throwing for expected failures in TypeScript Use Result in TypeScript for expected failures, Maybe for absence, and reserve exceptions for truly exceptional situations.
- The Billion-Dollar Mistake: Avoid "null" in TypeScript Why null still causes bugs in TypeScript - and how Maybe types make absence explicit.
- Dependency injection without frameworks in TypeScript Explicit dependencies improve clarity and testability. You do not need a framework to achieve that.
- Why your unit tests feel fragile Unit tests do not feel fragile because testing is hard. They feel fragile because our design mixes business logic and side effects.
- Why I started this Blog Why I finally decided to start writing on echooff.dev and what I want this blog to be.