Arqora logoA R Q O R A
arqora / development

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.

How we build
Standards

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.

Testing

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.

Process

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

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

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.

Architecture

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.

The stack
Languages
TypeScriptPrimary language for all web and tooling work
GoSystems tooling, CLIs, backend services
RustPerformance-critical and security-sensitive work
ShellAutomation, deployment scripts, environment setup
SQLData modelling and schema management
Frontend
Next.jsApp Router, server components, edge-friendly
ReactUI composition and interactive surfaces
Tailwind CSSUtility-first styling with a defined design system
Framer MotionAnimation where it earns its complexity
Backend & data
PostgreSQLPrimary relational store for durable data
RedisCaching, pub/sub, ephemeral state
SQLiteEmbedded storage for edge and local-first tools
Bun / NodeJS runtime depending on the project's constraints
Tooling
TurborepoMonorepo build orchestration
BiomeLinting and formatting — fast, opinionated
VitestUnit and integration testing
DockerLocal development and container builds
GitHub ActionsCI — build, test, typecheck on every push
The process
01

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.

02

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.

03

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.

04

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.

05

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.

ArqoraDevelopment
Active development