Documentation
EasyHost docs: the ezhst CLI
Everything on EasyHost runs through the ezhst CLI, which is built to be driven by coding agents. This page covers every command.
Quick start
For agents
Run the installer and choose Global for all projects or Local for the current project, then ask your agent to deploy.
npx ezhst skill install
Then tell it: Deploy this to EasyHost. The agent deploy guide walks through it for each agent. The agent creates an account if you do not have one, creates and links a project, sets environment variables and deploys.
For humans
Install the CLI globally or run it with npx.
npm i -g ezhst
Create an account (or log in), link your Node.js app folder and deploy.
npx ezhst register npx ezhst verify <code> npx ezhst link npx ezhst deploy
Already have an account? Use npx ezhst login instead of register. You can also sign up in the dashboard.
Installing the agent skill
The skill is a single SKILL.md file that teaches your agent how to use EasyHost.
ezhst skill installAsks which agent (Claude Code, Codex or Cursor), then Global or Local.ezhst skill install --agent claude --globalWrites ~/.claude/skills/easyhost/SKILL.md for use across projects.ezhst skill install --agent cursor --localWrites .cursor/skills/easyhost/SKILL.md in the current project.Claude Code uses .claude/skills, Codex uses .agents/skills and Cursor uses .cursor/skills, under your home folder for Global or the current directory for Local. Choose Local to check the skill into the repo for your team. For noninteractive use, including --json, pass --agent <claude|codex|cursor> and exactly one of --global or --local.
For other agents, ask them to read the raw file at https://easyhost.fun/skill.md before deploying.
Authentication
ezhst register --name <name> --email <email> --password <password>Create an account. A "Default project" is created and a 6-digit verification code is emailed to you.ezhst verify <code>Verify your email with the code. Required before any other command.ezhst login --email <email> --password <password>Log in.ezhst logoutLog out.ezhst whoamiShow the logged in account.ezhst resend-verificationEmail a new code. Codes expire after 10 minutes, and you can request one every 60 seconds.ezhst forgot-password --email <email>Send a password reset link.Verification is mandatory. Until you run ezhst verify with the code from your inbox, other commands are rejected. In the dashboard, the same code is entered on the screen shown after sign up.
login and register save your token in ~/.easyhost/config.json. In CI or agent sandboxes, provide the token with the EZHST_TOKEN environment variable instead.
EZHST_TOKEN=<token> npx ezhst deploy --json
Output and prompts
- Every command accepts
--jsonfor machine readable output. Agents should always use it. - In a terminal, missing values are asked for interactively. Without a TTY the CLI never prompts: it fails with a message naming the missing flag.
Projects and linking
A project contains up to three apps (Node.js apps and AI Builder apps count together) and five scheduled API calls, with a shared storage bucket and database. Each app has its own subdomain: <app-slug>.easyhost.fun.
ezhst projects listList your projects.ezhst projects create <name>Create a project.ezhst projects infoProject details and apps.ezhst projects rename <name>Change the display name. The URL stays the same.ezhst projects delete --yesDelete all apps, deployments, schedules, storage and the database.ezhst link [--project <slug>]Link the current folder to a project (writes .easyhost.json).Project-scoped commands use the project linked in .easyhost.json. Pass --project <slug> to any of them to target another project.
ezhst projects create my-project ezhst projects list ezhst apps create my-api --project <project-slug> ezhst link --project <project-slug> --app <app-slug>
Deploying
Use ezhst apps list, ezhst apps create <name>, and ezhst apps delete --app <slug> --yes to manage up to three apps per project. Deployment, environment, build, domain and runtime commands accept --app <slug-or-id>. Link an app with ezhst link --project <slug> --app <slug>.
ezhst deploy [--verbose]Package the Node.js app in the current folder, upload, build and go live.ezhst redeploy [--verbose]Rebuild the latest upload. Use after changing env vars or build settings.ezhst startStart the app.ezhst stopStop the app.ezhst deployments listList deployments.What gets uploaded
deploy uploads your project source. It skips node_modules, .next, .git and every .env* file. No changes to your project are needed.
Environment variables are not read from your .env files. Set them with ezhst env set or ezhst env import .env before deploying.
Your app is live at https://<slug>.easyhost.fun once the build finishes.
Environment variables
Variables are applied on the next deploy or redeploy.
ezhst env listList variables.ezhst env set KEY=VALUE [KEY=VALUE...]Set one or more variables.ezhst env unset KEY [KEY...]Remove one or more variables.ezhst env import <file>Merge the variables from a .env file.ezhst env set NEXT_PUBLIC_SITE_URL=https://my-app.easyhost.fun ezhst env import .env.production ezhst redeploy
Build settings
Empty settings are auto-detected, which works for most Node.js apps.
Supported frameworks include Next.js, Nuxt, Express, NestJS, Fastify, Hono, Koa, AdonisJS, Remix, SvelteKit, Astro and Strapi. SvelteKit and Astro projects need their Node adapters; any other framework works when its production start command listens on 0.0.0.0:$PORT.
ezhst build showShow the current settings.ezhst build set [--node 20|22|24] [--root-dir <dir>] [--install <cmd>] [--build <cmd>] [--start <cmd>]Override one or more settings. Pass "" to reset a field to auto.ezhst build resetReset every setting to auto.Auto-detection
| Setting | Default |
|---|---|
| Node version | engines.node in package.json, otherwise 24 |
| Package manager | From your lockfile |
| Build command | Package build script if present; skipped otherwise |
| Start command | Package start script, Next.js, Nuxt, or Node.js entry file; must listen on 0.0.0.0 and $PORT |
ezhst build set --node 22 --root-dir apps/web ezhst build set --install "" ezhst redeploy
Logs and build logs
ezhst logs [--tail <lines>]Runtime logs from the running app.ezhst deployments log [deploymentId]Full build log. Defaults to the latest deployment.When a deploy fails, read the build log, fix the cause and run ezhst deploy again.
ezhst deployments log --json ezhst logs --tail 200
Custom domains
ezhst domains listList domains with the DNS target for each.ezhst domains add <hostname>Add a domain.ezhst domains verify <hostname>Check DNS, then issue HTTPS.ezhst domains remove <hostname>Remove a domain.DNS records
| Domain | Type | Value |
|---|---|---|
Subdomain, like www.example.com | CNAME | <slug>.easyhost.fun |
Root domain, like example.com | A | Server IP shown by ezhst domains list |
ezhst domains add www.example.com ezhst domains list ezhst domains verify www.example.com
Storage S3 compatible
Each project gets one bucket. Files are public by URL.
ezhst storage infoBucket, public base URL and S3 credentials.ezhst storage create <name>Create the bucket.ezhst storage rotate-keysIssue new S3 credentials.ezhst storage ls [prefix]List files.ezhst storage upload <files...> [--prefix <path/>]Upload files.ezhst storage download <key> [output]Download a file.ezhst storage rm <key>Delete a file.ezhst storage delete --yesDelete the bucket.Using it from your app
Run ezhst storage info, store the credentials with ezhst env set, then use any S3 client. The endpoint is https://storage.easyhost.fun, the region is us-east-1 and requests must use path-style URLs.
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
export const s3 = new S3Client({
endpoint: "https://storage.easyhost.fun",
region: "us-east-1",
forcePathStyle: true,
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY_ID!,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
},
});
export const uploadAvatar = async (userId: string, body: Buffer) => {
await s3.send(
new PutObjectCommand({
Bucket: process.env.S3_BUCKET!,
Key: `avatars/${userId}.png`,
Body: body,
ContentType: "image/png",
}),
);
};The file is then served at the public base URL from storage info followed by its key.
Database Postgres
Each project gets one managed Postgres database. See free Postgres hosting for what is included.
ezhst db infoConnection string, shadow connection string and tables.ezhst db create <name>Create the database.ezhst db query "<sql>"Run a SQL statement.ezhst db query --file <file.sql>Run a SQL file.ezhst db rows <table> [--page <n>]Browse rows in a table.ezhst db reset-passwordRotate the password and print the new connection string.ezhst db delete --yesDelete the database.Connecting your app
Copy the connection string from ezhst db info into your app's environment. It works with Prisma, Drizzle or any Postgres client.
ezhst db create main ezhst db info --json ezhst env set DATABASE_URL="postgresql://..."
Prisma migrations
prisma migrate dev needs a shadow database. Use the shadow connection string from ezhst db info.
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}After ezhst db reset-password, update DATABASE_URL with ezhst env set and run ezhst redeploy.
Scheduled API calls
Create up to five schedules per project. Calls support public HTTP/HTTPS URLs, request headers and a body. Intervals range from 1 to 43200 minutes. Calls time out after 30 seconds and do not follow redirects.
ezhst schedules listList schedules.ezhst schedules create <name> --url <url> --every <minutes> [--method POST] [--headers '<json>'] [--body '<text>']Create a schedule.ezhst schedules update <id> [--url <url>] [--every <minutes>]Update a schedule. Also accepts --name, --method, --headers and --body.ezhst schedules pause <id> | resume <id>Pause or resume calls.ezhst schedules logs <id>Show the latest 10 results; the latest 100 are retained.ezhst schedules delete <id> --yesDelete a schedule and its history.The first call follows one full interval. Saving or resuming restarts the interval. Execution may be delayed by the 10-second worker poll or available capacity. Missed intervals are skipped after downtime, and calls to the same schedule do not overlap. Requests already in progress may finish after pausing or deleting.
Email coming soon
Transactional email for your apps is coming soon. It is not available yet: the dashboard Email page shows Coming soon, and the ezhst email commands and the email API return Email is coming soon. Account emails from EasyHost itself, such as verification codes, password resets and invites, are still sent.
Team members
Invite people to a project by email. Members can manage everything in it. Only the owner can invite, revoke invites, remove members, rename or delete the project.
ezhst members listShow the owner, members and pending invites.ezhst members invite <email>Email an invite. The link is valid for 7 days and is also printed.ezhst members revoke <email>Revoke a pending invite.ezhst members remove <email> --yesRemove a member.ezhst members leave --yesLeave a project you were invited to.ezhst accept-invite <link-or-token>Join a project. Log in with the invited email first.AI Builder dashboard
The AI Builder turns a description into a running app. Open Builder in the dashboard, create an app and describe it. The name becomes its address, https://<name>.easyhost.fun.
For a new app or a big feature, the AI asks a few questions, shows a short plan to approve and lets you pick one of 9 themes before it builds. Small changes go straight to code. Every step is shown live: files written, SQL run and packages installed.
AI apps are plain JavaScript Hono servers. They use the project's Postgres database and storage when they need them (email is coming soon), and work with environment variables, logs and custom domains like any other app. The AI Builder is not part of the CLI.
Each account gets its first AI app and its first build free. After that, AI requests use AI Tokens, bought once in the dashboard and never expiring: 500 tokens for $5, 1,100 for $10, 2,400 for $20 or 6,500 for $50. Each request is charged by how much work it takes, and a typical full build is a few hundred tokens. Hosting AI apps stays free, and AI apps count toward the 3 apps per project.
Limits
EasyHost hosting is free within these limits. The AI Builder uses AI Tokens after your first free AI app and build. Node.js apps are supported, including Next.js and HTTP APIs. The free Next.js hosting page explains what each limit means in practice.
| Resource | Limit |
|---|---|
| Projects | 3 |
| Apps | 3 per project |
| Schedules | 5 per project |
| Storage buckets | 1 per project |
| Databases | 1 per project |
| Coming soon | |
| Team members | 10 per project, including pending invites |
| AI Builder prompts | 30 per day, per project |
| Concurrent builds | 1 |
| App container | 512 MB RAM, 1 CPU |