Web applications where speed is a feature.
Server-rendered, Core-Web-Vitals-budgeted, accessibility-aware web apps — the same discipline we run on our own platforms.
- Architecture & budgets
- Design system & core flows
- Feature build-out
- Launch & RUM
Every route ships with a performance budget.
The web is the surface that reaches everyone: no install, instant updates, one codebase, a link you can put in an email. It is also the surface where quality decays fastest, because every sprint adds a script, a font, a third-party widget and another render-blocking request, and none of them looks expensive on its own. Months later the landing page is slow to become useful on a mid-range phone, the conversion rate has drifted down, and nobody can point to the change that did it. We build web applications that treat performance and accessibility as requirements with budgets — not aspirations that survive until the first deadline.
That means the architecture is decided before the components: which routes render on the server, which data is cached and where, what the page must show before any JavaScript arrives. Server rendering is the default because it is better for the first paint, better for search, and simpler to reason about than a client that has to fetch its own reason for existing. Interactivity is added where the product needs it rather than everywhere by habit, so the heavy code ships to the handful of screens that earn it.
If a change blows the budget, the build fails — before review, not after launch. That is how speed survives the roadmap, and it is why a budget conversation happens once at the start rather than repeatedly as a rescue project.
Four things a web application has to get right.
None of these are finishing touches. Each one is an architectural decision that is cheap at the start and structural later on.
Modern SSR architecture
Next.js and React with server rendering and edge caching — fast first paint, markup search engines can read, and app-grade interactivity where it is warranted. We decide per route: static where the content is shared, server-rendered where it is personal, client-side only where the screen is genuinely an application behind a login. Data access sits on the server, so the browser never becomes a place where credentials or business rules leak.
Core Web Vitals budgets
LCP, CLS and INP budgets set per route and enforced in CI, with a bundle-size ceiling alongside them. A pull request that pushes a route over its budget fails the same way a broken test does, so the trade-off is visible while the author is still in the code. Real-user monitoring keeps the budget honest after launch, because a lab score on a fast laptop is not evidence about your actual audience.
Accessibility as standard
WCAG 2.1 AA as the working bar: semantic markup, keyboard flows, managed focus, sensible contrast and screen-reader passes on the core journeys. Automated checks run in the pipeline to catch the mechanical failures, and a manual pass covers the ones tooling cannot see — a modal that traps focus, a form that announces its error to nobody. It is also the cheapest usability work you will ever fund, and it is increasingly a procurement requirement.
Design systems that scale
Token-driven component libraries so product teams ship consistent interfaces without pixel archaeology. Colour, spacing, type and radius live as tokens with names that mean something, components are documented with their states, and the library is versioned like any other dependency. Our UX / UI practice designs in the same tokens the code consumes, which removes the usual translation losses between a file and a build.
How the work runs, day to day.
A budget is a number the build enforces.
Everyone agrees the site should be fast. Almost nobody writes down how fast, per page, and fails a build when it is not. We set a budget per route in phase one — largest contentful paint, interaction latency, layout shift and a JavaScript ceiling — derived from what the route is for. A marketing landing page and an internal reporting grid do not deserve the same number, and pretending otherwise is how budgets get ignored. Then the pipeline measures every pull request against the budget for the routes it touches, and a regression is a red build with the offending payload named.
- Per-route budgets agreed with you in phase one and recorded in the repository
- CI runs the check on the preview deployment for the routes a change touches
- Real-user monitoring segmented by device and network, so the budget reflects your audience
One set of tokens, every screen.
Interface inconsistency is rarely a taste problem. It is what happens when the same button exists in nine places, each copied from a slightly different original, and nobody knows which one is current. A tokenised design system fixes the cause: values are defined once, components consume them, and a change to a token propagates rather than requiring a hunt. The library ships with documented states — default, hover, focus, disabled, loading, error — because those are the states that get invented ad hoc at the end of a sprint and are the ones that break keyboard and screen-reader use.
- Tokens for colour, spacing, type, radius and motion, shared by design and code
- Components documented with every state, including focus and error
- Versioned and published, so product teams upgrade deliberately rather than by copy-paste
Accessibility checked where it actually fails.
Automated accessibility tools find missing labels and poor contrast, and they find nothing at all about the two failures that matter most: a keyboard user who cannot escape a dialog, and a screen-reader user who is never told the form was rejected. So we run both passes. The pipeline catches the mechanical defects on every pull request, and a person walks the core journeys with a keyboard and a screen reader before launch. The result is written down with what was found and what was fixed, which is also the document your procurement team will ask for.
- Automated checks in CI on every route, blocking merge on new violations
- Manual keyboard and screen-reader passes on the journeys that carry the revenue
- An audit record with findings, fixes and any accepted exceptions, kept in the repository
One application, three sets of expectations.
Pages that load before attention runs out.
Acquisition spend is wasted on a page that is not usable in the first moments. Marketing routes are the fastest thing we build: rendered on the server, cached at the edge, with images sized and fonts loaded so nothing jumps as they arrive. Structured data, canonical hygiene and sitemap generation are part of the definition of done rather than a later ticket.
- Edge-cached server rendering on every acquisition route
- Structured data, canonicals and sitemaps generated from the content model
- A content model your team edits without a deployment
Application screens that stay quick as they grow.
Behind the login the constraint changes: less about first paint, more about interaction latency on data-dense screens. We keep the heavy work on the server, stream results where a table is long, and treat every new dependency as a decision with a cost attached. Feature work happens against the same budgets, so the twentieth screen is not slower than the second by default.
- Server-side data access with typed contracts, so the browser holds no business rules
- Streaming and pagination on data-heavy views instead of one large payload
- Interaction latency measured on mid-range devices, not on the build machine
A pipeline that says no on your behalf.
The pipeline is where quality becomes durable. Every pull request gets a preview URL, type checking, tests, an accessibility scan and a budget check; main deploys to staging automatically; a tagged release goes to production with migrations first and a rehearsed rollback. Infrastructure is code, so the environment can be rebuilt without a person who remembers how — the same standards described on our DevOps & Cloud page.
Budgeted delivery versus the usual arrangement.
Four phases, with the budget set before the build.
Architecture & budgets
Route map, rendering strategy, data flows — and the per-route performance budgets everything is measured against. We decide which routes are static, which are server-rendered per request and which are client applications behind a login, then set the numbers each one has to meet on the devices and networks your audience actually uses. The output is a short architecture note and a budget file in the repository, both of which stay accurate because the pipeline reads them.
Design system & core flows
Tokens, components, and the highest-value user journeys built first, demoed regularly. The component library is built as the first journeys need it rather than as a speculative kit, so every component ships with a real use and documented states. By the end of the phase there is a working path through the product on a live environment, styled in your tokens, that a stakeholder can click through rather than imagine.
Feature build-out
Sprint delivery against the budgeted routes, with accessibility checks in every review and the budget check running on each pull request. Scope decisions are made in the regular demos, and anything that would breach a budget is either optimised or explicitly re-budgeted with you — not absorbed silently. Your engineers review our pull requests from the first sprint if you want them to, which shortens the handover to a formality.
Launch & RUM
Cutover, real-user monitoring, and a tuning window against live traffic. Field data almost always disagrees with the lab in useful ways — a slow third-party script, a font that only hurts on one network, a route nobody predicted would be the most-visited — and the tuning window exists to act on that. You leave it with dashboards segmented by device and network, alert thresholds agreed, and the budgets updated to match reality.
What is on the table at handover.
- A deployed application meeting agreed Core Web Vitals budgets
- Token-driven component library with documentation
- Accessibility audit results and remediation log
- CI/CD with budget enforcement and preview environments
- Real-user monitoring dashboards
- An architecture note covering rendering, caching and data access
- Infrastructure as code
- Runbooks for release, rollback and incident response, rehearsed with your team
When this is the right call.
Choose this when the web is where your customers meet the product and the current experience is losing them: pages that take too long to become useful, a checkout that drops on mobile, an internal application people avoid, or an interface that has drifted into nine versions of the same button. It fits a new build where speed and search visibility are commercial requirements, a rescue where an existing application has become slow and nobody can say why, and a design-system programme where several teams need to ship consistent screens without coordinating by hand. If the first version has not been proven yet, an MVP is the cheaper starting point.
Look elsewhere when the product genuinely belongs on a phone — heavy device integration, offline field use, push as a core mechanic — where mobile development is the honest answer, though a web application often ships alongside it. Look elsewhere when the real constraint is behind the interface: a system of record that cannot answer quickly enough, which makes this an integration or modernisation problem wearing a front-end costume. And be cautious about budgets nobody will own after launch — an unenforced budget decays over time.
Frequently asked questions
What this connects to.
Which page is costing you customers?
Send us the URL and who it is for. An engineer reads it, looks at your field data, and replies in writing with what would actually make it faster.