The Adapter Detection DisasterSpend 3 hours wondering why your perfectly configured Vercel deployment keeps failing with "Could not detect a supported production environment" even though you've followed every [tutorial](https://vercel.com/docs/frameworks/sveltekit).
The adapter-auto magic that's supposed to "just work" is actually a fucking disaster waiting to happen.### Why Adapter-Auto Is a Production LiabilityHere's what actually happens when adapter-auto tries to be smart:
- Environment Detection Fails: Vercel sets `VERCEL=true` but adapter-auto sometimes can't read it during build
- Build Context Confusion: CI environments don't always match what adapter-auto expects
- Silent Fallbacks:
Adapter-auto fails silently and defaults to static mode, breaking your SSR### The Race Condition Nobody Talks AboutYour deployment succeeds locally because your machine has different timing than CI servers. GitHub issue #2956 documents cases where adapter-auto works on developer machines but consistently fails in production builds.
The problem: adapter-auto checks for platform environment variables during the Vite build phase, but some deployment platforms set these variables later in the deployment process.### Environment Variable Hell That Breaks EverythingSvelteKit's environment variable system is designed to be secure, but it fucks you when deploying:#### The $env/static/private
Import ErrorERROR: 'MONGO_KEY' is not exported by $env/static/private, imported by src/hooks.server.js
This happens because:
- Your local `.env` file has
MONGO_KEY=your_key
- Production environment doesn't have this variable set
- SvelteKit's build process validates all imports at build time
- Build fails even though the variable exists in your deployment platform#### The PUBLIC_ Prefix Confusion
javascript// This works locally but fails in productionimport { SUPABASE_URL } from '$env/static/private';// This is required for client-side accessimport { PUBLIC_SUPABASE_URL } from '$env/static/public';
The gotcha: CLIENT-SIDE components can only access PUBLIC_ variables, but this isn't enforced during development.
Your app works perfectly locally, then throws undefined errors in production when client components try to access private variables.### Build Success, Runtime Failure PatternYour deployment shows "Build successful" but users get blank pages or 500 errors. This happens because:
- Static Analysis Passes: TypeScript and build tools validate your code
- Runtime Context Different:
Production environment has different module resolution3. Client/Server Mismatch: SSR renders with server variables, client hydrates without themReal example from production:javascript// src/routes/+layout.server.jsimport { PRIVATE_API_KEY } from '$env/static/private';export async function load() { // This runs on server, works fine const data = await fetch(API_URL, { headers: { 'Authorization': `Bearer ${PRIVATE_API_KEY}` } }); return { data: await data.json() };}``````svelte<!-- src/routes/+layout.svelte --><script> import { PRIVATE_API_KEY } from '$env/static/private'; // This runs on client after hydration // PRIVATE_API_KEY is undefined in browser // But dev mode doesn't catch this console.log(PRIVATE_API_KEY); // undefined in production</script>
Build succeeds because the import exists.
Runtime fails because private variables aren't available in the browser.### The Docker Deployment NightmareYour Dockerfile builds fine locally but fails in production with cryptic Node.js errors. Common issues:```dockerfileFROM node:18-alpineCOPY . .
RUN npm ci --production```This fails because:
npm ci --production
skips devDependencies- SvelteKit needs build dependencies to generate the production bundle
- Alpine Linux has different library compatibilityFixed version:```dockerfileFROM node:18-alpineCOPY package*.json ./RUN npm ciCOPY . .
RUN npm run buildRUN npm ci --production### Platform-Specific Gotchas That Kill Deployments#### Vercel Edge Runtime LimitationsYour app uses Node.js APIs that don't exist in Edge Runtime:
javascriptimport fs from 'fs'; // Breaks in Edge Runtimeimport path from 'path'; // Also breaks// This works locally but fails on Vercel Edgeexport async function load() { const config = fs.read
FileSync(path.join(process.cwd(), 'config.json')); return { config:
JSON.parse(config) };}```#### Netlify Function Timeout Issues
Your server load functions work fine locally but timeout on Netlify after 10 seconds. Netlify Functions have strict timeout limits that development doesn't enforce.#### CloudFlare Workers Module ResolutionCloudFlare Workers can't resolve certain Node.js modules, but this only shows up at runtime:```Error:
Could not resolve "../output/server/index.js" from ".svelte-kit/cloudflare/_worker.js"### Memory Leaks in Production Load FunctionsYour server functions gradually consume more memory until the container restarts. This happens because:
javascript// Memory leak patternconst cache = new Map();export async function load({ params }) { // Cache never gets cleared cache.set(params.id, expensiveOperation()); return { data: cache.get(params.id) };}```Development server restarts frequently, hiding this issue. Production servers run for days, accumulating memory until they crash.The fix isn't just clearing the cache
- it's understanding that server load functions run in persistent processes, not per-request environments like traditional serverless functions.