Home/Services/Web Application Development
Service · Build software

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.

Web Application DevelopmentWhat we do
01Modern SSR architecture
02Core Web Vitals budgets
03Accessibility as standard
04Design systems that scale
How it runs
  1. Architecture & budgets
  2. Design system & core flows
  3. Feature build-out
  4. Launch & RUM
Why it exists

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.

Capabilities

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.

01

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.

02

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.

03

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.

04

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.

In practice

How the work runs, day to day.

01

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
02

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
03

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
By seat

One application, three sets of expectations.

Marketing

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
Product

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
Platform

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.

  • Preview environment per pull request, with the budget report attached
  • Infrastructure as code on Vercel or AWS, rebuildable from the repository
  • Error tracking and real-user monitoring wired before launch, with alert routes agreed
Comparison

Budgeted delivery versus the usual arrangement.

Performance
Regressions
Accessibility
Interface consistency
Rendering strategy
Monitoring
Environments
Handover
01Typical build
PerformanceMeasured after launch
RegressionsFound in a quarterly audit
AccessibilityA remediation project later
Interface consistencyComponents copied between screens
Rendering strategyOne approach for every page
MonitoringUptime only
EnvironmentsStaging, if there is time
HandoverA walkthrough meeting
02Odeontech web application
PerformanceBudgeted per route, enforced in CI
RegressionsFail the pull request that caused them
AccessibilityAutomated in CI plus a manual pass pre-launch
Interface consistencyTokens and a versioned library
Rendering strategyChosen per route, written down
MonitoringReal-user vitals segmented by device and network
EnvironmentsPreview per pull request, as code
HandoverRunbooks, architecture notes and your repositories
How it runs

Four phases, with the budget set before the build.

01

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.

02

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.

03

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.

04

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 you get

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
Usually runs with
TypeScriptNext.jsReactNode.jsPostgreSQLRedisVercelAWSPlaywrightSentry
Fit

When this is the right call.

Right fit

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

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.

FAQ

Frequently asked questions

Happily — we implement your design system, or build one with you, or work directly from your designers’ files while they keep owning the visual direction. Either way it ends up tokenised and documented, with the same token names on both sides so a change in design is a change in code rather than a translation exercise. Where you have no design capacity, our UX / UI team covers it.
Server-rendered by default — better vitals, better search visibility, and a simpler mental model because the page arrives complete instead of assembling itself. Pure client-side rendering is reserved for screens that genuinely live behind a login and behave like applications: an editor, a canvas, a live dashboard. We decide it per route in phase one and record the reasoning, so the decision can be revisited on evidence rather than preference.
Yes — performance rescue is a common engagement. We start with field data rather than a lab score, find where users actually wait, and fix the largest offenders first: render-blocking scripts, unsized images, oversized JavaScript bundles, third-party tags nobody remembers adding. Then we wire budgets into your CI so it stays fixed, because a one-off optimisation without enforcement is undone by the next round of feature work.
Server rendering, structured data, canonical hygiene and sitemap generation are part of the definition of done — not an add-on. Content is delivered in the markup rather than assembled after load, metadata comes from the content model so it cannot drift, and redirects are handled at the edge during a migration so link equity survives. We do not do keyword strategy; we make sure the technical foundation does not undermine whoever does.
Evergreen browsers by default, plus any specific matrix your audience needs — agreed in phase 01 from your analytics rather than from a generic list, and tested in CI with Playwright as part of our QA & Testing practice. If a meaningful share of your traffic is on older devices or constrained networks, that changes the budgets and sometimes the architecture, which is exactly why the question belongs at the start.
Because they are enforced by your pipeline, not by our memory. The budget file lives in your repository, the check runs on every pull request, and a breach fails the build with the specific route and payload named. Your team can change a budget deliberately — that is a normal decision with a visible commit — but nobody can drift past one by accident, which is the failure mode that turns fast applications into slow ones.

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.

✓ No pitch deck✓ Reply from an AI-native engineer✓ Written follow-up