TypeScript & Node.js
Our default for business applications and APIs. One language across the stack, a mature ecosystem, and a type system that makes refactoring safe.
- Fastify, Express, NestJS
- Strict mode, no implicit any
We keep to mainstream, well-documented tools. Not from caution, but because your system has to be maintainable by engineers who are not us — which is exactly the position you should be in.
01 — The rule
Every dependency is a commitment somebody has to keep for years. Before we add one, it has to survive these.
When a project genuinely calls for something unusual, we make the case in writing, note the trade-off in an architecture decision record, and get your agreement before committing.
Twenty pages, no framework, no build step in production, no third-party requests, no cookies. The whole thing is HTML, one stylesheet, one script and two self-hosted typefaces.
It is not the right architecture for every product. It is the right architecture for this one, and that distinction is the entire point.
02 — The stack
Not an exhaustive list of everything anyone here has ever touched — the things we are genuinely fluent in and willing to support.
Our default for business applications and APIs. One language across the stack, a mature ecosystem, and a type system that makes refactoring safe.
Where data processing, scripting or scientific libraries lead. Typed, linted and packaged like any other production code.
For services where predictable latency, small binaries and low memory matter — integration workers, high-throughput APIs, CLI tooling.
Semantic HTML and modern CSS do more than most teams assume. Grid, container queries, custom properties and view transitions replace a lot of former JavaScript.
When an interface has genuine application state. Server components where they reduce shipped JavaScript, client components where interaction requires them.
React Native for shared codebases; Swift and Kotlin when the app leans on the platform. The choice is argued per project, not assumed.
Our default system of record. Constraints in the database rather than only in the application, and migrations versioned alongside the code.
Redis for caching, locks and lightweight queues. Dedicated brokers when delivery guarantees justify the extra moving part.
When reporting queries start hurting the transactional database, we separate them rather than adding indexes forever.
Terraform in your repository, reviewed like application code. No environment exists that cannot be rebuilt from a commit.
Containers on a managed platform by default. Kubernetes when the scale and the team genuinely justify the operational cost.
Structured logs, metrics and traces from the first deployment, not retrofitted after the first outage.
Unit tests for logic, integration tests at every boundary, end-to-end tests for the journeys whose failure a customer would notice.
Type checking, linting and formatting enforced in CI so review conversations are about design rather than semicolons.
Dependency scanning on a schedule, pinned versions, and an upgrade plan rather than an annual panic.
03 — A note on AI tooling
Our engineers use AI assistants the way they use any other tool — for boilerplate, for exploring an unfamiliar API, for a first draft of a test. What does not change is that a human reads every line, a second engineer reviews it, and the automated suite has to pass before anything merges.
We do not send client source code or production data to a third-party service without your written agreement, and where a client prohibits such tooling entirely we work without it. If you would like this stated explicitly in the contract, ask — we will put it there.
Tell us what it is. We would rather work inside your constraints than sell you a rewrite you do not need.
HALDIR LTD · HE 459882 · Nicosia, Cyprus