Capxul · Delivery · 31 August 2026

We stopped building features
into the app.

We build them into the SDK now — the published set of ready-made pieces that any app can drop in, ours or somebody else's. The pieces are headless components: they carry all of the behaviour and none of the appearance. That sounds like an internal detail. It is the most consequential thing that happened this week.

4SDK releases in seven days
2capabilities delivered end to end
−1,174lines removed from the app, while gaining a feature

What changed in how we build

Until this week, the difficult part of a feature lived inside the screen that showed it. Contacts logic lived in the contacts screen. Working out what somebody is allowed to do was written into every screen that needed to know — slightly differently in each one.

We paid both costs of that. A bug had to be fixed in four places, and we usually found three. And every new screen started from nothing, because there was nothing to reuse.

Now it is built once, in the SDK, and it draws nothing. One piece knows how to load your contacts, add one, rename one, hide one, what to do while it is loading, and what to report when it fails. It does not know what any of that looks like. Whoever places it supplies the look.

Behaviour is built once and shared. Appearance stays entirely with whoever is building the screen.
One headless component all behaviour, no appearance Personal dashboard Organisation dashboard The full Contacts screen Somebody else's product its own design its own design its own design their design

What one of them actually looks like

This is the contacts capability, as a developer uses it. It is worth looking at even if you do not read code, because the shape of it is the whole argument.

orange — ours, from the SDK green — yours, whatever you want it to look like
// Everything about contacts. Draws nothing.
<CapxulContacts actor={me} onAdded={toast} onFailed={showError}>

  // The count tile.
  <CapxulContacts.Summary>
    {({ total, activeCount }) => <YourStatTile value={total} sub={activeCount} />}
  </CapxulContacts.Summary>

  // The list. Five rows on a dashboard, all of them on a full screen.
  <CapxulContacts.List limit={5}>
    {({ rows, isLoading }) => rows.map((r) => (
      <YourContactRow
        key={r.id}
        name={r.name}
        initials={r.initials}
        onRename={r.rename}
        onHide={r.hide}
      />
    ))}
  </CapxulContacts.List>

</CapxulContacts>

Three things are true in that snippet, and they are the reason this matters.

The values arrive finished

total, activeCount, rows, initials — already fetched, already correct, already consistent between the dashboard and the full screen. Nobody writes that twice.

The actions already work

r.rename and r.hide are wired to the backend, with the loading and failure cases handled. You attach them to a button. You do not implement them.

Everything green is yours

YourStatTile and YourContactRow are whatever you like — our design, a partner's design, a completely different product's design. We never say what a contact looks like.

Permissions are the same idea, smaller. This is a real button that only exists for somebody allowed to spend:

<CapxulOrgMember.Can action="spend">
  {({ allowed }) => allowed && <YourPayButton />}
</CapxulOrgMember.Can>

allowed is false until the real answer arrives, deliberately. A pay button can never flash into view for somebody who is not allowed to press it. That rule now lives in one place instead of being re-remembered on every screen.

Which means other people can build on this

A component that carries no appearance is one anyone can restyle completely. They are not adopting our design, our brand, or our layout — they take the behaviour and draw their own product on top. Payments, contacts, permissions, spending limits and history stop being things they have to build.

This is the difference between a company with an app and a company with a platform. We are quietly becoming the second one.

And it makes Capxul something an agent can build with. This is the part worth sitting with. An AI agent asked to build a payments screen today has to understand payments, permissions, balances and the blockchain, and it will get some of that subtly wrong. Given these pieces it does not have to understand any of it.

The hard parts are named and typed

Every piece announces exactly what it hands over — the values, the actions, the failure cases. An agent reads that and knows what it is allowed to do. There is nothing to guess and nothing to reinvent.

So the agent only writes appearance

Which is the part agents are genuinely good at. The money logic underneath is ours, already correct, already tested. It cannot be got subtly wrong by a confident guess.

Someone should be able to point an agent at Capxul and have a working, styled payments product back, without that agent touching a single line of money handling. Every capability we move into the SDK makes that more true. It is the same work we would have done anyway, done in a better place.

What it already bought us this week

The app got smaller as it got better

Fitting one of this week's capabilities into Capxul deleted around 2,700 lines and added around 1,500. The app came out roughly 1,200 lines lighter and gained the feature.

That is not a vanity number. It is fewer places for something to break, and less to read before anyone — or any agent — can change anything.

Nothing on screen moved

Because these components bring no appearance with them, Capxul still looks exactly like Capxul. The designs did not change. We connected finished screens to real behaviour rather than redrawing them.

That is a deliberate rule while the capabilities land, not a happy accident.

What is in the SDK now

Four capabilities went in this week. Each one is a root that holds the behaviour, plus named parts a screen arranges however it likes.

CapxulContacts

.Summary · .List · .Add

An address book where a person stays the same person after they sign up, so their payout details never orphan.

CapxulSendMoney

.Recipient · .Amount · .Asset · .Actions

One send flow serving both a person and an organisation, instead of two that drift apart.

CapxulOrgMember

.Standing · .Can

Whether somebody may manage people or spend money, and which budgets they hold, with the real limit on each.

CapxulDashboardAccess

.Checking · .Granted · .Redirect

Whether this person may be here at all, decided once rather than guessed by each screen.

Beneath them sit around forty smaller building blocks — balances, holdings, payments, invitations, permissions — that any screen can use directly.

Where the eight capabilities stand

These are the eight on the queue. Each is a complete thing a person can do, and each now gets built the same way — into the SDK first, then placed into our screens.

Contacts

An address book where a person stays the same person after they sign up.

In the SDK

Access & session

Standing, permissions and budgets, answered in one place instead of guessed per screen.

In the SDK

Activity & history

The money feed — filters, export, notes, receipts, and a payslip for the person who was paid.

Next release

Send / Quick Pay

One send flow serving both a person and an organisation, rather than two that drift apart.

Building

Payroll

Rosters, pay runs, run records, payslips.

To design

Invoices

Issue and settle, and a payment link for the person being billed.

To design

Personal inbox

The screen is missing. Everything behind it already exists.

To design

Receive & wallet

Taking money in from outside Capxul.

Queued

Five more sit behind these — scheduled and streaming payments, treasury, withdrawals, organisation membership. Eight further ones are parked on purpose and carry no work at all.

The rhythm this establishes

Four releases went out in seven days. Before this week, releases carried foundation work — necessary, invisible, impossible to demonstrate. These four carried capabilities.

29 AUG

Contacts goes out. The address book stops being a guess.

30 AUG

Access goes out. Permissions and budgets answered honestly, in one place.

31 AUG

Two more, hardening the money path — interrupted setups recover, invitations activate on the spot, permission grants retry until the chain confirms them.

That is the cadence we are holding: a capability leaves the SDK, the app picks it up, and the app gets simpler each time it does. Repeat until the queue is empty.

One supplier also left the building. Reading somebody's balance no longer goes through a paid third party — it goes through our own node, which we already run.

Where this stops, honestly

Four of the eight are moving. The other four have not had their turn, and nothing about them is blocked — we are simply not starting a fifth while four are in flight. Each goes through the same three stages before any code is written: map what exists, answer every unknown, agree the shape.

That gate is the reason this week did not stall. Skipping it is exactly what cost us three weeks in August.