Skip to content

xndrjs

A clean cut through complexity for scalable fullstack TypeScript.

xndrjs is a TypeScript toolkit for teams that want Clean Architecture without over-engineering their codebase from day one, while leaving room to evolve as complexity grows.

It helps you keep the core of your system as independent as possible from React, Next.js, Angular, SvelteKit, backend frameworks, databases, queues, and other infrastructure details.

Frameworks stay useful entry points. Your domain stays the place where meaning, rules, and correctness live.


Architecture over frameworks

Clean Architecture starts from a simple idea: the core of your application should not depend on delivery mechanisms.

UI frameworks, runtimes, databases, and external services are adapters. They should plug into your system, not shape it.

xndrjs gives TypeScript projects small primitives for making this separation explicit instead of relying on custom solutions and discipline alone.

Domain modeling first

The domain model is where xndrjs is most opinionated, because it is often the most under-modeled part of a TypeScript application.

When values, invariants, transitions, and guarantees are explicit, the rest of the architecture becomes easier to organize.

xndrjs focuses on APIs that are both correct by architectural standards and ergonomic enough to use every day.

Meaningful boundaries

The toolkit defines orthogonal responsibilities that compose instead of getting tangled.

For example, domain modeling is split into:

  • validation -> what data is allowed (Validator)
  • representation -> what data can be trusted (shape, primitive)
  • behavior -> how data evolves (capabilities)
  • guarantees -> what additional conditions hold (proof)

This gives each concept a natural home and keeps business meaning out of controllers, components, handlers, and persistence code.

Correct by construction

Instead of scattering validation across the codebase, xndrjs makes it part of how data is created and transformed.

Once a value enters the system through a domain boundary, it is:

  • validated
  • immutable
  • safe to use

This removes entire classes of bugs and eliminates uncertainty about data correctness.

If you can create/transform it, it’s valid.

Adapters, not lock-in

xndrjs integrates with Zod, Valibot, AJV, OpenAPI, and other validation sources through adapters.

Your code depends on a small validation contract, not on a specific schema engine.

That lets each boundary use the tool that fits it best while the domain continues to speak in Email, User, Order, VerifiedUser, and named capabilities.

Beyond the domain

xndrjs also includes a small package for retryable async tasks. And there will be more.

But these areas are harder to capture with a large universal API, so the toolkit stays intentionally light there.

The goal is to provide useful primitives and clear guidance for integrating them into your own architecture, while keeping framework and infrastructure choices outside the core.

  1. Read the introduction to see what xndrjs is and what it deliberately is not.
  2. Read the mental model to understand how xndrjs thinks about trust boundaries.
  3. Build the first model to see primitive, shape, capability, and proof working together.
  4. Pick an adapter with Choose an adapter.
  5. Use the Domain overview and Tasks to place the packages inside a Clean Architecture project.