Skip to main content
Skip to main content

Alchemy

Use the Zerops provider for Alchemy to manage projects, services and deployments from TypeScript.

Requires alchemy@2.0.0-beta.84. Check the npm package for the latest provider version.

Install​

npm i @zerops/alchemy alchemy@2.0.0-beta.84 effect
bun add @zerops/alchemy alchemy@2.0.0-beta.84 effect

Auth​

export ZEROPS_TOKEN="YOUR_TOKEN"
VariableSetting
ZEROPS_TOKENBearer token.
ZEROPS_ENDPOINTOptional API origin. Defaults to https://api.app-prg1.zerops.io.
ZEROPS_ORGANIZATION_IDOptional organization API clientId. Required with multiple memberships.

Alchemy Profile Alternative​

bunx alchemy profile create zerops
bunx alchemy profile edit --profile zerops --add Zerops
bunx alchemy deploy --profile zerops
  • Profile fields are token, optional endpoint, and optional organizationId.

Minimal Stack​

alchemy.run.ts
import * as Alchemy from "alchemy";
import * as Effect from "effect/Effect";
import * as Zerops from "@zerops/alchemy";

export default Alchemy.Stack("ZeropsApp", {
providers: Zerops.providers(),
state: Alchemy.localState(),
}, Effect.gen(function* () {
const project = yield* Zerops.Project("Project", { mode: "LIGHT" });
const db = yield* Zerops.Postgres("Database", {
project, hostname: "db", version: "16",
});
const api = yield* Zerops.Service("Api", {
project, hostname: "api", type: "nodejs@22",
source: { dir: "./api" },
env: { DATABASE_URL: Zerops.ref(db, "connectionString") },
subdomain: true,
});
const route = yield* Zerops.HttpRoute("ApiRoute", {
project, domains: ["api.example.com"], ssl: false,
locations: [{ path: "/", service: api, port: 3000 }],
});
return { subdomainUrls: api.subdomainUrls, routeId: route.routeId };
}));
  • api/ holds the Node.js app with package.json, a lockfile, and npm start listening on port 3000.
  • api/zerops.yaml defines setup api with a Node.js 22 build and runtime and HTTP port 3000. See the zerops.yaml specification.
  • Zerops.ref(db, "connectionString") renders a server-side environment reference, so no database credentials are fetched.
  • Configure custom-domain DNS separately. Certificate issuance is not awaited.
bunx alchemy plan
bunx alchemy deploy

Resource Map​

Alchemy resourceZerops object
Zerops.ProjectProject
Zerops.ServiceRuntime service and source deployment; optional generated subdomain
Zerops.ManagedServiceManaged service without application code
Managed family helpersTyped managed services; see below
Zerops.ProjectVariableProject environment variable
Zerops.ServiceVariableService environment variable
Zerops.ObjectStorageObject-storage service, quota, access policy
Zerops.HttpRouteCustom-domain HTTP routing
Zerops.PortRoutePublic IPv6 TCP/UDP routing

Managed Families​

HelperVersionsModesFloorTypical ref keys
Postgres14, 16, 17, 18Single / HADisk 2 GBconnectionString, hostname, user, password
MariaDB10.6Single / HACatalog minimumconnectionString, dbName, user, password
Valkey7.2Single / HACatalog minimumconnectionString, connectionTlsString, hostname, password
ClickHouse25.3Single / HARAM 0.375 GBconnectionString, portHttp, user, password
Elasticsearch8.16, 9.2Single / HARAM 2 GBconnectionString, hostname, user, password
Kafka3.9Single / HACatalog minimumhostname, port, user, password
Nats2.10, 2.12Single / HACatalog minimumconnectionString, portManagement, user, password
Qdrant1.10, 1.12Single / HACatalog minimumconnectionString, grpcConnectionString, apiKey, readOnlyApiKey
Typesense27.1, 30.2Single / HACatalog minimumconnectionString, apiKey, hostname, port
SeaweedFS3.85Single / HACatalog minimumhostname, port, projectId, serviceId
Meilisearch1.10, 1.20, 1.44Single onlyCatalog minimumconnectionString, masterKey, defaultSearchKey, hostname
LocalStorage1Single onlyCatalog minimumhostname, projectId, serviceId, BACKUP_PERIOD
  • Helpers take project, version, an optional hostname, and managed-service props. The default mode is "NON_HA" (single).
  • mode: "HA" unlocks PostgreSQL connectionStringReplicas / portReplicas and Valkey connectionStringReplicas / connectionTlsStringReplicas / portReplicas / portTlsReplicas.
  • SeaweedFS is shared storage, and deprecated shared-storage import aliases map to it.
  • ManagedService({ type }) is the untyped escape hatch. Family floors and mode restrictions still apply.
  • For full ref keys and floor environment overrides, see the provider README.

Deploy Sources​

SourceZerops.Service props
Directorysource: { dir: "./api" }
Archivesource: { archive: "./api.tar.gz" }; build: false for prebuilt code
Git refsource: { git: { url: "https://github.com/owner/repo.git", ref: "v1.0.0" } }
  • Use exactly one source mode per deployment.
  • Root zerops.yml / zerops.yaml, or explicit zeropsYaml; setup defaults to the service hostname.
  • Git branches and tags resolve to commits. Tags and full 40-character SHAs are fetched provider-side, not as branch-HEAD builds on Zerops.
  • For private HTTP(S) Git repositories, git.auth accepts an Effect Redacted token. Do not put credentials in URLs.
  • Directory and Git sources exclude .git and .alchemy. Use .deployignore or the directory ignore option for other sensitive files.

Adoption and Ownership​

  • To adopt existing unowned resources, run bunx alchemy deploy --adopt. Subsequent updates and deletion then belong to the stack.
  • The project tag alchemy:<48 hex> hashes the stack, stage, and resource FQN. Matching tags recover ownership after state loss without --adopt.
  • Keep logical IDs, stack, and stage stable, and do not remove or forge ownership tags.
  • Existing explicit service and storage hostnames, variables, and routes require adoption. Incompatible service types are refused.
  • Resource .ref(...) reads Alchemy state. It is not a remote lookup or adoption.

Behavior Notes​

  • Check drift with bunx alchemy drift --no-input. To repair drift intentionally, use bunx alchemy drift --repair --no-input.
  • Generated secrets stay out of resource attributes, and environment attributes store digests. Masked secret-content drift cannot be detected.
  • Resolved props, including user-supplied secrets, persist as plaintext in Alchemy state. Redacted does not encrypt state.
  • Routing sync commits all staged edits for the project and routing kind. Foreign staged edits block sync unless forceSync: true or ZEROPS_ROUTING_FORCE_SYNC=true is set. Use one routing writer per project and routing kind.
  • Unset scaling minima default to family floors, and explicit min/max values below the floor are rejected. ZEROPS_POSTGRESQL_MIN_DISK_GB, ZEROPS_CLICKHOUSE_MIN_RAM_GB, and ZEROPS_ELASTICSEARCH_MIN_RAM_GB replace their floors, bounded below by catalog minimums (1 GB disk, 0.25 GB RAM, and 0.75 GB RAM respectively).
  • Alchemy v2 is in beta, and the provider is pinned to alchemy@2.0.0-beta.84.
  • Destroy deletes managed resources, including database and object-storage data.