Skip to content

Tech Stack Standards

All client sites use Astro 5/6 (not Next.js — that is for internal Boxi products only). Deployed on Vercel by default or Cloudflare Pages when required.

LayerVercel (default)Cloudflare (when needed)
FrameworkAstro 5/6, output: hybridAstro 5/6, output: hybrid
Adapter@astrojs/vercel/serverless@astrojs/cloudflare
DatabaseNeon (Postgres, Drizzle ORM)Cloudflare D1 (SQLite, Drizzle)
CacheUpstash RedisCloudflare KV
StorageVercel BlobCloudflare R2 (no egress fees)
AnalyticsPostHogPostHog
Email / FormsResendResend
CRM syncBoxi App webhookBoxi App webhook
Blog (agency writes)Astro Content CollectionsAstro Content Collections
Blog (client edits)Keystatic → CloudCannon → SanityKeystatic → CloudCannon → Sanity
Package managerbunbun
SecretsDoppler (per-client project)Doppler (per-client project)

Use Cloudflare only when: zero egress fees on storage are required (R2), site needs Workers/Durable Objects, or very high traffic at minimal cost.

Community consensus in 2026 is unambiguous: Astro for content/marketing sites, Next.js for apps.

  • 100/100 Lighthouse out of the box (static-first, zero client JS on marketing pages)
  • Free hosting on Vercel hobby or Cloudflare Pages
  • Agencies actively migrating 40+ WordPress/Webflow sites to Astro + Cloudflare at $0 hosting cost
  • Next.js is over-engineered for blogs and landing pages

All Boxi client sites use output: 'hybrid':

  • Pages are static by default (best performance, cacheable)
  • /api/contact is always server-rendered (required for contact form)
  • Keystatic requires hybrid mode for its admin routes

output: 'static' cannot be used — it does not support API routes.

Terminal window
# Always required
RESEND_API_KEY=
RESEND_FROM_EMAIL= # noreply@clientdomain.com
CLIENT_NOTIFY_EMAIL= # owner@clientbusiness.com
# Full-service clients only (Boxi CRM sync)
BOXI_APP_URL=https://app.boximarketing.com
BOXI_WEBHOOK_SECRET= # openssl rand -hex 32
BOXI_CLIENT_ID= # From Boxi App → Client profile