September 17, 2025

When we set out to build Mapped, we weren’t just thinking about the next feature or release. We were thinking about longevity: how to build software that a small team can maintain for years without grinding under the weight of technical debt.
Mapped is a living experiment in this philosophy. Along the way, we’ve made architectural choices and set guiding principles that others might find useful — especially teams who want their tools to last beyond the latest framework trend.
We chose a monolithic TypeScript codebase. On the surface, this might feel old-fashioned in the age of microservices. But simplicity has benefits:
The lesson: don’t chase complexity for its own sake. A simpler system is often more resilient.
Every third-party package you add is a bet on someone else’s future. If they abandon it, you inherit the burden.
Our approach:
This isn’t about “not invented here.” It’s about durability. A dependency that accelerates you today can become quicksand tomorrow.
Mapped is built on Next.js. For us, the key lesson has been clarity around what runs where.
We separate client and server code explicitly. This keeps mental models simple, avoids accidental misuse, and makes the system easier to reason about as it grows.
The principle: invisible boundaries are brittle. Explicit boundaries are durable.
We started with GraphQL but found the overhead and risks outweighed the benefits. We’re now moving to tRPC, which gives us:
tRPC also reinforces an API-first philosophy. Mapped isn’t just an app — it’s part of an ecosystem. The same API that powers our UI can power other tools.
The principle: pick tools that amplify your approach, not ones you need to fight against.
As a small team, we can’t always rely on cultural solutions like detailed code reviews. Instead, we invest in technical guardrails: linting, automated testing, and build-time checks that enforce consistency.
The principle: processes that rely on discipline fail under pressure. Processes baked into the system endure.
Forms and validation are deceptively complex. Our rule is simple:
By using shared schemas, we avoid duplication and ensure consistency across layers.
The principle: validate at the source of truth, not just at the edges.
Global state libraries can make React apps fast and elegant. They can also create invisible complexity. For now, we’ve chosen to keep things simple with React Context, revisiting the decision when the need becomes clear.
The principle: don’t optimise for problems you don’t yet have.
Mapped is more than code — it’s an experiment in sustainable software. The guiding thread through all of these decisions is durability: fewer moving parts, fewer fragile dependencies, stronger boundaries, and technical guardrails that do the heavy lifting.
For small teams especially, this approach can mean the difference between a product that burns out and one that endures.