Server-rendered React, budgeted before it ships.
React and Next.js engineers who build performance-budgeted, accessible, server-rendered web applications — the front-end stack behind Odeontech’s own products and our client web work.
- TypeScript
- React
- Next.js
- Tailwind
- Storybook
- Playwright
React is how we build interfaces, and Next.js is how we ship them.
Our own product consoles — the loyalty operator’s screens, the sales-plan designer, the carrier portal — are built on React, served through Next.js. We chose the pair for a plain reason: server rendering gives fast first paint and search-friendly pages out of the box, the component model keeps large interfaces maintainable, and the ecosystem is deep enough that we rarely write plumbing.
Next.js in particular solved problems we used to solve by hand: routing, code-splitting, image optimisation, caching per route, and the boundary between server and client code. Server Components move data fetching to where the data lives and cut the JavaScript shipped to the browser — which is what a Core Web Vitals budget rewards.
It is not the answer to everything. A content-only site with no interactivity may be better served by a static generator; a highly interactive canvas or real-time dashboard may want a client-first architecture with a thin API. We start from the user journey and pick the rendering model that fits it, then hold it to a budget.
Six kinds of front-end we ship on React and Next.js.
Customer-facing web applications
Account areas, checkout flows, booking journeys and self-service portals — server-rendered for speed and search, hydrated only where interaction needs it, measured against a per-route performance budget.
Operator consoles and back-offices
Data-dense internal tools with tables, filters, forms and approvals. We design for keyboard use, long sessions and large tables without the interface falling over.
Marketing and content sites
Next.js with Payload CMS or a headless CMS of your choice: editors publish without a deploy and pages render at the edge.
Design systems and component libraries
Tokens, primitives and documented components in Storybook, with visual regression tests and accessibility checks in CI, so every team builds from the same parts.
Progressive web apps
Installable, offline-tolerant web applications for field and retail staff where a native app is not justified — service workers, background sync and a cache strategy you can explain.
Micro-front-end integration
Incremental replacement of a legacy front-end: Next.js takes over a route at a time behind the same domain, sharing auth and design tokens with what remains.
When to choose it.
Choose React and Next.js when the product is a web application that must be fast on first load, indexable by search engines and maintained by more than one team over several years. It fits a TypeScript back-end particularly well: shared types travel from the API to the component. It also fits organisations that want one hiring profile for web, and a path to React Native for mobile.
Do not choose it for a five-page brochure site that a static generator would serve just as well, for a native-feeling mobile experience where React Native or Flutter is the honest answer, or when your organisation already runs a mature Angular or Vue estate with the tooling and people to match. Migrating a working front-end to React for its own sake is a cost, not an upgrade.
Data fetched on the server, cached by tag, revalidated on write.
export default async function Statement({ params }: Props) {
const statement = await getStatement(params.memberId, {
// cached at the edge until a redemption invalidates the tag
next: { tags: [`member:${params.memberId}`], revalidate: 300 },
});
return (
<StatementTable rows={statement.rows} currency={statement.currency}>
<RedeemButton memberId={params.memberId} />
{/* the only client component on this route */}
</StatementTable>
);
}How a Next.js front-end fits the rest of the estate.
What we hold our front-ends to.
- Per-route performance budgets. LCP, INP and CLS targets per route, checked by Lighthouse CI on every pull request; a broken budget fails the build rather than the launch.
- Accessibility as a gate. WCAG 2.1 AA: semantic markup, keyboard paths, focus management and automated axe checks — plus a manual pass on every new pattern.
- Server first, client where needed. Components are server-rendered by default;
'use client'is a deliberate decision recorded in review, not a habit. - Typed all the way down. API responses typed from the OpenAPI or GraphQL schema; props typed; forms validated with the same zod schema the back-end uses.
- A design system, not a folder of components. Tokens, documented primitives and Storybook stories with visual regression tests, so the interface stays consistent as teams grow.
- Tests where users are. Playwright journeys for the flows that make money, component tests for the tricky interactions, and nothing that tests the framework.
- Observability in the browser. Real-user Web Vitals, error tracking with source maps, and release markers on the dashboards so regressions are attributable.
- Security by default. Strict CSP, no secrets in client bundles, dependency scanning, and auth handled by a provider rather than hand-rolled sessions.
What usually ships alongside it.
- A Next.js application on Vercel or your Kubernetes cluster with preview environments per pull request
- A documented component library in Storybook with tokens, stories and visual regression tests
- Lighthouse CI and axe checks in the pipeline with the budgets written down
- Playwright journeys for the critical paths, running against every preview
- Real-user monitoring, error tracking and a Web Vitals dashboard
Frequently asked questions
Neighbouring technologies and the services that use them.
Need React engineers who ship against a performance budget?
Tell us the product, the routes that matter and the seniority you need. We will propose a named team or place front-end specialists into yours.