Skip to content

Deploy your first app

This page takes a one-file app from your computer to a live address and shares it with one other person. You need the CLI installed and signed in. Signing in the first time is also when you agree to the terms of service, in the dashboard: until you have, creating a workspace is refused with Sign in to the dashboard once to accept the terms of service, then try again.

  1. Create a workspace.

    Every app lives in a workspace, and signing up doesn’t make one. Pick a slug: lowercase letters, digits and single dashes, up to 30 characters. It becomes part of every app’s name and address.

    Terminal window
    jiayang workspace create acme
    Created workspace acme. You own it.

    Slugs are unique across the platform. If someone has acme already:

    error: That short name is taken, by another workspace or by one deleted in the last 30 days. Pick another.

    A new workspace is on the Free plan. See Workspaces and roles for what a workspace holds.

  2. Write an app.

    Make a directory called hello with one file, index.js:

    hello/index.js
    export default {
    async fetch(request) {
    // For display only. To decide what someone may do, verify the identity token with an SDK.
    const email = request.headers.get("x-jiayang-email") ?? "there";
    return new Response(`Hello, ${email}.\n`);
    },
    };

    A directory with an index.js and no package.json deploys as a Worker, as it stands, with nothing to install or build. Check what the CLI makes of it:

    Terminal window
    jiayang detect ./hello
    a Worker
    because it has index.js
  3. Deploy it.

    Terminal window
    jiayang deploy acme/hello ./hello --create
    a Worker
    because it has index.js
    Deployed version 1 (8b217ef9bf3c).
    https://hello--acme.jiayang-apps.cloud

    acme/hello names the app: the workspace, then the app’s own slug. --create makes the app because it doesn’t exist yet. The app is private: nobody but you can open it. The last line is its address, https://<app>--<workspace>.jiayang-apps.cloud.

  4. Open it.

    Open the address in your browser. The first time, the platform sends you to sign in to the dashboard, then straight back to the app, which says:

    Hello, ada@example.com.

    jiayang open acme/hello prints the address again. To call the app from the terminal as yourself:

    Terminal window
    jiayang curl acme/hello
    Hello, ada@example.com.
    200 OK
  5. Share it.

    Terminal window
    jiayang share acme/hello grace@example.com
    grace@example.com can now use acme/hello as viewer.

    Grace gets an email with the app’s address. She signs in with a code sent to her address and sees Hello, grace@example.com. She doesn’t need to be in your workspace, and she can’t see anything else in it.

    Anyone you haven’t shared the app with gets 403 forbidden after they sign in. See who has access:

    Terminal window
    jiayang access acme/hello
    owner ada@example.com
    viewer grace@example.com

    You own the app because you created it. To take access away, run jiayang unshare acme/hello grace@example.com. It ends within 60 seconds, open connections included.

Run the same command after every change. --create does nothing once the app exists, so you can leave it in:

Terminal window
jiayang deploy acme/hello ./hello --create
a Worker
because it has index.js
Deployed version 2 (c02ed76b2040).
https://hello--acme.jiayang-apps.cloud
Version 1 can still answer some requests for up to a minute, until this one reaches every location.

Each deploy is a new version, and it goes live when the upload finishes. jiayang versions acme/hello lists them:

2 deployed 2026-09-23 ada@example.com (live)
1 deployed 2026-09-23 ada@example.com

jiayang rollback acme/hello 1 puts version 1 back. See Versions and rollback.

For a script, --json prints the result as JSON, with the address in url and the version in number:

Terminal window
jiayang --json deploy acme/hello ./hello

Deploying to an app that doesn’t exist, without --create:

error: app acme/hello not found. `jiayang app list acme` shows the apps there that you can see, and `jiayang deploy acme/hello <dir> --create` makes it. If acme isn't a workspace you're in, `jiayang workspace list` shows the ones you are.

The Free plan holds three apps:

error: This workspace has 3 apps, which is all the Free plan allows. Delete one, or upgrade: Team allows 25 apps. Billing: https://app.jiayang.cloud/w/acme/billing

A server in a container (Python, Go, Rust, or a Node server) on the Free plan:

error: The Free plan runs JS and static apps only. Container apps (Python, Go, Rust, Node servers) need a paid plan: Team runs container apps. Upgrade the workspace at https://app.jiayang.cloud/w/acme/billing

Your role in the workspace, or on the app, doesn’t allow the change:

error: You don't have permission to do that.

Not signed in:

error: not logged in: run `jiayang login`

The app deployed, but answers with a 500 or Cloudflare’s error 1101: it threw. Its log has the exception:

Terminal window
jiayang logs acme/hello

See Logs.