Custom web development, measured in milliseconds.
A full-stack web development company where performance is a contract, not a promise. Published Core Web Vitals targets, honest stack picks by problem, and code we show you before you sign.
A fintech dashboard, taken apart.
Most web development pages open with "we build websites." Here's the actual architecture we'd propose for a hypothetical 20-person fintech team needing a client dashboard, showing every decision and why. This is how we think. Stack of record: Next.js, React, TypeScript, Vercel, Cloudflare.
Frontend
Next.js 16 · TypeScript
State + data
React Query · Zustand
API
tRPC · Hono on Node
Database
Postgres · Drizzle
Auth + billing
Clerk · Stripe
Infra + deploys
Vercel · GitHub Actions
Observability
Sentry · PostHog · Axiom
Every decision above is defensible. Every one has at least one alternative we rejected for a named reason. That's the conversation you get on day one.
We don't pick a favorite. We pick the right one.
Every framework is good at something and bad at something else. The decision isn't "which is best in 2026" — it's "which is best for your problem." Here's how we call it.
| If your site is… | Our pick |
|---|---|
| Content-heavy blog / editorial | Astro |
| Marketing site + some interactivity | Next.js 16 |
| SaaS product with dashboards | Next.js 16 |
| Form-heavy workflow tool | Remix |
| Shopify storefront (headless) | Hydrogen |
| Small team, fast author velocity | SvelteKit |
| Regulated / government / healthcare | Next.js + AWS |
| Documentation + docs portal | Astro (Starlight) |
| Real-time + collaborative | Next.js + Partykit |
We'll argue against our own pick if your situation warrants it. The call happens on the Discover week, not in the contract.
Core Web Vitals, in writing.
Every engagement ships a Core Web Vitals contract. Three thresholds. One verification method. One penalty clause. No discovery-deck wiggle language.
The largest visible element renders within 2.5 seconds on a throttled Moto G4 over 4G. Verified via PageSpeed Insights field data. Mobile and desktop both.
The slowest interaction responds within 200 milliseconds. This replaced First Input Delay in March 2024. We ship under it at the 75th percentile of real users.
No layout shift above 0.1 in the page's lifetime. Images sized, fonts preloaded, ads and embeds reserve their space. The page doesn't jump under your finger.
Field data, not lab
PSI field data on mobile, 75th percentile, 28-day rolling window. Lab scores are nice; field data is the actual user experience.
Real user monitoring
web-vitals package reports every user's LCP, INP, CLS to our Axiom instance. We see regressions the same day, not the same quarter.
CI gates
Lighthouse CI runs on every PR. A score below threshold blocks the merge. Bundle-size guard does the same.
Not everything should be custom.
Most "custom" web dev is reinventing infrastructure that a hosted product already does better. Before we scope a build, we ask whether a SaaS owns the problem. Sometimes it does.
- ✓The workflow is your product's competitive moat — the thing customers pay you for
- ✓You've tried three SaaS options and each one hits a wall your users complain about
- ✓Data sensitivity or compliance forbids routing through a third party
- ✓Performance requirements (latency, throughput, edge) exceed what any SaaS offers
- ✓Volume makes SaaS per-seat pricing uneconomical at 18+ months
- ϵYou need auth. Buy Clerk or Auth0. We will not build auth.
- ϵYou need CMS. Buy Sanity, Contentful, or Payload. Don't build an admin panel.
- ϵYou need billing. Buy Stripe. Buy Paddle for tax-handled SaaS.
- ϵYou need search. Buy Algolia or Typesense. Don't write regex in production.
- ϵYou need email. Buy Resend or Postmark. Don't configure SMTP servers.
- ϵYou need analytics. Buy PostHog. Don't roll your own event pipeline.
The rule: buy the infrastructure. Build the thing only you can build.
Here's what our code looks like.
A Next.js 16 server component that fetches a user and renders their dashboard with proper error handling, typed from the database all the way to JSX. No frameworks-within-frameworks, no state machines for a loading spinner.
import { auth } from '@/lib/auth';
import { db } from '@/lib/db';
import { notFound } from 'next/navigation';
import { DashboardView } from './_components/dashboard-view';
export default async function DashboardPage() {
// Runs on the server. Never ships to the client.
const session = await auth();
if (!session) return notFound();
const user = await db.query.users.findFirst({
where: (u, { eq }) => eq(u.id, session.userId),
with: { accounts: true },
});
if (!user) return notFound();
return <DashboardView user={user} />;
}
17 lines. Authenticated. Type-safe database query via Drizzle. Graceful not-found. Zero client JavaScript for the data fetch. Zero loading spinner because Server Components don't need one. This is the baseline — not a highlight reel.
Five anti-patterns we refuse.
These show up in briefs from smart teams regularly. We'll push back on all of them — not because they're always wrong, but because they're almost always wrong for the team asking.
-
1.
Micro-frontends on a single product.
You have 20 engineers and one product. Module Federation adds weeks of infrastructure for a decoupling benefit you won't feel until you hit 200. Build a monorepo with clean module boundaries; we'll tell you when micro-frontends start paying.
-
2.
GraphQL when REST or tRPC would do.
GraphQL pays for itself when the client and server teams are separate and data needs differ wildly across consumers. If it's one frontend hitting one backend, tRPC ships end-to-end types with a tenth of the ceremony. We'll stand up GraphQL if it's genuinely warranted; we'll tell you when it's not.
-
3.
Custom CMS for a 20-page marketing site.
Sanity, Contentful, and Payload solve the problem in a week. A custom admin panel solves the same problem in three months and then requires ongoing engineering to keep alive. If your content team is two people, buy the CMS.
-
4.
NoSQL without a reason.
MongoDB is not a default. Postgres handles 99% of web-app workloads, gives you SQL, transactions, real joins, row-level security, and a hiring pool twenty times deeper. Pick NoSQL when the access pattern genuinely demands it — rarely.
-
5.
Redux in 2026.
React Query handles server state. Zustand handles the tiny slice of client state you actually have. Redux was a reasonable answer in 2017 to problems the ecosystem has since solved better. If we inherit a codebase with Redux, we don't rip it out — but we don't add to it either.
Four shapes of engagement.
Performance rescue
2-week Core Web Vitals remediation. Audit, bundle tuning, image pipeline, server optimization, rendering strategy review. Fixed fee.
Single-page build
Conversion-focused landing or single-page. Next.js or Astro, TypeScript, analytics, full CWV contract. 2–4 weeks.
Marketing or product site
5–15 pages. Headless CMS, design system wiring, i18n, schema, editorial workflows. 6–8 weeks.
Custom web app
Auth, dashboards, workflows, integrations, real-time, billing. Next.js + Node or full-stack TypeScript. 10–20 weeks.
Prices valid through 2026-Q3. Scope changes get priced before they happen, not after.
Six answers.
What does a web development company actually do?
A custom web development company engineers sites and web applications end-to-end: architecture, backend APIs, database schema, frontend framework, rendering, auth, integrations, CI/CD, deployment, and post-launch optimization. At Digital Heroes, every engagement commits to a Core Web Vitals contract (LCP < 2.5s, INP < 200ms, CLS < 0.1) before the first invoice. Miss the target, the launch sprint is refunded.
How much does custom web development cost?
Landing or single-page: $6,500–$18,000. Marketing or product sites (5–15 pages + CMS): $22,000–$65,000. Custom web applications (auth, dashboards, real-time, billing): $55,000–$250,000. Performance rescue: $8,000. Ranges are published; scope moves price, discovery doesn't.
Which web framework should I use in 2026?
Follow the problem, not a favorite. Next.js 16 for content-plus-app sites. Astro for content-heavy where JS should be zero. Remix for form-heavy data-forward apps. SvelteKit for small teams valuing ergonomics. See the decision matrix in § 02 above.
Do you publish Core Web Vitals targets?
Yes, and contractual. LCP < 2.5s, INP < 200ms, CLS < 0.1, verified on throttled Moto G4 via PageSpeed Insights field data. If the launch build misses any of the three, the launch sprint is refunded at the client's option.
Can you rebuild our existing site?
Yes. Rebuild starts with a technical audit (dependencies, rendering strategy, bundle size, queries, CMS friction, CI/CD maturity). We publish the audit before we touch code. Rebuilds typically run 6–12 weeks with preserved URLs, 301 redirects, and Search Console address change. Rankings are almost always preserved.
Will you work with our existing engineering team?
Yes. Three shapes: white-label (we ship, your team brands), embedded (our engineers in your sprints, 3-month minimum), handoff (we build, you maintain). Code quality and documentation are the same across all three — we assume your team will read every line.
Start with a metric.
Tell us the number that's broken — conversion, TTFB, bounce rate, user-reported latency. We'll come back with an architecture, a stack, a performance contract, and a price. Within 24 hours. No discovery calls.