Octane
Archil.Website.Octane deploys a Octane app to an Archil
sandbox, Octane’s SSR server, with client assets served first. The site is the
program of its own sandbox, on port 3000, at a public
https://3000-…archil.app URL. A stopped sandbox starts again on the next
request.
Install
Section titled “Install”The build integration is not bundled with alchemy. Install
@alchemy.run/frontend-frameworks; the resource loads the package’s
/octane and /octane/node exports from your project at deploy
time. It is only used at build time, so a dev dependency is enough:
pnpm add -D https://pkg.alchemy.run/@alchemy.run/frontend-frameworks/pr:2930:d8eb8a5bun add -d https://pkg.alchemy.run/@alchemy.run/frontend-frameworks/pr:2930:d8eb8a5npm install -D https://pkg.alchemy.run/@alchemy.run/frontend-frameworks/pr:2930:d8eb8a5yarn add -D https://pkg.alchemy.run/@alchemy.run/frontend-frameworks/pr:2930:d8eb8a5Configure Octane
Section titled “Configure Octane”Keep native compiler and route settings in octane.config.ts, without
an adapter:
import { defineConfig, RenderRoute } from "@octanejs/vite-plugin";
export default defineConfig({ router: { routes: [new RenderRoute({ path: "/", entry: ["App", "/src/App.tsx"] })], },});Archil.Website.Octane selects hosting and automatically wraps Octane’s
default native Node output as an HTTP server. The legacy Node marker
adapter remains optional for existing projects.
Vite plugins like Tailwind go in vite.config.ts next to it,
alongside the Octane plugin:
import { octane } from "@octanejs/vite-plugin";import tailwindcss from "@tailwindcss/vite";import { defineConfig } from "vite";
export default defineConfig({ plugins: [octane(), tailwindcss()],});Declare the Website
Section titled “Declare the Website”Declare the site as a module-level const:
import * as Archil from "@alchemy.run/archil";
export const Website = Archil.Website.Octane("Website");sandbox sizes the site’s sandbox and sets its image, timeouts, disks and network policy:
export const Website = Archil.Website.Octane("Website", { sandbox: { vcpuCount: 2, memSizeMiB: 4096, idleTtlSeconds: 600 },});Add it to the Stack
Section titled “Add it to the Stack”Yield the site from your Stack and return its URL:
import * as Archil from "@alchemy.run/archil";import * as Alchemy from "alchemy";import * as Effect from "effect/Effect";
export const Website = Archil.Website.Octane("Website");
export default Alchemy.Stack( "MyOctaneSite", { providers: Archil.providers(), state: Alchemy.localState(), }, Effect.gen(function* () { const site = yield* Website; return { url: site.url }; }),);Run alchemy deploy. url is the site’s https://3000-…archil.app URL.
site.sandbox is the sandbox behind it, and undefined under
alchemy dev.
See examples/archil-website-octane for the checked-in example.
Add environment variables
Section titled “Add environment variables”Process environment is configured under env — plain strings, or
Redacted values. They are copied onto process.env before the
build and onto the program at deploy time:
export const Website = Archil.Website.Octane("Website", { env: { GREETING: "Hello from alchemy", API_BASE: "https://api.example.com", },});The same values are injected into the dev server’s process
environment under alchemy dev, so server code reads them in both
modes.
Read the environment in server code
Section titled “Read the environment in server code”Octane’s server runs in Node in the sandbox, so middleware and
ServerRoute handlers read the environment from process.env:
new ServerRoute({ path: "/api/greeting", methods: ["GET"], handler: async () => { return Response.json({ greeting: process.env.GREETING ?? "hello" }); },});Asset routing
Section titled “Asset routing”Octane’s intended setup is asset-first with SSR on miss: exact files
in dist/client are served by the Node process without invoking the
Octane handler, and every miss streams from Octane SSR. That is the
default — there is nothing to configure. GET /health answers for
the program’s health check.
Local dev
Section titled “Local dev”bun alchemy devalchemy dev runs Octane’s own Vite dev server — the plugin’s
in-process SSR middleware serves rendering, server routes, and RPC
with full HMR. site.url is the local address and no Archil
resources are created (sandbox is undefined). Wrap
the site in Alchemy.remote() to deploy the real infrastructure even
during dev.
Where next
Section titled “Where next”Archil.Website.Octanereference- Websites — every framework Archil hosts
- Programs and Sandboxes — what the site runs on