Skip to main content

The Complete API Stack for a Modern Web App in 2026

·APIScout Team
api stackweb developmentarchitecturebest 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

ProviderBest ForFree TierPaid
ClerkFull-featured, fast setup10K MAU$25/mo (10K+)
Auth.jsSelf-hosted, open sourceFree (OSS)Hosting costs
Supabase AuthAlready using Supabase50K MAUIncluded
WorkOSEnterprise SSO/SCIM1M users$49/mo

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

// 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

ProviderBest ForTransaction FeeMonthly Fee
StripeEverything2.9% + $0.30None
Lemon SqueezyDigital products, MoR5% + $0.50None
PaddleSaaS, MoR5% + $0.50None
PayPalBuyer trust, global2.99% + $0.49None

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

// 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

ProviderBest ForFree TierCost Per Email
ResendDeveloper experience3K/month$0.001
SendGridHigh volume100/day$0.001-0.003
PostmarkDeliverability100/month$0.001
AWS SESCheapest at scale62K/month (EC2)$0.0001

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

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

ProviderBest ForFree TierCost
Cloudflare R2S3-compatible, no egress10 GB$0.015/GB stored
AWS S3Enterprise, ecosystem5 GB$0.023/GB + egress
Vercel BlobSimple, Vercel-native250 MB$0.023/GB
UploadThingFile uploads (React)2 GB$10/mo (100 GB)
Supabase StorageAlready using Supabase1 GBIncluded

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

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

ProviderTypeFree TierBest For
NeonServerless Postgres0.5 GBServerless apps, branching
SupabasePostgres + extras500 MBFull BaaS, real-time
PlanetScaleServerless MySQL5 GBMySQL, schema branching
TursoEdge SQLite (libSQL)9 GBEdge, embedded, low latency
UpstashServerless Redis10K commands/dayCaching, rate limiting

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

// 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'));
ProviderBest ForFree TierCost
TypesenseSelf-hosted or cloudFree (OSS)$30/mo cloud
AlgoliaFastest, richest features10K searches/mo$1/1K searches
MeilisearchSelf-hosted, simpleFree (OSS)Cloud pricing
pgvector + PostgresAlready using PostgresFreeNo 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.

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

ProviderBest ForFree TierCost
PostHogAll-in-one, open source1M events$0.00031/event
MixpanelEvent analytics20M events$28/mo
PlausiblePrivacy-first web analyticsNone$9/mo
LaunchDarklyFeature 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.

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

ProviderBest ForFree TierCost
SentryError tracking5K errors/mo$26/mo
BetterStackLogs + uptimeFree$25/mo
AxiomLog aggregation500 GB ingest/mo$25/mo
DatadogEnterprise observabilityNone$15/host/mo

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

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

ProviderBest ModelStrengthCost (1M tokens)
AnthropicClaude SonnetCoding, safety, analysis$3 in / $15 out
OpenAIGPT-4oEcosystem, multimodal$5 in / $15 out
GoogleGemini 2.0 FlashCheapest good model$0.10 in / $0.40 out
GroqLlama 3.3 70BFastest 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.

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

ProviderBest ForFree TierCost
InngestEvent-driven workflows50K runs/mo$50/mo
Trigger.devLong-running jobs50K runs/mo$25/mo
Upstash QStashServerless message queue500 msgs/day$1/100K msgs
BullMQSelf-hosted Redis queuesFree (OSS)Redis cost

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

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

ProviderBest ForFree TierCost
VercelNext.js, frontendHobby free$20/mo
Fly.ioContainers, globalFree tier$2-5/mo per VM
RailwayFull-stack, databases500 hrs/mo$5/mo
Cloudflare PagesStatic + WorkersGenerous free$5/mo

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

12. Communication

ChannelProviderFree TierCost Per Message
SMSTwilio$15 trial credit$0.0079 (US)
PushFCMFreeFree
In-appKnock / NovuFree tier$0.001-0.01
TeamSlack webhooksFreeFree

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

// 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:

FactorWeightQuestion
DX30%How fast can I integrate? How good are the docs?
Free Tier20%Can I start without paying?
Pricing at Scale20%Does it stay affordable at 10x, 100x growth?
Reliability15%What's their uptime history? SLA?
Lock-in Risk10%How hard is it to switch providers later?
Community5%Is there help available when I'm stuck?

Common Mistakes

MistakeImpactFix
Over-engineering day 1Months wasted before launchStart with the starter stack, upgrade as you grow
Building auth yourselfSecurity vulnerabilities, weeks of workUse Clerk or Auth.js
No error monitoringBugs in production you don't know aboutAdd Sentry before launch
Ignoring API costsSurprise bills at scaleModel costs at 10x and 100x current usage
No abstraction layerVendor lock-in, painful migrationsInterface + adapter pattern for critical services
Using 20 APIs when 5 workIntegration complexity, more failure pointsConsolidate where possible (PostHog replaces 3+ tools)

Compare every API in this stack on APIScout — auth, payments, email, storage, search, analytics, and more, with pricing calculators and feature-by-feature comparisons.

Comments