Hosting presets
Pre-populate schemas with Vercel, Netlify, Cloudflare, Railway, Render, or Fly.io environment variables.
Hosting providers inject system environment variables at build and runtime. Presets teach ArkEnv which variables to generate into your schema, pre-typed and optional, so you do not have to look them up manually.
Presets work with ArkType, Zod, and Valibot on a flat env.ts schema.
[!NOTE] ArkEnv is code-first. Presets write readable TypeScript schema code directly into your
./env.ts. There are no runtime dependencies on CLI presets or black-box configuration loaders.
Select a preset during init
When bootstrapping a project, select your hosting provider from the interactive
wizard or specify the --preset flag:
npx arkenv init --preset vercelpnpm dlx arkenv init --preset vercelyarn dlx arkenv init --preset vercelbunx arkenv init --preset vercelAccepted values: none, vercel, netlify, cloudflare, railway, render, fly.
The CLI also accepts -P, --host-preset, or -H as aliases. Passing none
scaffolds standard schema templates without provider fields.
Adding presets to an existing schema
Because ArkEnv is code-first and generates plain TypeScript schemas, you can copy
and paste hosting provider fields directly into your ./env.ts at any time.
Vercel
import arkenv from "@arkenv/core";
export const env = arkenv({
DATABASE_URL: "string",
// Vercel system environment variables
VERCEL: "string?",
VERCEL_ENV: "'production' | 'preview' | 'development'?",
VERCEL_URL: "string?",
});import arkenv from "@arkenv/standard";
import { z } from "zod";
export const env = arkenv({
DATABASE_URL: z.string(),
// Vercel system environment variables
VERCEL: z.string().optional(),
VERCEL_ENV: z.enum(["production", "preview", "development"]).optional(),
VERCEL_URL: z.string().optional(),
});import arkenv from "@arkenv/standard";
import * as v from "valibot";
export const env = arkenv({
DATABASE_URL: v.string(),
// Vercel system environment variables
VERCEL: v.optional(v.string()),
VERCEL_ENV: v.optional(v.picklist(["production", "preview", "development"])),
VERCEL_URL: v.optional(v.string()),
});Netlify
import arkenv from "@arkenv/core";
export const env = arkenv({
DATABASE_URL: "string",
// Netlify system environment variables
NETLIFY: "string?",
DEPLOY_URL: "string?",
CONTEXT: "'production' | 'deploy-preview' | 'branch-deploy'?",
URL: "string?",
});import arkenv from "@arkenv/standard";
import { z } from "zod";
export const env = arkenv({
DATABASE_URL: z.string(),
// Netlify system environment variables
NETLIFY: z.string().optional(),
DEPLOY_URL: z.string().optional(),
CONTEXT: z.enum(["production", "deploy-preview", "branch-deploy"]).optional(),
URL: z.string().optional(),
});import arkenv from "@arkenv/standard";
import * as v from "valibot";
export const env = arkenv({
DATABASE_URL: v.string(),
// Netlify system environment variables
NETLIFY: v.optional(v.string()),
DEPLOY_URL: v.optional(v.string()),
CONTEXT: v.optional(v.picklist(["production", "deploy-preview", "branch-deploy"])),
URL: v.optional(v.string()),
});Cloudflare Pages / Workers
import arkenv from "@arkenv/core";
export const env = arkenv({
DATABASE_URL: "string",
// Cloudflare system environment variables
CF_PAGES: "string?",
CF_PAGES_COMMIT_SHA: "string?",
CF_PAGES_BRANCH: "string?",
CF_PAGES_URL: "string?",
});import arkenv from "@arkenv/standard";
import { z } from "zod";
export const env = arkenv({
DATABASE_URL: z.string(),
// Cloudflare system environment variables
CF_PAGES: z.string().optional(),
CF_PAGES_COMMIT_SHA: z.string().optional(),
CF_PAGES_BRANCH: z.string().optional(),
CF_PAGES_URL: z.string().optional(),
});import arkenv from "@arkenv/standard";
import * as v from "valibot";
export const env = arkenv({
DATABASE_URL: v.string(),
// Cloudflare system environment variables
CF_PAGES: v.optional(v.string()),
CF_PAGES_COMMIT_SHA: v.optional(v.string()),
CF_PAGES_BRANCH: v.optional(v.string()),
CF_PAGES_URL: v.optional(v.string()),
});Railway
import arkenv from "@arkenv/core";
export const env = arkenv({
DATABASE_URL: "string",
// Railway system environment variables
RAILWAY_ENVIRONMENT_NAME: "string?",
RAILWAY_PUBLIC_DOMAIN: "string?",
RAILWAY_SERVICE_NAME: "string?",
RAILWAY_GIT_COMMIT_SHA: "string?",
});import arkenv from "@arkenv/standard";
import { z } from "zod";
export const env = arkenv({
DATABASE_URL: z.string(),
// Railway system environment variables
RAILWAY_ENVIRONMENT_NAME: z.string().optional(),
RAILWAY_PUBLIC_DOMAIN: z.string().optional(),
RAILWAY_SERVICE_NAME: z.string().optional(),
RAILWAY_GIT_COMMIT_SHA: z.string().optional(),
});import arkenv from "@arkenv/standard";
import * as v from "valibot";
export const env = arkenv({
DATABASE_URL: v.string(),
// Railway system environment variables
RAILWAY_ENVIRONMENT_NAME: v.optional(v.string()),
RAILWAY_PUBLIC_DOMAIN: v.optional(v.string()),
RAILWAY_SERVICE_NAME: v.optional(v.string()),
RAILWAY_GIT_COMMIT_SHA: v.optional(v.string()),
});Render
import arkenv from "@arkenv/core";
export const env = arkenv({
DATABASE_URL: "string",
// Render system environment variables
RENDER: "string?",
RENDER_SERVICE_ID: "string?",
RENDER_SERVICE_TYPE: "string?",
RENDER_EXTERNAL_URL: "string?",
});import arkenv from "@arkenv/standard";
import { z } from "zod";
export const env = arkenv({
DATABASE_URL: z.string(),
// Render system environment variables
RENDER: z.string().optional(),
RENDER_SERVICE_ID: z.string().optional(),
RENDER_SERVICE_TYPE: z.string().optional(),
RENDER_EXTERNAL_URL: z.string().optional(),
});import arkenv from "@arkenv/standard";
import * as v from "valibot";
export const env = arkenv({
DATABASE_URL: v.string(),
// Render system environment variables
RENDER: v.optional(v.string()),
RENDER_SERVICE_ID: v.optional(v.string()),
RENDER_SERVICE_TYPE: v.optional(v.string()),
RENDER_EXTERNAL_URL: v.optional(v.string()),
});Fly.io
import arkenv from "@arkenv/core";
export const env = arkenv({
DATABASE_URL: "string",
// Fly.io system environment variables
FLY_APP_NAME: "string?",
FLY_REGION: "string?",
FLY_ALLOC_ID: "string?",
});import arkenv from "@arkenv/standard";
import { z } from "zod";
export const env = arkenv({
DATABASE_URL: z.string(),
// Fly.io system environment variables
FLY_APP_NAME: z.string().optional(),
FLY_REGION: z.string().optional(),
FLY_ALLOC_ID: z.string().optional(),
});import arkenv from "@arkenv/standard";
import * as v from "valibot";
export const env = arkenv({
DATABASE_URL: v.string(),
// Fly.io system environment variables
FLY_APP_NAME: v.optional(v.string()),
FLY_REGION: v.optional(v.string()),
FLY_ALLOC_ID: v.optional(v.string()),
});Customizing and refining variables
Because ArkEnv gives full code ownership to your repository, you have complete control over how platform variables are validated:
Adding missing platform variables
If a hosting provider introduces a new environment variable, add the variable directly to your schema:
export const env = arkenv({
DATABASE_URL: "string",
// Add new or unlisted provider variables directly:
VERCEL_NEW_FEATURE: "string?",
VERCEL_ENV: "'production' | 'preview' | 'development'?",
VERCEL_URL: "string?",
});Refining types and transformations
You can modify field definitions to add stricter validations, regex constraints, default values, or runtime transformations (such as prefixing URLs with https://):
import { type } from "@arkenv/core";
import arkenv from "@arkenv/core";
export const env = arkenv({
// Custom transformed Vercel URL
VERCEL_URL: type("string?").pipe((url) => (url ? `https://${url}` : undefined)),
// Stricter custom environment enum
VERCEL_ENV: "'production' | 'preview' | 'development' | 'staging'?",
});What each preset adds
Every preset field is optional (present only when deployed on that provider). Fields split into:
- Server-only: Kept off the client bundle.
- Client-exposed: Safe on the client; the CLI also generates a framework-prefixed copy when a client prefix applies (
NEXT_PUBLIC_,NUXT_PUBLIC_,VITE_).
Vercel
| Variable | Type | Exposure |
|---|---|---|
VERCEL | string (optional) | Server-only |
VERCEL_ENV | "production" | "preview" | "development" (optional) | Client-exposed |
VERCEL_URL | string (optional) | Client-exposed |
Netlify
| Variable | Type | Exposure |
|---|---|---|
NETLIFY | string (optional) | Server-only |
DEPLOY_URL | string (optional) | Server-only |
CONTEXT | "production" | "deploy-preview" | "branch-deploy" (optional) | Client-exposed |
URL | string (optional) | Client-exposed |
Cloudflare Pages/Workers
| Variable | Type | Exposure |
|---|---|---|
CF_PAGES | string (optional) | Server-only |
CF_PAGES_COMMIT_SHA | string (optional) | Server-only |
CF_PAGES_BRANCH | string (optional) | Client-exposed |
CF_PAGES_URL | string (optional) | Client-exposed |
Railway
| Variable | Type | Exposure |
|---|---|---|
RAILWAY_ENVIRONMENT_NAME | string (optional) | Server-only |
RAILWAY_PUBLIC_DOMAIN | string (optional) | Server-only |
RAILWAY_SERVICE_NAME | string (optional) | Server-only |
RAILWAY_GIT_COMMIT_SHA | string (optional) | Server-only |
Render
| Variable | Type | Exposure |
|---|---|---|
RENDER | string (optional) | Server-only |
RENDER_SERVICE_ID | string (optional) | Server-only |
RENDER_SERVICE_TYPE | string (optional) | Server-only |
RENDER_EXTERNAL_URL | string (optional) | Server-only |
Fly.io
| Variable | Type | Exposure |
|---|---|---|
FLY_APP_NAME | string (optional) | Server-only |
FLY_REGION | string (optional) | Server-only |
FLY_ALLOC_ID | string (optional) | Server-only |