1---
2title: Websites
3description: Deploy Vite, Astro, Next.js, vinext, Nuxt, React Router, SolidStart, SvelteKit, TanStack Start, Waku, Octane, Foldkit, Vocs, or any static build to Railway with first-class Website resources.
4sidebar:
5 label: Overview
6 order: 1
7---
8
9Alchemy deploys frontends to Railway with a family of
10`Railway.Website` resources. Each one builds your project
11programmatically and deploys it as a
12[Service](/railway/compute/services) from a container image — Node
13on port 3000, health check `/health` — with no `railway.toml` and
14no adapter to put in the framework config. Your framework's own
15config file (`vite.config.ts`, `astro.config.*`, `nuxt.config.ts`,
16...) loads natively; Alchemy layers its Node container integration
17on top.
18
19Omit `project` and Alchemy creates a
20[`Railway.Project`](/railway/compute/projects). Pass `project` to
21put the site next to other Services in an existing Project.
22
23The live path generates a Dockerfile and uploads it; Railway
24builds the image. No GHCR. No Docker daemon on your machine.
25`alchemy dev` never creates a Project or Service.
26
27The live URL is the generated `https://{name}.up.railway.app`,
28or `https://{domain}` when you pass `domain` (a
29[`CustomDomain`](/railway/networking#custom-domains) on port
303000).
31
32- [`Vite`](/railway/frontend/vite) — client-only Vite apps
33 (React, Vue, Solid SPAs, `index.html` multi-page sites); a tiny
34 static-file server serves the `vite build` output.
35- [`Astro`](/railway/frontend/astro) — Astro sites, server-rendered
36 on Node or fully static; your `astro.config.*` loads natively.
37- [`Nextjs`](/railway/frontend/nextjs) — Next.js as a long-running
38 Node process (`next build`, then `next({ dev: false })`). Not
39 OpenNext.
40- [`Vinext`](/railway/frontend/vinext) — vinext (Next.js API on Vite)
41 as a long-running Node process (`vinext build`, then
42 `startProdServer`). Not the Cloudflare Worker path.
43- [`Nuxt`](/railway/frontend/nuxt) — Nuxt apps through nitro's
44 Node server; your `nuxt.config.ts` loads natively. Do not set
45 `nitro.preset`.
46- [`ReactRouter`](/railway/frontend/react-router) — React Router
47 v7 in framework mode, built through your own `vite build`.
48- [`SolidStart`](/railway/frontend/solidstart) — SolidStart 2.x
49 SSR; Alchemy appends nitro's `node` preset to your `vite build`.
50- [`SvelteKit`](/railway/frontend/sveltekit) — SvelteKit SSR plus
51 prerendered assets; the Node adapter is injected. Do not set
52 `kit.adapter`.
53- [`TanStackStart`](/railway/frontend/tanstack-start) — TanStack
54 Start (React or Solid), built through your own `vite build`.
55- [`Waku`](/railway/frontend/waku) — Waku (React Server
56 Components) on Node, with SSG pages baked into the image.
57- [`Octane`](/railway/frontend/octane) — OctaneJS SSR. Alchemy wraps
58 native Node output; no hosting adapter is needed in `octane.config.ts`.
59- [`Foldkit`](/railway/frontend/foldkit) — client-only Foldkit
60 SPA; deep links fall back to `index.html`.
61- [`Vocs`](/railway/frontend/vocs) — prerendered Vocs docs;
62 extensionless pages (`/about` → `about/index.html`).
63- [`StaticSite`](/railway/frontend/static-site) — any build
64 command's output directory (Hugo, Zola, Eleventy).
65
66The return is `{ url, service, project }` — `service` and
67`project` are `undefined` under `alchemy dev`.
68
69Shared props: `rootDir`, `memo`, `env` (process environment on
70the Service — not Worker bindings), `dev`, `domain`, `project`.
71Builds are memoized by content-hashing the input files — an
72unchanged project skips the build.
73
74## What's supported
75
76| Framework | Resource | Guide |
77| --- | --- | --- |
78| React / Vue / Solid SPA | `Vite` | [Vite](/railway/frontend/vite) |
79| TanStack Start (React & Solid) | `TanStackStart` | [TanStack Start](/railway/frontend/tanstack-start) |
80| React Router | `ReactRouter` | [React Router](/railway/frontend/react-router) |
81| SolidStart | `SolidStart` | [SolidStart](/railway/frontend/solidstart) |
82| Astro | `Astro` | [Astro](/railway/frontend/astro) |
83| Next.js | `Nextjs` | [Next.js](/railway/frontend/nextjs) |
84| vinext | `Vinext` | [vinext](/railway/frontend/vinext) |
85| Nuxt | `Nuxt` | [Nuxt](/railway/frontend/nuxt) |
86| SvelteKit | `SvelteKit` | [SvelteKit](/railway/frontend/sveltekit) |
87| Waku | `Waku` | [Waku](/railway/frontend/waku) |
88| OctaneJS | `Octane` | [Octane](/railway/frontend/octane) |
89| Foldkit | `Foldkit` | [Foldkit](/railway/frontend/foldkit) |
90| Vocs | `Vocs` | [Vocs](/railway/frontend/vocs) |
91| Zola, Hugo, or any static generator | `StaticSite` | [Static sites](/railway/frontend/static-site) |
92
93See
94[examples/railway-website-vite](https://github.com/alchemy-run/alchemy/tree/main/examples/railway-website-vite)
95for a Vite SPA in a shared Project.
96
97## How to choose
98
99Use the resource named after your framework. `Astro`, `Nextjs`,
100`Nuxt`, `ReactRouter`, `SolidStart`, `SvelteKit`,
101`TanStackStart`, `Waku`, `Octane`, `Foldkit`, and `Vocs` each
102drive that framework's programmatic build and know its output
103layout, config surface, and dev server.
104
105Use `Vite` when the whole deployable output is static assets — a
106React, Vue, or Solid SPA, or an `index.html`-per-route multi-page
107app. SSR frameworks that wrap Vite (`Astro`, `SvelteKit`,
108`Octane`, …) have their own resources; `Vite` never starts a
109framework server module.
110
111Use `StaticSite` when the build is an arbitrary shell command
112that emits a directory of files.
113
114## Environment variables
115
116Top-level `env` is copied onto `process.env` before build and
117dev, and onto the Railway Service at deploy. Client inlining is
118whatever the framework already does (`VITE_*` for Vite). It is
119not Worker bindings and not AWS `server.environment`.
120
121```typescript
122const site = yield* Railway.Website.Vite("Web", {
123 project,
124 env: {
125 VITE_API_URL: api.url,
126 },
127});
128```
129
130Server code reads `process.env`. Pair a site with
131[Postgres](/railway/data/postgres) in the same Project the same
132way you would any other Service.
133
134## Local development
135
136`alchemy dev` runs the framework's own dev server (native HMR)
137instead of deploying. `site.url` is the local address and no
138Project or Service is created. Wrap the site in
139`Alchemy.remote()` to deploy the live path even during dev.
140
141## Custom domain
142
143```typescript
144const site = yield* Railway.Website.Astro("Web", {
145 project,
146 domain: "app.example.com",
147});
148```
149
150`domain` attaches a `Railway.CustomDomain` (`targetPort: 3000`).
151`url` becomes `https://app.example.com` instead of the generated
152`*.up.railway.app`.
153
154## Where next
155
156- [The Vite resource](/railway/frontend/vite) — assets-only SPA,
157 `assets.notFoundHandling`, env inlining.
158- [The StaticSite resource](/railway/frontend/static-site) — build
159 commands, SPA/404 handling.
160- Framework guides:
161 [Astro](/railway/frontend/astro),
162 [Next.js](/railway/frontend/nextjs),
163 [Nuxt](/railway/frontend/nuxt),
164 [React Router](/railway/frontend/react-router),
165 [SolidStart](/railway/frontend/solidstart),
166 [SvelteKit](/railway/frontend/sveltekit),
167 [TanStack Start](/railway/frontend/tanstack-start),
168 [Waku](/railway/frontend/waku),
169 [Octane](/railway/frontend/octane),
170 [Foldkit](/railway/frontend/foldkit),
171 [Vocs](/railway/frontend/vocs).
172- [Services](/railway/compute/services) — the container these
173 resources deploy.
174- [Custom domains](/railway/networking#custom-domains) — hostname
175 on a Service.
176- [Postgres](/railway/data/postgres) — Postgres in the same
177 Project.
178- [`Vite` reference](/providers/railway/website/vite),
179 [`Astro` reference](/providers/railway/website/astro),
180 [`StaticSite` reference](/providers/railway/website/staticsite).