Skip to content

${redev}

Published 12/5/2025 · 5 min read

Tags: svelte , sveltekit , deployment

Lesson 19: Deployment

Your app is ready. Time to ship it. SvelteKit uses adapters to deploy to different platforms — from serverless to Node.js to static hosting.

How Adapters Work

SvelteKit builds your app, then an adapter transforms it for a specific platform:

// svelte.config.js
import adapter from "@sveltejs/adapter-vercel";

export default {
  kit: {
    adapter: adapter(),
  },
};

The adapter handles platform-specific details like serverless functions, edge functions, and static file serving.

Auto Adapter

The default adapter tries to detect your platform:

import adapter from "@sveltejs/adapter-auto";

export default {
  kit: {
    adapter: adapter(),
  },
};

It works with Vercel, Netlify, Cloudflare Pages, and Azure Static Web Apps automatically. Great for getting started.

Vercel

npm i -D @sveltejs/adapter-vercel
// svelte.config.js
import adapter from "@sveltejs/adapter-vercel";

export default {
  kit: {
    adapter: adapter({
      // Optional: specify runtime
      runtime: "nodejs20.x",

      // Optional: edge functions
      // runtime: 'edge'
    }),
  },
};

Deploy:

# Install Vercel CLI
npm i -g vercel

# Deploy
vercel

Or connect your GitHub repo for automatic deployments.

Netlify

npm i -D @sveltejs/adapter-netlify
import adapter from "@sveltejs/adapter-netlify";

export default {
  kit: {
    adapter: adapter({
      // Use edge functions
      edge: false,

      // Split into multiple functions
      split: false,
    }),
  },
};

Add netlify.toml:

[build]
  command = "npm run build"
  publish = "build"

Cloudflare Pages

npm i -D @sveltejs/adapter-cloudflare
import adapter from "@sveltejs/adapter-cloudflare";

export default {
  kit: {
    adapter: adapter(),
  },
};

Cloudflare Workers run at the edge, giving excellent performance globally.

Node.js Server

For traditional hosting (VPS, Docker):

npm i -D @sveltejs/adapter-node
import adapter from "@sveltejs/adapter-node";

export default {
  kit: {
    adapter: adapter({
      out: "build",
      precompress: true,
    }),
  },
};

Build and run:

npm run build
node build

Or with PM2:

pm2 start build/index.js --name my-app

Static Site Generation

For fully static sites (no server):

npm i -D @sveltejs/adapter-static
import adapter from "@sveltejs/adapter-static";

export default {
  kit: {
    adapter: adapter({
      pages: "build",
      assets: "build",
      fallback: "404.html",
      precompress: false,
    }),
  },
};

Add prerender option to your root layout:

// src/routes/+layout.js
export const prerender = true;

This renders all pages at build time. Perfect for blogs, documentation, and marketing sites.

Environment Variables

SvelteKit has strict rules about environment variables for security.

Public variables (exposed to browser):

# .env
PUBLIC_API_URL=https://api.example.com
PUBLIC_SITE_NAME=My App
// In any file
import { PUBLIC_API_URL } from "$env/static/public";

Private variables (server only):

# .env
DATABASE_URL=postgres://...
API_SECRET=super-secret
// Only in +page.server.js, +server.js, hooks.server.js
import { DATABASE_URL, API_SECRET } from "$env/static/private";

Dynamic environment variables:

import { env } from "$env/dynamic/private";
import { env as publicEnv } from "$env/dynamic/public";

// Access at runtime
const dbUrl = env.DATABASE_URL;
const apiUrl = publicEnv.PUBLIC_API_URL;

Use $env/static/* when possible — it enables dead code elimination.

Production Checklist

Before deploying:

1. Set page options:

// src/routes/+layout.js
export const prerender = false; // or true for static
export const ssr = true; // server-side rendering
export const csr = true; // client-side rendering

2. Add error tracking:

// src/hooks.server.js
import * as Sentry from "@sentry/sveltekit";

Sentry.init({
  dsn: "your-sentry-dsn",
  tracesSampleRate: 1.0,
});

export const handleError = Sentry.handleErrorWithSentry();

3. Configure caching:

// src/routes/api/data/+server.js
export function GET() {
  return json(data, {
    headers: {
      "cache-control": "public, max-age=60",
    },
  });
}

4. Set up redirects:

// src/hooks.server.js
export function handle({ event, resolve }) {
  // Redirect old URLs
  if (event.url.pathname === "/old-page") {
    return new Response(null, {
      status: 301,
      headers: { location: "/new-page" },
    });
  }

  return resolve(event);
}

5. Add security headers:

// src/hooks.server.js
export async function handle({ event, resolve }) {
  const response = await resolve(event);

  response.headers.set("X-Frame-Options", "DENY");
  response.headers.set("X-Content-Type-Options", "nosniff");
  response.headers.set("Referrer-Policy", "strict-origin-when-cross-origin");

  return response;
}

Docker Deployment

# Dockerfile
FROM node:20-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine

WORKDIR /app
COPY --from=builder /app/build ./build
COPY --from=builder /app/package*.json ./
RUN npm ci --production

ENV PORT=3000
EXPOSE 3000

CMD ["node", "build"]
# docker-compose.yml
version: "3"
services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://...

Preview Before Deploy

npm run build
npm run preview

This runs the production build locally. Test everything before deploying.

Comparing to Nuxt

Nuxt deployment:

// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    preset: "vercel", // or 'netlify', 'cloudflare', etc.
  },
});

SvelteKit:

// svelte.config.js
import adapter from "@sveltejs/adapter-vercel";

export default {
  kit: {
    adapter: adapter(),
  },
};

Both use adapters/presets. Similar concepts, different config files.

Deployment Platforms Comparison

PlatformBest ForEdge SupportFree Tier
VercelGeneral appsYesGenerous
NetlifyJAMstackYesGenerous
CloudflareEdge-firstYes (native)Very generous
RailwayNode.js appsNoLimited
Fly.ioContainersGlobal regionsLimited
AWS/GCP/AzureEnterpriseDependsPay as you go

Key Takeaways

  • Adapters transform SvelteKit output for specific platforms
  • adapter-auto works for most serverless platforms
  • Use adapter-static for fully static sites
  • Use adapter-node for traditional servers
  • Environment variables: PUBLIC_* for client, others server-only
  • Preview builds locally before deploying
  • Add error tracking, caching, and security headers

Next: Lesson 20: What’s Next

Related Articles