How Arqora
writes software.
The stack, the standards, and the process behind every system Arqora builds — internal tools, public-facing surfaces, and everything in between.
Code is read far more than it is written.
Arqora's development approach is shaped by one constraint: the code we write today will need to be understood, modified, and debugged by someone — often us — months or years from now. That future reader is the primary audience of every line written.
This isn't a philosophical position. It's a practical one. Systems that can't be understood can't be improved, and systems that can't be improved slowly become liabilities. Clarity is a feature, not a preference.
Typed end-to-end
TypeScript is not optional at Arqora. Every surface — API contracts, database schemas, config shapes, environment variables — is typed. Runtime surprises are a documentation failure.
Tests that earn their existence
No coverage targets. No test-for-the-sake-of-testing. Tests exist where a regression would be costly and where the behaviour is non-obvious. Everything else is clarity-of-code's job.
Small, reviewable changesets
A PR that can't be understood in one sitting is a PR that's too large. Scope is kept tight — not because of a rule, but because small changes are easier to revert, easier to understand, and faster to ship.
Automation where it removes friction
If a step is manual and repeatable, it gets automated. CI enforces types, lint, and tests on every push. Deploys are scripted, not clicked through. The goal is to make doing things right the path of least resistance.
Security by default
Secrets never touch version control. Dependencies are audited. Environment variables are validated at startup. Security isn't a phase of development — it's a constraint that shapes the architecture from the start.
Reversibility over cleverness
Clever code is hard to change. Arqora optimises for systems that can be corrected — clear boundaries, minimal implicit coupling, data migrations that can be rolled back. The ability to be wrong cheaply is a feature.
Start with the interface, not the implementation.
Before writing a function, define what it takes and what it returns. Before building a service, define the API contract. The interface is the design — the implementation is just how you honour it.
Write the simplest thing that could work.
Abstractions are taken on when they've been earned by actual repetition, not anticipated repetition. Premature abstraction creates complexity that outlives the problem it was meant to solve.
Type it, test the edges, ship it small.
A typed codebase with tests on the non-obvious paths is more valuable than full coverage with loose types. Ship in small increments so that something going wrong has a clear culprit.
Document the why, not the what.
Code explains what it does. Comments and documentation explain why it does it that way — and specifically what constraints or decisions led here. Future maintainers need the reasoning, not the paraphrase.
Revisit before adding.
When something feels wrong, the answer is rarely to add more. It's usually to remove something, simplify something, or reconsider an earlier decision. Addition is the path of least resistance. It is rarely the right path.
None of this is doctrine. The stack changes when something better fits the problem. The process evolves when we find it failing us. The only constant is the underlying goal: code that can be understood, corrected, and improved by whoever comes next.