Skip to content

Vinext

AWS.Website.Vinext builds with the Vinext Vite API for production and runs native vinext dev locally. The React Server Components handler runs on a streaming Lambda Function URL. S3 stores assets and CloudFront routes asset requests to S3 and other requests to Lambda. This uses vinext, not OpenNext.

The Lambda target supports App Router applications. Use a Node deployment target such as Prisma or Fly for Pages Router applications.

Keep vinext, react, react-dom, and react-server-dom-webpack in your application dependencies, with vite and @vitejs/plugin-rsc for building. Use vinext 1.0.0-beta.10 or newer. Alchemy uses its standalone packaging to include external runtime dependencies in the Lambda archive. Add the Alchemy integration:

Terminal window
bun add -d @alchemy.run/frontend-frameworks
vite.config.ts
import { defineConfig } from "vite";
import vinext from "vinext";
export default defineConfig({
plugins: [vinext({ prerender: true })],
});

Alchemy injects the target-specific data-cache adapter during deployment. No Alchemy plugin is required in vite.config.ts; deployment settings belong on Website.Vinext. Leave Cloudflare plugins and Worker entrypoints out of this application.

alchemy.run.ts
import * as AWS from "alchemy/AWS";
export const Website = AWS.Website.Vinext("Website", {
rootDir: ".",
});

rootDir, env, memo, assets, dev, and domain use the same vocabulary as the other Website constructors. Framework configuration stays in vite.config.ts rather than a nested server configuration object.

import * as Alchemy from "alchemy";
import * as Effect from "effect/Effect";
export default Alchemy.Stack(
"MyVinextSite",
{ providers: AWS.providers(), state: Alchemy.localState() },
Effect.gen(function* () {
const site = yield* Website;
return { url: site.url };
}),
);

Keep the local state available for subsequent deploys and teardown.

export const Website = AWS.Website.Vinext("Website", {
env: { GREETING: "Hello from vinext on AWS!" },
});

env is available during build, development, and production. Server code reads process.env; public framework variables may be compiled into browser assets. Keep secrets out of public keys and wrap credentials in Redacted.

app/api/hello/route.ts
export function GET(request: Request) {
const name = new URL(request.url).searchParams.get("name") ?? "world";
return Response.json({ name, greeting: process.env.GREETING ?? "hello" });
}

Request-dependent route handlers read the production environment. A prerendered page reflects its build-time inputs instead.

The Website provisions an S3 bucket for ISR and "use cache", sets CACHE_BUCKET_NAME, and grants the Lambda access. The build selects the S3 adapter. Local development uses memory and creates no bucket.

Terminal window
bun alchemy dev

The Website runs vinext dev with native HMR and creates no cloud resources. Other resources declared in the Stack retain their own provider behavior. Apply .pipe(Alchemy.remote()) to the Website for a live deployment during dev.

const site = yield* AWS.Website.Vinext("Web", {
domain: "app.example.com",
});

See Website domains for platform-specific DNS and certificate configuration.