Railway.Project reference
Source:
src/Railway/Group.ts
A Railway.Group organizes services, databases, volumes, and buckets on
the project canvas. IaC parity with group("Backend", [api, worker, db]).
Groups have no dedicated create/delete mutation. Alchemy writes
EnvironmentConfig.groups (and services[id].groupId) via
environmentPatchCommit, matching Railway’s own IaC compiler. Volume
membership is observed from environment.canvasGroupRefs. When Railway
does not persist a first-class Group id, the resource still records
member service/volume/bucket ids. canvasViewMerge /
canvasViewMergePreview copy canvas layout between environments.
Group: Create a Group
Section titled “Group: Create a Group”Pass a Project and the members to group. Alchemy generates a unique name unless you pass one.
const site = yield* Railway.Project("Site");const api = yield* Railway.Service("Api", { project: site, image: "hashicorp/http-echo",});const worker = yield* Railway.Service("Worker", { project: site, image: "hashicorp/http-echo",});const backend = yield* Railway.Group("Backend", { project: site, resources: [api, worker],});Group: Environment
Section titled “Group: Environment”Defaults to the Project’s primary environment. Pass a
Railway.Environment (or { environmentId }) to target another one.
const staging = yield* Railway.Environment("Staging", { project: site });const backend = yield* Railway.Group("Backend", { project: site, environment: staging, resources: [api],});Group: Databases, volumes, and buckets
Section titled “Group: Databases, volumes, and buckets”Postgres/Redis/MySQL/Mongo group as services (serviceId). Volumes and
buckets are accepted as members (volumeId / bucketId).
const db = yield* Railway.Postgres("Db", { project: site });const backend = yield* Railway.Group("Backend", { project: site, resources: [api, db],});Group: Module-scope declarations
Section titled “Group: Module-scope declarations”Declare the Project once. Pass it into every child. Resource-valued props accept the resource or an Effect producing it.
import * as Railway from "alchemy/Railway";
export const Site = Railway.Project("Site");export const Api = Railway.Service("Api", { project: Site, image: "hashicorp/http-echo",});export const Backend = Railway.Group("Backend", { project: Site, resources: [Api],});Project
Section titled “Project”Source:
src/Railway/Project.ts
A Railway.Project is a workspace-scoped namespace. It owns environments and services. Names are unique per workspace.
Project: Create a Project
Section titled “Project: Create a Project”Alchemy generates a unique name unless you pass one. url is the
dashboard URL. A production environment is created with the project —
do not recreate it as an Environment resource.
const site = yield* Railway.Project("Site");Project: A stable name
Section titled “Project: A stable name”Pass name when you need a stable project name. Changing it later
updates the project in place.
const site = yield* Railway.Project("Site", { name: "my-site",});Project: Description
Section titled “Project: Description”description is optional and updates in place.
const site = yield* Railway.Project("Site", { description: "production web app",});Project: Workspace
Section titled “Project: Workspace”Workspace defaults to the current token. Pass workspaceId to pin it.
const site = yield* Railway.Project("Site", { workspaceId: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",});Project: Default environment name
Section titled “Project: Default environment name”defaultEnvironmentName is create-only. Railway’s default is
production. Extra environments (staging) are a separate Environment
resource.
const site = yield* Railway.Project("Site", { defaultEnvironmentName: "production",});Project: Module-scope declarations
Section titled “Project: Module-scope declarations”Declare the Project once. Pass it into every child. Resource-valued props accept the resource or an Effect producing it.
import * as Railway from "alchemy/Railway";
export const Site = Railway.Project("Site");Environment
Section titled “Environment”Source:
src/Railway/ProjectEnvironment.ts
A Railway.Environment is an extra deploy environment under a Project (staging, preview, …). The production environment is created with the Project — do not recreate it as an Environment resource.
Environment: Create an extra environment
Section titled “Environment: Create an extra environment”Alchemy generates a unique name unless you pass one. Production is
already on the Project as environmentId.
const site = yield* Railway.Project("Site");const staging = yield* Railway.Environment("Staging", { project: site,});Environment: A stable name
Section titled “Environment: A stable name”Pass name when you need a stable environment name (staging).
Changing it later updates the environment in place.
const staging = yield* Railway.Environment("Staging", { project: site, name: "staging",});Environment: Fork from production
Section titled “Environment: Fork from production”sourceEnvironmentId copies services, volumes, configuration, and
variables from another environment. Create-only.
const staging = yield* Railway.Environment("Staging", { project: site, sourceEnvironmentId: site.environmentId,});Environment: Module-scope declarations
Section titled “Environment: Module-scope declarations”Declare the Project once. Pass it into every child. Resource-valued props accept the resource or an Effect producing it.
import * as Railway from "alchemy/Railway";
export const Site = Railway.Project("Site");export const Staging = Railway.Environment("Staging", { project: Site,});Source:
src/Railway/ref.ts
Emit a Railway variable-reference template (${{Service.KEY}} or
${{shared.NAME}}). Distinct from the unexported resource-prop
Ref<T> — never export that Ref.
Railway.ref(Db, "DATABASE_URL") returns ${{LogicalName.DATABASE_URL}}
where LogicalName is resource.LogicalId (Postgres("Db") → Db).
Shared variables use the "shared" namespace:
Railway.ref("shared", "SENTRY_DSN") returns ${{shared.SENTRY_DSN}}.
Store the string as a Variable value (or on Service.env).
Railway keeps the template (unrendered: true) and interpolates it at
build/runtime — it is not a resolved URI. Use ConnectPostgres
when you want a typed client inside an Effect-native Service.
Railway interpolates by service name. Set name on Postgres/Service to
the LogicalId if you need the template to resolve to that service.
ref: Reference a service variable
Section titled “ref: Reference a service variable”Pass a resource (or its LogicalId) and the variable key. The result is a template string, not a URI.
const db = yield* Railway.Postgres("Db", { project: site });yield* Railway.Variable("DatabaseUrl", { project: site, service: api, name: "DATABASE_URL", value: Railway.ref(db, "DATABASE_URL"),});ref: Shared variables
Section titled “ref: Shared variables”"shared" is the environment-wide namespace (IaC ctx.shared.NAME).
env: { SENTRY_DSN: Railway.ref("shared", "SENTRY_DSN"),}Template
Section titled “Template”Source:
src/Railway/Template.ts
A Railway.Template deploys a marketplace template into a Project.
Alchemy looks up the template (template / templates), sends
templateDeployV2 with its serializedConfig, and adopts the
project/services the workflow creates.
Pass a Project to deploy into an existing one. Omit project and
Alchemy creates an owned Project first (the workspace project-create
cap is serialized).
Template: Deploy a marketplace template
Section titled “Template: Deploy a marketplace template”templateId is a marketplace UUID or code (postgres). Pass a
Project to deploy into it.
const site = yield* Railway.Project("Site");const db = yield* Railway.Template("Postgres", { templateId: "postgres", project: site,});Template: Create the Project
Section titled “Template: Create the Project”Omit project to let Alchemy create one. The name is stamped so
nuke can reclaim it.
const db = yield* Railway.Template("Postgres", { templateId: "postgres",});Template: Serialized config
Section titled “Template: Serialized config”Omit serializedConfig to use the marketplace default. Pass a
config (from template.serializedConfig, with service variable
values filled in) to override.
const db = yield* Railway.Template("Postgres", { templateId: "postgres", project: site, serializedConfig: config,});Template: Environment
Section titled “Template: Environment”Defaults to the Project’s primary environment.
const staging = yield* Railway.Environment("Staging", { project: site });const db = yield* Railway.Template("StagingPostgres", { templateId: "postgres", project: site, environment: staging,});Template: Module-scope declarations
Section titled “Template: Module-scope declarations”Resource-valued props accept the resource or an Effect producing it.
import * as Railway from "alchemy/Railway";
export const Site = Railway.Project("Site");export const Postgres = Railway.Template("Postgres", { templateId: "postgres", project: Site,});