Skip to content

Front end

React

The component library we build most interfaces in, from a schema designer and a social timeline to client marketing sites.

React is a library for describing what a screen should look like given some state, and letting something else work out which parts of the page to change. It is not a framework. It has no opinion about routing, data fetching, forms or the build, which is why every React project is really React plus five other decisions, and why two React codebases can look nothing alike.

How we use it

It is behind almost everything on our shelf. The Objectify dashboard is React 19 with React Router 7, and it is the hardest interface we run: a visual schema designer, a spreadsheet-style data explorer, a SQL editor and an audit log, all over a multi-tenant API. ClassProfile is React 18 driving a feed, profiles, connections and a settings area where the visibility rules are more subtle than they look, a subject we picked apart in four visibility levels and what they cost.

@Heartbeat uses it for an infinite timeline with polls, media uploads and live notification counts, DMARC Engine for multi-domain analytics dashboards, 360nutri for a camera capture flow on a phone, and Jonosakti for five sections of forms and listings. It also does duty on plain client sites: Taxcare Accountancy is a React single page application with an interactive Making Tax Digital calculator sitting inside a marketing site, Linked Corporate is a static export with a filtered gallery, Starterflare has a thin React front end over a much larger backend, and the AHZ Associates sites serve Next.js build output, so React by inference from what is shipped rather than from source we hold.

What it costs you

You assemble the rest yourself, and those choices age at different speeds. A five year old React app is usually a museum of the routing and state libraries that were current when it started, and the upgrade is never just React. Version churn is real: 18 to 19 changed enough around refs, context and the compiler story that a large codebase needs a proper pass, not a version bump, which is the pattern described in dependency rot.

Performance is opt-in. The default is to re-render more than you need, and on a busy screen such as a timeline that turns into dropped frames on a mid-range Android phone. Fixing it means memoisation, stable keys and virtualised lists, and none of that is free to read afterwards. There is a floor on the shipped JavaScript too: even a well-split bundle costs the browser a parse and an execute before anything appears, which is a poor trade for a page whose job is to show eight paragraphs of text.

Accessibility is entirely your problem. Nothing in the library stops you shipping a div with an onClick where a button belonged.

When we would choose something else

For anything where the first paint matters and the content is mostly text, we would put it behind a framework that renders on the server or at build time rather than a bare client bundle, which is the case made on Next.js. A brochure site does not need a runtime to display a phone number.

If a project already runs on Laravel, we would use Vue instead and keep the stack coherent, exactly as Consonas does. And for a page that is genuinely static, sixteen office addresses and a map, we would ship HTML from a build step, with the interactive parts kept to the handful of components that actually need state.

Where we have used it

Every build below lists this in its stack, so the claim is checkable.