PocketArC LogoPocketArC

Hardcore TypeScript: Maximum-strictness static analysis with Biome and ESLint.

Cover Image for Hardcore TypeScript: Maximum-strictness static analysis with Biome and ESLint.

A few days ago I published Hardcore PHPStan, a living reference for the strictest PHPStan config I could put together for Laravel. Same thesis applies on the frontend: AI writes the bulk of my TypeScript and React code now, and deterministic guardrails are the only thing that keeps it from cutting corners.

This is the companion to that post. A living reference for the strictest TypeScript + Biome + ESLint config I could put together, with the reasoning behind every rule: pocketarc.com/typescript.

The stack

Biome handles linting, formatting, and import organization, and it's fast enough to run on every keystroke. typescript-eslint fills the gaps Biome hasn't implemented yet (the any-propagation rules, deprecation at call sites, strict boolean expressions, weak crypto detection). It's slower, so it runs in pre-commit and CI rather than on every save.

The lint command runs all three in order:

biome check --write src/ && tsc --noEmit && eslint src/

Biome runs first with auto-fix. TypeScript runs second to type-check. ESLint runs last for the remaining checks. If any of them fail, your build fails.

Why it matters for AI-generated code

LLMs trained on the corpus of TypeScript that exists on the internet have absorbed every bad habit the language allows. They write process.env.API_KEY.trim() instead of process.env.API_KEY?.trim(). They write useEffect(() => fetch(url), []) with a missing dependency array entry. Stuff like that.

Static analysis catches all of this. You can tell an LLM "use strict types" in a system prompt, and it'll mostly comply. The linter makes sure it 100% complies.

What the config covers

The Hardcore TypeScript reference covers:

  • Every strict TypeScript flag beyond strict: true, with the reasoning behind each one.
  • Biome's domain system (next, react, project, types) all set to "all" for maximum strictness, including type-aware nursery rules like noFloatingPromises and useExhaustiveSwitchCases.
  • Cognitive complexity limits, disallowed calls, explicit return types, and naming conventions.
  • typescript-eslint's strict-type-checked preset for the any-propagation rules, deprecation detection, strict boolean expressions, and eslint-plugin-security for weak crypto.
  • The full tsconfig.json, biome.json, and eslint.config.js, ready to drop into a project.

The full config with every rule explained is at pocketarc.com/typescript. I'd love to hear what you think. Reach out via email or X/Twitter.

Same warning as with the PHPStan config: when adding this to an existing project, this config will surface a lot of errors. If only you had a code generation tool to automatically fix those errors... ๐Ÿ˜‰