Tooling & Developer Experience (DX)

Tooling & Developer Experience (DX)

Want to propose a change, disagree with a placement, or add an interesting new technology? Please reach out to @Damian Szafranek. This Tech Radar is a living document - we keep it useful by updating it together as our projects, tools, and experiences evolve.

Scope

Tools that support the developer workflow rather than shipping with the product: linters and formatters, code quality and static analysis, dependency and package management, monorepo tooling, and whatever keeps development environments consistent. Libraries we pull into applications belong in Libraries & Utilities. Anything whose value comes from a model belongs in one of the AI categories: a tool that does engineering work on your behalf in Agentic Coding, an extension for such a tool in Agent Skills & MCP Servers, and everything else model-related in AI & LLM Tooling.

Overview

ADOPT

Proven technologies we have high confidence in; our default choices.


Biome

npm

pnpm

Checkstyle

PMD

Spotless

Lombok

ruff

uv

pre-commit

Obsidian

Generated Documentation

TRIAL

Promising technologies to explore and evaluate for adoption.


Lefthook

ty

ASSESS

Interesting technologies requiring investigation.


Turborepo

HOLD

Not recommended for new work; plan migration from existing uses.


ESLint

Prettier

TSLint

Technologies Breakdown

Biome ADOPT

Our default linter and formatter for JavaScript and TypeScript, import sorting included. Use it on new frontend projects, and prefer it over adding ESLint and Prettier. It is already the default in our sd-react-template.

One fast tool and one configuration file replace the ESLint and Prettier pairing that every project used to wire up by hand, along with the plugin drift that came with it. It is the default in our shared React template and in daily individual use, which is what promotes it here.

The honest limit is lint coverage. Biome carries its own type inference and covers most of what we relied on, but it is not at parity with the most aggressive typescript-eslint rules, so a project that leans on those should keep ESLint alongside it. Formatting is the clean case: Biome is a practical drop-in for Prettier.


npm ADOPT

The default package manager bundled with Node.js. Used for managing project dependencies (package.json, package-lock.json) when pnpm is not used or for compatibility reasons.

Comes standard with Node.js, universally understood. While pnpm is preferred, npm remains adopted as the baseline and fallback package manager.


pnpm ADOPT

The preferred package manager for managing dependencies in new projects, especially effective in monorepos. Manages dependencies via package.json and pnpm-lock.yaml.

Offers significant improvements in installation speed and disk space usage compared to npm by using a content-addressable store. Provides strictness that prevents phantom dependency issues. Adopted as the preferred standard for its efficiency benefits.


Checkstyle ADOPT

Standard Java code-style enforcement. Keeps conventions consistent across teams and projects.

Checkstyle helps prevent style drift and reduces review noise by enforcing agreed conventions automatically. Adopt it as a baseline quality gate in JVM projects, tuned to rules that support readability and maintainability rather than personal preferences.


PMD ADOPT

Static analysis for catching common Java code issues and code smells early beyond formatting and style.

PMD complements formatting and style checks by flagging problematic patterns (complexity, error-prone constructs, maintainability issues). Use it as part of the standard quality toolchain to keep technical debt from silently accumulating.


Spotless ADOPT

Build-integrated formatter that keeps code consistently formatted automatically—reducing “format wars” in reviews.

Spotless enforces formatting as part of the build, making it easy to keep style consistent across IDEs and contributors. It’s especially effective when paired with other quality gates (Checkstyle/PMD) to separate “format” from “logic” in code reviews.


Lombok ADOPT

Productivity library that reduces boilerplate in Java (getters/setters/builders, etc.) while keeping codebases readable.

Lombok can significantly cut repetitive code and make models and DTOs cleaner. Use it intentionally and consistently, and be mindful of team conventions and IDE/tooling setup so the generated code remains transparent to contributors.


ruff ADOPT

The linter and formatter for new Python work, replacing flake8, isort, black and pyupgrade with one tool and one configuration. The Python counterpart to what Biome does for JavaScript.

On the LLM platform we delivered in 2026 it ran twenty-seven rule families including security, async and framework-specific checks. The effect worth reporting is social rather than technical: formatting stopped being a review topic, because there was nothing left to discuss. It is the direction of travel for Python tooling, and it is what we would set up on the next Python project without discussion.


uv ADOPT

The package manager and lock tool for new Python work. Its underrated feature is running a tool ephemerally, without adding it to the project's dependencies.

It managed dependencies on the LLM platform we delivered in 2026, but the part worth copying is the ephemeral run. Every load measurement on that project was taken with a tool invoked on the fly rather than installed as a project dependency, which keeps measurement tooling out of the lockfile entirely. One caution recorded from that project: a snap-packaged wrapper produced a silent non-zero exit that looked like a test failure, and pointing at the real binary fixed it.


pre-commit ADOPT

Worth using to put the cheap checks where they cost least, at commit time, and the slow ones at push. Sits alongside Lefthook on this radar as the other way to manage hooks.

Nineteen hooks in two stages on the LLM platform we delivered in 2026: whitespace, secret scanning, linting and security scanning at commit, then type checking, unused-dependency detection, the single-migration-head gate and documentation regeneration at push. Splitting the stages is what makes the discipline survive, because a hook that takes a minute on every commit is a hook people bypass.


Obsidian ADOPT

Worth using for a private knowledge base of methods and hard-won lessons, deliberately kept separate from the repository so that how we work does not drift with what we shipped.

Used as a private vault alongside a 2026 platform delivery, holding review runbooks and a numbered catalogue of edge cases, each one an error that got past review once. Numbers are never reused, so a reference stays a permanent address that later pull request notes and retrospectives can point at. The deliberate cost is that it is not a git repository, so there is no review and no history, which is the price of it being a place to think rather than a place to publish. Repository-tracked documentation is a different job and stayed in Markdown.


Generated Documentation ADOPT

Generate documentation that can be generated, then fail the build when the committed copy no longer matches. Applies to API specifications, entity diagrams, permission tables and API client collections.

On the LLM platform we delivered in 2026 the OpenAPI specification, an entity-relationship diagram, a role and permission matrix and a Postman collection were all produced from the code, and a continuous integration gate regenerated them and failed the pull request on any difference. Generated documentation cannot lie about the code, which hand-written documentation does quietly and constantly. The lesson that made it worth the setup: matching endpoint counts is not freshness, because a changed field requirement broke nine test collections while an endpoint-coverage audit saw nothing wrong.


Lefthook TRIAL

Worth using for pre-commit and pre-push hooks on new projects. Fast, and the whole configuration is one readable file.

Lefthook manages Git hooks with less ceremony than Husky and runs hook commands in parallel, which is what keeps a pre-commit hook from becoming the thing everyone bypasses with --no-verify. It is in individual use and has been straightforward to configure. Trial until it has run on a shared project long enough to show whether the hooks stay useful or quietly get skipped.


ty TRIAL

Worth trying as the type checker on new Python work, in place of mypy. Note that it was still beta when we used it, so treat a confusing result as possibly the tool rather than the code.

It earned its place on the LLM platform we delivered in 2026 in an unusual way: it correctly flagged a Liskov substitution violation in a planned refactor, and the refactor was abandoned rather than forced through. A tool that saves time by saying no is rare enough to be worth recording. Trial rather than Adopt because of the beta status and a single project's use.


Turborepo ASSESS

Investigate as a potentially simpler alternative for managing monorepos, focusing primarily on optimizing build and test times through caching and task orchestration. Compare with manual scripting or other potential solutions if monorepo needs arise.

Developed by Vercel, Turborepo focuses specifically on high-performance build caching within monorepos. Assessing its capabilities, ease of use, and suitability for our potential monorepo needs, especially given its focus compared to more comprehensive tools previously assessed.


ESLint HOLD

Not for new frontend projects; reach for Biome instead. Keep ESLint where a project depends on type-aware rules that Biome does not yet cover, or on a plugin with no Biome equivalent. Existing projects can stay on it and migrate when convenient.

ESLint is not deprecated and its plugin ecosystem is still the largest in the JavaScript world. It sits at Hold because we have a single tool that does linting, formatting and import ordering, and running ESLint as well means maintaining two configurations for one job.

The exception is real rather than theoretical. Biome detects roughly three quarters of the floating promises typescript-eslint catches, and the deepest type-aware checks that need the full TypeScript language service are not all there yet. A project relying on those should keep ESLint and say so in its own README. Note this applies to JavaScript and TypeScript only: our JVM code-quality tools, Checkstyle, PMD and Spotless, are unaffected and stay Adopt.


Prettier HOLD

Not for new frontend projects; Biome formats the same languages and is a practical drop-in. Existing projects can stay on Prettier and migrate when convenient.

Prettier settled the code-style argument and there is nothing wrong with it. It sits at Hold only because Biome does the same job as part of one tool we already run, so keeping Prettier means a second formatter and a second config for no gain. Unlike the linting side, there is no coverage gap here worth keeping it for.


TSLint HOLD

Avoid completely. TSLint was deprecated in 2019. Projects still using TSLint must migrate to Biome, which is our default linter and formatter.

The project is deprecated and unmaintained, and lacks support for modern TypeScript features. Migrate to Biome, which covers linting and formatting in one tool. ESLint is also on this radar at Hold, and remains the right target only for a project that depends on the type-aware rules Biome does not yet cover; its entry records that exception.