<!-- APIScout AI-readable guide source -->
<!-- Canonical: https://apiscout.dev/guides/complete-api-stack-modern-web-app-2026 -->
<!-- Raw Markdown: https://apiscout.dev/guides/complete-api-stack-modern-web-app-2026/raw.md -->
<!-- Source path: content/guides/complete-api-stack-modern-web-app-2026.mdx -->

---
og_image: "/images/guides/complete-api-stack-modern-web-app-2026.webp"
title: "API Stack for a Modern Web App in 2026"
description: "Every API you need to build a production web app — auth, payments, email, storage, search, analytics, monitoring, and more. The definitive 2026 stack guide."
date: "2026-03-08"
author: "APIScout Team"
tags: ["api-stack", "web-development", "architecture", "best-practices"]
---

# The Complete API Stack for a Modern Web App in 2026

A modern web app touches 10-15 external APIs. Auth, payments, email, storage, search, analytics, monitoring, AI — each is a build-vs-buy decision. Here's the complete API stack with the best provider for each layer, why they win, and what they cost.

## The Full Stack Map

```
┌──────────────────────────────────────────────────┐
│  FRONTEND                                         │
│  Next.js / Remix / SvelteKit / Nuxt              │
├──────────────────────────────────────────────────┤
│                                                    │
│  ┌─ IDENTITY ──────────┐  ┌─ PAYMENTS ──────────┐ │
│  │  Clerk / Auth.js     │  │  Stripe             │ │
│  │  (auth, users, SSO)  │  │  (cards, subs, tax) │ │
│  └─────────────────────┘  └─────────────────────┘ │
│                                                    │
│  ┌─ EMAIL ─────────────┐  ┌─ STORAGE ───────────┐ │
│  │  Resend              │  │  Cloudflare R2      │ │
│  │  (transactional)     │  │  (files, images)    │ │
│  └─────────────────────┘  └─────────────────────┘ │
│                                                    │
│  ┌─ DATABASE ──────────┐  ┌─ SEARCH ────────────┐ │
│  │  Neon / PlanetScale  │  │  Typesense / Algolia│ │
│  │  (Postgres / MySQL)  │  │  (full-text, facets)│ │
│  └─────────────────────┘  └─────────────────────┘ │
│                                                    │
│  ┌─ ANALYTICS ─────────┐  ┌─ MONITORING ────────┐ │
│  │  PostHog             │  │  Sentry / BetterStack│
│  │  (events, flags)     │  │  (errors, logs)     │ │
│  └─────────────────────┘  └─────────────────────┘ │
│                                                    │
│  ┌─ AI ────────────────┐  ┌─ COMMUNICATION ─────┐ │
│  │  Anthropic / OpenAI  │  │  Twilio (SMS)       │ │
│  │  (LLM, embeddings)  │  │  Slack (webhooks)   │ │
│  └─────────────────────┘  └─────────────────────┘ │
│                                                    │
│  ┌─ DEPLOYMENT ────────┐  ┌─ BACKGROUND JOBS ───┐ │
│  │  Vercel / Fly.io     │  │  Inngest / Trigger  │ │
│  │  (hosting, CDN)      │  │  (queues, cron)     │ │
│  └─────────────────────┘  └─────────────────────┘ │
│                                                    │
└──────────────────────────────────────────────────┘
```

## Layer by Layer

### 1. Authentication & Identity

| Provider | Best For | Free Tier | Paid |
|----------|----------|-----------|------|
| **Clerk** | Full-featured, fast setup | 10K MAU | $25/mo (10K+) |
| **Auth.js** | Self-hosted, open source | Free (OSS) | Hosting costs |
| **Supabase Auth** | Already using Supabase | 50K MAU | Included |
| **WorkOS** | Enterprise SSO/SCIM | 1M users | $49/mo |

**Winner: Clerk** for most apps. Drop-in components, webhooks, org management, and it handles the hardest auth edge cases.

```typescript
// 3 lines to protect a route
import { auth } from '@clerk/nextjs/server';

export async function GET() {
  const { userId } = await auth();
  if (!userId) return new Response('Unauthorized', { status: 401 });
  // ... your code
}
```

**When to pick something else:**
- Self-hosted / open source required → Auth.js
- Already on Supabase → Supabase Auth
- Enterprise SSO is primary requirement → WorkOS

### 2. Payments & Billing

| Provider | Best For | Transaction Fee | Monthly Fee |
|----------|----------|----------------|-------------|
| **Stripe** | Everything | 2.9% + $0.30 | None |
| **Lemon Squeezy** | Digital products, MoR | 5% + $0.50 | None |
| **Paddle** | SaaS, MoR | 5% + $0.50 | None |
| **PayPal** | Buyer trust, global | 2.99% + $0.49 | None |

**Winner: Stripe** for everything except when you need a Merchant of Record (MoR) to handle global tax compliance — then Lemon Squeezy or Paddle.

```typescript
// Stripe Checkout — 5 lines to accept payment
const session = await stripe.checkout.sessions.create({
  mode: 'subscription',
  line_items: [{ price: 'price_pro_monthly', quantity: 1 }],
  success_url: `${APP_URL}/success`,
  cancel_url: `${APP_URL}/pricing`,
});
```

**When to pick something else:**
- Don't want to handle taxes/VAT → Lemon Squeezy (Merchant of Record)
- International customers, tax complexity → Paddle
- One-time digital sales → Gumroad or Lemon Squeezy

### 3. Transactional Email

| Provider | Best For | Free Tier | Cost Per Email |
|----------|----------|-----------|---------------|
| **Resend** | Developer experience | 3K/month | $0.001 |
| **SendGrid** | High volume | 100/day | $0.001-0.003 |
| **Postmark** | Deliverability | 100/month | $0.001 |
| **AWS SES** | Cheapest at scale | 62K/month (EC2) | $0.0001 |

**Winner: Resend** for DX — React Email templates, clean API, simple pricing. SendGrid or SES if you're sending millions.

```typescript
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);

await resend.emails.send({
  from: 'App <hello@yourapp.com>',
  to: user.email,
  subject: 'Welcome!',
  react: WelcomeEmail({ name: user.name }),
});
```

### 4. File Storage

| Provider | Best For | Free Tier | Cost |
|----------|----------|-----------|------|
| **Cloudflare R2** | S3-compatible, no egress | 10 GB | $0.015/GB stored |
| **AWS S3** | Enterprise, ecosystem | 5 GB | $0.023/GB + egress |
| **Vercel Blob** | Simple, Vercel-native | 250 MB | $0.023/GB |
| **UploadThing** | File uploads (React) | 2 GB | $10/mo (100 GB) |
| **Supabase Storage** | Already using Supabase | 1 GB | Included |

**Winner: Cloudflare R2** for most apps — S3-compatible API, zero egress fees, generous free tier.

```typescript
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

// R2 uses the S3 SDK
const r2 = new S3Client({
  region: 'auto',
  endpoint: process.env.R2_ENDPOINT,
  credentials: {
    accessKeyId: process.env.R2_ACCESS_KEY!,
    secretAccessKey: process.env.R2_SECRET_KEY!,
  },
});

await r2.send(new PutObjectCommand({
  Bucket: 'my-app',
  Key: `uploads/${userId}/${filename}`,
  Body: fileBuffer,
  ContentType: mimeType,
}));
```

### 5. Database

| Provider | Type | Free Tier | Best For |
|----------|------|-----------|----------|
| **Neon** | Serverless Postgres | 0.5 GB | Serverless apps, branching |
| **Supabase** | Postgres + extras | 500 MB | Full BaaS, real-time |
| **PlanetScale** | Serverless MySQL | 5 GB | MySQL, schema branching |
| **Turso** | Edge SQLite (libSQL) | 9 GB | Edge, embedded, low latency |
| **Upstash** | Serverless Redis | 10K commands/day | Caching, rate limiting |

**Winner: Neon** for Postgres (serverless scaling, branching, generous free tier). Add **Upstash Redis** for caching.

```typescript
// Neon + Drizzle ORM
import { drizzle } from 'drizzle-orm/neon-http';
import { neon } from '@neondatabase/serverless';

const sql = neon(process.env.DATABASE_URL!);
const db = drizzle(sql);

const users = await db.select().from(usersTable).where(eq(usersTable.plan, 'pro'));
```

### 6. Search

| Provider | Best For | Free Tier | Cost |
|----------|----------|-----------|------|
| **Typesense** | Self-hosted or cloud | Free (OSS) | $30/mo cloud |
| **Algolia** | Fastest, richest features | 10K searches/mo | $1/1K searches |
| **Meilisearch** | Self-hosted, simple | Free (OSS) | Cloud pricing |
| **pgvector + Postgres** | Already using Postgres | Free | No extra cost |

**Winner: Typesense** for most apps — open source, typo-tolerant, fast. Algolia if budget isn't a concern and you want the best search UX out of the box.

```typescript
import Typesense from 'typesense';

const client = new Typesense.Client({
  nodes: [{ host: 'search.yourapp.com', port: 443, protocol: 'https' }],
  apiKey: process.env.TYPESENSE_API_KEY!,
});

const results = await client.collections('products').documents().search({
  q: 'wireless headphones',
  query_by: 'name,description',
  filter_by: 'price:<100 && in_stock:true',
  sort_by: 'popularity:desc',
});
```

### 7. Analytics & Feature Flags

| Provider | Best For | Free Tier | Cost |
|----------|----------|-----------|------|
| **PostHog** | All-in-one, open source | 1M events | $0.00031/event |
| **Mixpanel** | Event analytics | 20M events | $28/mo |
| **Plausible** | Privacy-first web analytics | None | $9/mo |
| **LaunchDarkly** | Feature flags (enterprise) | None | $10/seat/mo |

**Winner: PostHog** — analytics, feature flags, session replay, A/B testing, surveys in one tool. Open source. Generous free tier.

```typescript
import { PostHog } from 'posthog-node';

const posthog = new PostHog(process.env.POSTHOG_API_KEY!);

// Track events
posthog.capture({ distinctId: userId, event: 'project_created', properties: { plan: 'pro' } });

// Feature flags
const showNewUI = await posthog.isFeatureEnabled('new-dashboard', userId);
```

### 8. Error Monitoring & Logging

| Provider | Best For | Free Tier | Cost |
|----------|----------|-----------|------|
| **Sentry** | Error tracking | 5K errors/mo | $26/mo |
| **BetterStack** | Logs + uptime | Free | $25/mo |
| **Axiom** | Log aggregation | 500 GB ingest/mo | $25/mo |
| **Datadog** | Enterprise observability | None | $15/host/mo |

**Winner: Sentry** for error tracking (source maps, breadcrumbs, performance). Add **BetterStack** or **Axiom** for log aggregation.

```typescript
import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 0.1,
  environment: process.env.NODE_ENV,
});

// Errors are automatically captured
// Manual capture for business logic errors:
Sentry.captureException(new Error('Payment processing failed'), {
  tags: { userId, plan: 'pro' },
});
```

### 9. AI / LLM

| Provider | Best Model | Strength | Cost (1M tokens) |
|----------|-----------|----------|-------------------|
| **Anthropic** | Claude Sonnet | Coding, safety, analysis | $3 in / $15 out |
| **OpenAI** | GPT-4o | Ecosystem, multimodal | $5 in / $15 out |
| **Google** | Gemini 2.0 Flash | Cheapest good model | $0.10 in / $0.40 out |
| **Groq** | Llama 3.3 70B | Fastest inference | $0.59 in / $0.79 out |

**Winner: Depends on use case.** Claude for coding/analysis, GPT-4o for ecosystem/multimodal, Gemini Flash for cost-sensitive, Groq for speed.

```typescript
import Anthropic from '@anthropic-ai/sdk';

const anthropic = new Anthropic();

const response = await anthropic.messages.create({
  model: 'claude-sonnet-4-20250514',
  max_tokens: 1024,
  messages: [{ role: 'user', content: prompt }],
});
```

### 10. Background Jobs & Cron

| Provider | Best For | Free Tier | Cost |
|----------|----------|-----------|------|
| **Inngest** | Event-driven workflows | 50K runs/mo | $50/mo |
| **Trigger.dev** | Long-running jobs | 50K runs/mo | $25/mo |
| **Upstash QStash** | Serverless message queue | 500 msgs/day | $1/100K msgs |
| **BullMQ** | Self-hosted Redis queues | Free (OSS) | Redis cost |

**Winner: Inngest** for serverless apps — event-driven functions, retries, cron, step functions, all without managing infrastructure.

```typescript
import { inngest } from '@/lib/inngest';

// Define a background job
export const processUpload = inngest.createFunction(
  { id: 'process-upload', retries: 3 },
  { event: 'upload/received' },
  async ({ event, step }) => {
    const file = await step.run('download', () =>
      downloadFile(event.data.fileUrl)
    );

    const processed = await step.run('process', () =>
      processFile(file)
    );

    await step.run('notify', () =>
      sendEmail(event.data.userId, 'Upload processed!')
    );

    return { processed: true };
  }
);
```

### 11. Deployment & Hosting

| Provider | Best For | Free Tier | Cost |
|----------|----------|-----------|------|
| **Vercel** | Next.js, frontend | Hobby free | $20/mo |
| **Fly.io** | Containers, global | Free tier | $2-5/mo per VM |
| **Railway** | Full-stack, databases | 500 hrs/mo | $5/mo |
| **Cloudflare Pages** | Static + Workers | Generous free | $5/mo |

**Winner: Vercel** for Next.js apps. **Fly.io** if you need containers or server-side control.

### 12. Communication

| Channel | Provider | Free Tier | Cost Per Message |
|---------|----------|-----------|-----------------|
| **SMS** | Twilio | $15 trial credit | $0.0079 (US) |
| **Push** | FCM | Free | Free |
| **In-app** | Knock / Novu | Free tier | $0.001-0.01 |
| **Team** | Slack webhooks | Free | Free |

## The Starter Stack (Day 1)

For a new SaaS with $0 budget:

```
Auth:       Clerk (10K MAU free)
Database:   Neon (500 MB free)
Email:      Resend (3K emails/month free)
Analytics:  PostHog (1M events free)
Monitoring: Sentry (5K errors free)
Storage:    Cloudflare R2 (10 GB free)
Hosting:    Vercel (hobby free)
Payments:   Stripe (no monthly fee)
Jobs:       Inngest (50K runs free)

Total: $0/month
```

## The Growth Stack (1K-10K users)

```
Auth:       Clerk              $25/month
Database:   Neon + Upstash     $25 + $10/month
Email:      Resend             $20/month
Analytics:  PostHog            Free-$45/month
Monitoring: Sentry + Axiom     $26 + $0/month
Storage:    Cloudflare R2      ~$5/month
Hosting:    Vercel Pro         $20/month
Search:     Typesense Cloud    $30/month
Payments:   Stripe             ~2.9% per transaction
Jobs:       Inngest            $50/month

Total: ~$210/month + Stripe fees
```

## The Scale Stack (10K-100K users)

```
Auth:       Clerk / WorkOS     $100-500/month
Database:   Neon Scale + Redis $50-200/month
Email:      Resend / SES       $50-200/month
Analytics:  PostHog            $100-500/month
Monitoring: Sentry + Datadog   $100-500/month
Storage:    Cloudflare R2      $20-100/month
Hosting:    Vercel / Fly.io    $100-500/month
Search:     Typesense / Algolia $50-300/month
AI:         Anthropic / OpenAI  Usage-based
Jobs:       Inngest            $150-500/month

Total: $700-3,300/month + usage
```

## Integration Architecture

```typescript
// The service layer that connects everything
class AppServices {
  auth: ClerkClient;
  payments: Stripe;
  email: Resend;
  analytics: PostHog;
  monitoring: Sentry;
  storage: S3Client;
  search: Typesense.Client;
  jobs: Inngest;

  // User signs up → triggers across all services
  async onUserCreated(user: { id: string; email: string; name: string }) {
    // 1. Create Stripe customer
    const customer = await this.payments.customers.create({
      email: user.email,
      name: user.name,
      metadata: { userId: user.id },
    });

    // 2. Store in database
    await db.users.create({
      ...user,
      stripeCustomerId: customer.id,
      plan: 'free',
    });

    // 3. Index for search
    await this.search.collections('users').documents().upsert({
      id: user.id,
      name: user.name,
      email: user.email,
    });

    // 4. Track signup
    this.analytics.capture({
      distinctId: user.id,
      event: 'user_signed_up',
    });

    // 5. Send welcome email
    await this.email.emails.send({
      from: 'App <hello@yourapp.com>',
      to: user.email,
      subject: `Welcome, ${user.name}!`,
      react: WelcomeEmail({ name: user.name }),
    });
  }
}
```

## Decision Framework

When choosing a provider for any layer:

| Factor | Weight | Question |
|--------|--------|----------|
| **DX** | 30% | How fast can I integrate? How good are the docs? |
| **Free Tier** | 20% | Can I start without paying? |
| **Pricing at Scale** | 20% | Does it stay affordable at 10x, 100x growth? |
| **Reliability** | 15% | What's their uptime history? SLA? |
| **Lock-in Risk** | 10% | How hard is it to switch providers later? |
| **Community** | 5% | Is there help available when I'm stuck? |

## Common Mistakes

| Mistake | Impact | Fix |
|---------|--------|-----|
| Over-engineering day 1 | Months wasted before launch | Start with the starter stack, upgrade as you grow |
| Building auth yourself | Security vulnerabilities, weeks of work | Use Clerk or Auth.js |
| No error monitoring | Bugs in production you don't know about | Add Sentry before launch |
| Ignoring API costs | Surprise bills at scale | Model costs at 10x and 100x current usage |
| No abstraction layer | Vendor lock-in, painful migrations | Interface + adapter pattern for critical services |
| Using 20 APIs when 5 work | Integration complexity, more failure points | Consolidate where possible (PostHog replaces 3+ tools) |

One frequently overlooked consideration when finalizing your stack: **vendor concentration risk**. If three of your core services come from a single platform (e.g., Vercel for hosting, AI, and analytics), a pricing change or policy shift affects your entire stack simultaneously. For resilience, distribute critical dependencies across at least two or three vendors. The redundancy rarely costs more in fees, but it preserves negotiating leverage and reduces the blast radius of any single vendor's decisions as your business scales.

---

*Compare every API in this stack on [APIScout](https://apiscout.dev) — auth, payments, email, storage, search, analytics, and more, with pricing calculators and feature-by-feature comparisons.*

*Related: [gRPC-Web vs REST vs Connect-RPC for Frontend 2026](/blog/grpc-web-vs-rest-vs-connect-rpc-frontend-2026), [How AI Is Transforming API Design and Documentation](/blog/ai-transforming-api-design-documentation-2026), [API Breaking Changes Without Breaking Clients](/blog/api-breaking-changes-without-breaking-clients-2026)*
