Websites
Alchemy deploys frontends to Railway with a family of
Railway.Website resources. Each one builds your project
programmatically and deploys it as a
Service from a container image — Node
on port 3000, health check /health — with no railway.toml and
no adapter to put in the framework config. Your framework’s own
config file (vite.config.ts, astro.config.*, nuxt.config.ts,
…) loads natively; Alchemy layers its Node container integration
on top.
Omit project and Alchemy creates a
Railway.Project. Pass project to
put the site next to other Services in an existing Project.
The live path generates a Dockerfile and uploads it; Railway
builds the image. No GHCR. No Docker daemon on your machine.
alchemy dev never creates a Project or Service.
The live URL is the generated https://{name}.up.railway.app,
or https://{domain} when you pass domain (a
CustomDomain on port
3000).
Vite— client-only Vite apps (React, Vue, Solid SPAs,index.htmlmulti-page sites); a tiny static-file server serves thevite buildoutput.Astro— Astro sites, server-rendered on Node or fully static; yourastro.config.*loads natively.Nextjs— Next.js as a long-running Node process (next build, thennext({ dev: false })). Not OpenNext.Nuxt— Nuxt apps through nitro’s Node server; yournuxt.config.tsloads natively. Do not setnitro.preset.ReactRouter— React Router v7 in framework mode, built through your ownvite build.SolidStart— SolidStart 2.x SSR; Alchemy appends nitro’snodepreset to yourvite build.SvelteKit— SvelteKit SSR plus prerendered assets; the Node adapter is injected. Do not setkit.adapter.TanStackStart— TanStack Start (React or Solid), built through your ownvite build.Waku— Waku (React Server Components) on Node, with SSG pages baked into the image.Octane— OctaneJS SSR. Selectnode()from@alchemy.run/frontend-frameworks/octane/node-adapterinoctane.config.ts.Foldkit— client-only Foldkit SPA; deep links fall back toindex.html.Vocs— prerendered Vocs docs; extensionless pages (/about→about/index.html).StaticSite— any build command’s output directory (Hugo, Zola, Eleventy).
The return is { url, service, project } — service and
project are undefined under alchemy dev.
Shared props: rootDir, memo, env (process environment on
the Service — not Worker bindings), dev, domain, project.
Builds are memoized by content-hashing the input files — an
unchanged project skips the build.
What’s supported
Section titled “What’s supported”| Framework | Resource | Guide |
|---|---|---|
| React / Vue / Solid SPA | Vite |
Vite |
| TanStack Start (React & Solid) | TanStackStart |
TanStack Start |
| React Router | ReactRouter |
React Router |
| SolidStart | SolidStart |
SolidStart |
| Astro | Astro |
Astro |
| Next.js | Nextjs |
Next.js |
| Nuxt | Nuxt |
Nuxt |
| SvelteKit | SvelteKit |
SvelteKit |
| Waku | Waku |
Waku |
| OctaneJS | Octane |
Octane |
| Foldkit | Foldkit |
Foldkit |
| Vocs | Vocs |
Vocs |
| Zola, Hugo, or any static generator | StaticSite |
Static sites |
See examples/railway-website-vite for a Vite SPA in a shared Project.
How to choose
Section titled “How to choose”Use the resource named after your framework. Astro, Nextjs,
Nuxt, ReactRouter, SolidStart, SvelteKit,
TanStackStart, Waku, Octane, Foldkit, and Vocs each
drive that framework’s programmatic build and know its output
layout, config surface, and dev server.
Use Vite when the whole deployable output is static assets — a
React, Vue, or Solid SPA, or an index.html-per-route multi-page
app. SSR frameworks that wrap Vite (Astro, SvelteKit,
Octane, …) have their own resources; Vite never starts a
framework server module.
Use StaticSite when the build is an arbitrary shell command
that emits a directory of files.
Environment variables
Section titled “Environment variables”Top-level env is copied onto process.env before build and
dev, and onto the Railway Service at deploy. Client inlining is
whatever the framework already does (VITE_* for Vite). It is
not Worker bindings and not AWS server.environment.
const site = yield* Railway.Website.Vite("Web", { project, env: { VITE_API_URL: api.url, },});Server code reads process.env. Pair a site with
Postgres in the same Project the same
way you would any other Service.
Local development
Section titled “Local development”alchemy dev runs the framework’s own dev server (native HMR)
instead of deploying. site.url is the local address and no
Project or Service is created. Wrap the site in
Alchemy.remote() to deploy the live path even during dev.
Custom domain
Section titled “Custom domain”const site = yield* Railway.Website.Astro("Web", { project, domain: "app.example.com",});domain attaches a Railway.CustomDomain (targetPort: 3000).
url becomes https://app.example.com instead of the generated
*.up.railway.app.
Where next
Section titled “Where next”- The Vite resource — assets-only SPA,
assets.notFoundHandling, env inlining. - The StaticSite resource — build commands, SPA/404 handling.
- Framework guides: Astro, Next.js, Nuxt, React Router, SolidStart, SvelteKit, TanStack Start, Waku, Octane, Foldkit, Vocs.
- Services — the container these resources deploy.
- Custom domains — hostname on a Service.
- Postgres — Postgres in the same Project.
Vitereference,Astroreference,StaticSitereference.