1---
2title: SvelteKit
3description: Deploy a SvelteKit app to Railway with Railway.Website.SvelteKit — kit SSR plus prerendered assets on one Service, and Kit's own dev server under alchemy dev.
4sidebar:
5 order: 12
6---
7
8import { Code, Tabs, TabItem } from "@astrojs/starlight/components";
9
10export const devDeps = "@alchemy.run/frontend-frameworks";
11
12`Railway.Website.SvelteKit` deploys a
13[SvelteKit](https://svelte.dev/docs/kit) app to Railway. It builds
14the app with SvelteKit's own Vite pipeline and an in-memory Node
15adapter. Client assets and prerendered pages bake into a container
16image; dynamic routes run in the kit handler on port 3000. Alchemy
17creates a `Railway.Project` if you omit `project`, then a
18`Railway.Service` from that image. `url` is the generated
19`*.up.railway.app` hostname. Your `vite.config.ts` loads natively;
20there is no `svelte.config.js` to write (kit v3 dropped it) and no
21adapter to install.
22
23## Install
24
25The build integration is not bundled with alchemy. Install
26`@alchemy.run/frontend-frameworks`; the resource loads its
27`/sveltekit` and `/sveltekit/node` exports from your project at
28deploy time. It is only used at build time, so a dev dependency is
29enough:
30
31<Tabs syncKey="pkgManager">
32 <TabItem label="bun" icon="bun">
33 <Code code={`bun add -d ${devDeps}`} lang="sh" />
34 </TabItem>
35 <TabItem label="npm" icon="npm">
36 <Code code={`npm install -D ${devDeps}`} lang="sh" />
37 </TabItem>
38 <TabItem label="pnpm" icon="pnpm">
39 <Code code={`pnpm add -D ${devDeps}`} lang="sh" />
40 </TabItem>
41 <TabItem label="yarn" icon="seti:yarn">
42 <Code code={`yarn add -D ${devDeps}`} lang="sh" />
43 </TabItem>
44</Tabs>
45
46## Configure SvelteKit
47
48Your project's `vite.config.ts` loads natively — your Vite plugins
49and the kit options in your `sveltekit(...)` call all apply as usual.
50Alchemy injects its Node adapter (replacing any adapter you declare,
51with a warning), so a fresh SvelteKit project deploys as-is.
52Deploy-specific kit overrides can also be passed via the `kit` prop,
53which merges over your `sveltekit(...)` options — see
54[Kit options](#kit-options) below. A project without a
55`vite.config.*` works too: the resource falls back to a fully
56programmatic build.
57
58## Declare the Website
59
60Declare the site as a module-level const (rather than inline in the
61Stack):
62
63```typescript
64// alchemy.run.ts
65import * as Railway from "alchemy/Railway";
66
67export const Website = Railway.Website.SvelteKit("Website");
68```
69
70Omit `project` to create a `Railway.Project` under the site
71namespace. Pass an existing Project to share it with other services.
72
73## Add it to the Stack
74
75Yield the site from your Stack and return its URL:
76
77```typescript
78// alchemy.run.ts
79import * as Alchemy from "alchemy";
80import * as Effect from "effect/Effect";
81
82export default Alchemy.Stack(
83 "MySvelteKitSite",
84 {
85 providers: Railway.providers(),
86 state: Alchemy.localState(),
87 },
88 Effect.gen(function* () {
89 const site = yield* Website;
90 return { url: site.url };
91 }),
92);
93```
94
95Routes with `export const prerender = true` are baked into the image
96and served as static files first; server routes (`+server.ts`) and
97server load functions run in the kit handler on the Service.
98
99## Add environment variables
100
101Process environment is a top-level `env` map:
102
103```diff lang="typescript"
104// alchemy.run.ts
105export const Website = Railway.Website.SvelteKit("Website", {
106+ env: {
107+ GREETING: "Hello from alchemy",
108+ API_BASE: "https://api.example.com",
109+ },
110});
111```
112
113The values are copied onto `process.env` before the build (and the
114dev server) and onto the Service at deploy time, so server code
115reads the same keys in both modes.
116
117## Read the environment in server code
118
119The Kit server runs in Node on the Service, so server routes read
120the environment from `process.env` (or kit's `$env/dynamic/private`,
121which is initialized from it):
122
123```typescript
124// src/routes/+page.server.ts
125export const load = () => {
126 return { greeting: process.env.GREETING ?? "hello" };
127};
128```
129
130## Kit options
131
132Since kit v3 there is no `svelte.config.js` — kit options live in the
133`sveltekit(...)` call in your `vite.config.ts`, which loads natively.
134A `svelte.config.js` on disk is an upstream error.
135
136```typescript
137// vite.config.ts
138import { sveltekit } from "@sveltejs/kit/vite";
139import tailwindcss from "@tailwindcss/vite";
140import { defineConfig } from "vite";
141
142export default defineConfig({
143 plugins: [
144 tailwindcss(),
145 sveltekit({
146 alias: { $lib: "src/lib" },
147 }),
148 ],
149});
150```
151
152The `kit` prop on the resource is a deploy-time override layer merged
153over those options (the override wins). It must be JSON-serializable:
154
155```typescript
156// alchemy.run.ts
157export const Website = Railway.Website.SvelteKit("Website", {
158 kit: {
159 paths: { base: "/docs" },
160 },
161});
162```
163
164Don't set `kit.adapter` — Alchemy injects its Node adapter (an
165adapter declared in your `sveltekit(...)` call is replaced with a
166warning).
167
168## Local dev
169
170```sh
171bun alchemy dev
172```
173
174`alchemy dev` runs SvelteKit's own Vite dev server — Node SSR with
175full HMR — instead of deploying; `site.url` is the local address and
176no Railway resources are created (`service` and `project` are
177`undefined`). Wrap the site in
178`Alchemy.remote()` to deploy the live Service even during dev.
179
180## Custom domain
181
182```typescript
183const site = yield* Railway.Website.SvelteKit("Web", {
184 domain: "app.example.com",
185});
186```
187
188Alchemy attaches a [`Railway.CustomDomain`](/railway/networking)
189(`targetPort` 3000). `url` becomes `https://app.example.com`. Point
190DNS at Railway's verification records.
191
192## Where next
193
194- [`SvelteKit` API](/providers/railway/website/sveltekit)
195- [Projects](/railway/compute/projects) and
196 [Services](/railway/compute/services)
197- [Custom domains](/railway/networking)