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