All services
Pillar 12 · Web

React Development Services

What you get

Capabilities included in every engagement.

  • Next.js 15 App Router
  • React 19 with Server Components
  • Server Actions
  • TanStack Query
  • Zustand (client state when needed)
  • Tailwind CSS + design tokens
  • shadcn/ui on Radix primitives
  • React Hook Form + Zod
  • Playwright + Vitest
  • Sentry with session replay
The stack we default to

What we use. Why we pick it.

We useWhy we pick it
Next.js App RouterServer components by default, client islands where they are needed. Streaming, Suspense, route groups, Server Actions out of the box.
React Server ComponentsData fetching on the server, zero client bundle for read-only UI. The loading-spinner-for-a-list problem stops existing.
Server ActionsForm submissions and mutations without a hand-rolled API route. Validate with Zod, mutate, revalidate, done.
TanStack QueryClient cache, mutations, optimistic updates, refetch-on-focus. The right abstraction for anything that stays on the client.
Zustand (not Redux)Cross-page client state without Redux ceremony. Redux only on projects that already use it.
Tailwind + shadcn/uiRadix primitives are ARIA-correct. shadcn gives you the styled wrapper that lives in your repo, not a node_module you cannot change.
React Hook Form + ZodForms validated by the same Zod schemas the API uses. Submit a form and every field's type matches the server. One schema, two sides.
Sentry with session replayEvery error has a user session replay attached. Repro beats guessing every time.
Playwright + VitestUnit tests for business logic. Playwright covering critical user flows against a preview URL on every PR. Visual regression where it earns its keep.
Reference architecture

How it fits together.

Next.js App Router renders on the edge, TanStack Query caches in the browser, your API stays typed and predictable.

Client Browser React Server Components TanStack cache Edge Next.js App Router Vercel / Netlify · streaming Components Tailwind · shadcn/ui Radix a11y primitives Service FastAPI / Node API Typed JSON Edge functions · webhooks HTML hydrate fetch mutate

What a React build actually ships with in 2026

Most React agencies still ship create-react-app-style single-page apps with client-side routing, a spinner on every navigation, and a JavaScript bundle crossing 500KB gzipped. That is not what React looks like in 2026.

A real React build today is Next.js with the App Router, Server Components where data lives on the server, client components where interaction lives on the client, streaming for anything over 100ms, and a design system living in the repo - not in a node_module you cannot touch.

When React (not Astro, Svelte, or plain HTML) is the right call

  • Interactive dashboards with complex client state, filters, and real-time updates.
  • Auth-gated products with role-based access and user-specific views.
  • Shared component libraries across a web app and a React Native mobile app.
  • Admin panels where the UI is genuinely an application, not a page.
  • Forms with complex validation and cross-field rules (insurance, fintech, healthcare).

When it is not

  • Marketing and content sites - Astro or plain HTML + CSS wins on performance and is cheaper to maintain.
  • Apps that are 95% static - no server state, no user interaction - Astro again.
  • Tiny interactive widgets embedded in someone else’s page - plain JS or Preact.

Server Components in practice

The rule we use per component:

  • Reads data from the database or an API? Server component.
  • Holds user state or listens to the browser (inputs, scrolls, effects)? Client component.
  • Renders once, then the user interacts? Server shell + client island.
  • Needs a third-party library that touches window? Client component, isolated.

Bundle size drops 30 to 60% on most dashboards we touch when the split is clean. LCP improves by more than the numbers suggest, because the browser has less JS to parse before paint.

Our React capabilities

  • Next.js 15 App Router with Server Components and Server Actions.
  • TanStack Query for client-side server state with caching, retries, and optimistic updates.
  • Zustand for cross-page client state. Redux only on projects that already use it.
  • React Hook Form + Zod for forms shared between client and server schemas.
  • shadcn/ui on Radix for ARIA-correct components that live in your repo.
  • Tailwind with design tokens in CSS variables. Light/dark from the same tokens.
  • Sentry with session replay. Every error repros in minutes, not hours.
  • Playwright covering critical flows against preview URLs. CI blocks merges on regressions.
  • Storybook when a component library needs to be reviewed across teams.

Case studies

  • Cross-border mobile top-up - reseller dashboard in React - React web reseller dashboard sharing form logic, auth, and component patterns with the React Native consumer app. One FastAPI backend, two surfaces. Multi-gateway payments (Stripe, PayPal) and a webhook-driven ledger under the hood.
  • Live auction bidding - operator console in React - React web operator console for user verification, vendor and vehicle onboarding, auction scheduling, and live event monitoring. Same FastAPI + WebSocket backend as the React Native buyer app. Server-authoritative timer; admin can schedule and close auctions without deploying code.

How we work on a React engagement

Week 1 - architecture. Routes, data boundaries, server-vs-client component split, auth strategy, deploy target. Written down, reviewed, signed off before any TSX.

Weeks 2 to 3 - the spine. Shell layout, auth, first real data fetch, design token system in place. Deployed to a preview environment by Friday of week 2.

Weeks 4 to 10 - features, one per week. Demoed on real network conditions, not localhost. Lighthouse runs on every PR. Regressions block merge.

Weeks 11 to 12 - polish, accessibility, launch. WCAG 2.2 AA keyboard pass, screen-reader pass, analytics, error boundaries, CWV dashboards.

TanStack Query, React Hook Form, Zod - the client-side stack we trust

  • TanStack Query for anything fetched client-side that lives longer than a render. Caching, retries, refetch-on-focus, optimistic updates - configured once, used everywhere.
  • React Hook Form + Zod for forms. The Zod schema validates the form AND the server input. Client-server drift on forms is a whole class of bugs that disappears.
  • Zustand for cross-page client state when needed.

Design tokens, not Figma-to-code plugins

Every component hits CSS variables. Light and dark mode from the same tokens. When the designer changes brand colour, one variable moves and the whole app follows. No theme-provider spaghetti.

shadcn/ui gives us Radix-correct primitives wrapped in Tailwind, living in our repo. We change the styles without fighting a library.

Deploys and CI - boring by design

  • GitHub Actions: type-check, unit tests, Playwright against a preview URL on every PR.
  • Preview deploys per branch. Product reviews happen on real URLs, not localhost screenshots.
  • Production behind a protected branch. Rollback is one click.
  • Sentry wired from day one. Every error has a user session replay attached.

What we will not do

  • CSS-in-JS with a runtime on new builds. Performance tax for ergonomics that Tailwind + CSS variables already give you.
  • GraphQL where REST + OpenAPI does the job. We default to typed REST. GraphQL only when there is a concrete reason (federation, client-specified shapes).
  • Redux when Zustand or TanStack Query covers it. Less ceremony, same outcome.
  • Opinionated without switching. The point is not the stack. The point is the app shipping on time with the bugs caught.

Why teams pick our React delivery

We use Server Components where they earn their place. A static product page loads faster with RSC. A rich form-heavy editor does not. The split is per component, written down in the architecture doc, not decided by feeling on a Tuesday.

Types carry from backend to frontend: OpenAPI from FastAPI, Zod schemas shared between client forms and server validators, TypeScript strict throughout. Design tokens in CSS variables, Radix + axe-core for accessibility, senior engineers on the product, full IP transfer at launch. The point is not the stack. The point is the app shipping on time with the bugs caught.

FAQ

Questions people ask before we start.

Next's App Router is the most honest implementation of Server Components today. Remix is great for form-heavy apps - we use it when Next's overhead is not justified. Astro for marketing and content. Plain React + Vite for app-shells that do not need server rendering. We pick, not default.

Yes, for the workloads they suit: read-heavy pages, data-rich dashboards, admin panels. They are not a silver bullet - some apps are mostly client-side, and then RSC buys you little. We scope this per page, not per project.

Middleware for session validation. Clerk, NextAuth, Auth0, or Firebase Auth for the identity layer depending on the product. Zod for the session schema. Role-based access enforced at the server-component boundary, not in client JS.

Tailwind with a design token layer in CSS variables. Light and dark themes from the same tokens. We avoid CSS-in-JS runtimes on new builds - they cost performance for ergonomics we do not need.

Yes. Every build ships with a Lighthouse 95+ target on mobile, structured data (JSON-LD), a working sitemap, and canonical tags. CWV metrics tracked from day one.

Radix primitives underneath shadcn handle ARIA correctly. We keyboard-test every flow before ship. axe-core runs on every PR.

Yes. GitHub Actions for tests and type-check on every PR. Preview deploys per branch via Vercel or equivalent. Production behind a protected branch. Rollback is one click.

Default to Server Components. Reach for client components when the component needs browser state (inputs, scroll, effects), a third-party library that touches window, or interactivity. Split client bundles by route group or lazy import when the interactive payload crosses 100KB gzipped.

Start a react development services engagement

Tell us what you’re building.

Name the app, the users, and the deadline. We scope a discovery sprint ending with a written architecture, data boundaries, and a scoped proposal for the build. NDA signed on request. Response within 1 business day.

The team on the call

Named engineers, not a pool.

You speak to the person who’ll review the architecture. No account-manager layer. No offshore switcheroo.

Founder & Lead Engineer

Sameer Donga

Shipping Flutter, FastAPI, and AI systems since 2019. Reviews the architecture on every engagement.