docs

Quick-start

This page takes you from a built static site to a live URL. It assumes you already have the yourspace CLI — if not, the install page is one command (curl -fsSL https://yo.urspace.net/install.sh | sh); come back here once yourspace --version runs.

The CLI takes a built static site and ships it to the edge. The fastest path is yourspace setup from your project directory — it walks through scaffolding, token enrollment, and the first deploy in one continuous flow. The same three steps are also available as separate commands (init, login, deploy) when you'd rather drive them one at a time, or for re-deploys after the initial setup.

Prefer no binary?

The shell-script reference at the bottom of this page covers the lifecycle primitives (login, init, deploy, ls, status) — narrower than the binary, but readable before you run it.

Before you start

You'll need a built static site — the output of npm run build, hugo, or whatever emits HTML + assets into a folder, usually dist/ or public/. The setup walk will hand you off to api.yo.urspace.net/tokens to mint an API token mid-flow; you don't need to do anything in advance.

The fast path: yourspace setup

Run from inside your project directory. Setup walks you through naming the site, choosing the build output directory, pasting an API token, and shipping the first deploy — bailing cleanly at any step you want to defer. Re-running setup on an already-configured project keeps your yourspace.yml and resumes at whichever step is next.

$ cd my-blog && yourspace setup
Welcome to YourSpace! Let's get your site to the edge.
  this walk takes you through 3 steps:
    1. write a yourspace.yml for this project
    2. add an API token (mint one + paste it here)
    3. deploy your built site to the platform

Step 1/3 — site config
$ yourspace init
  site name [my-blog]:
  static output [dist]:
  ✓ wrote yourspace.yml

Step 2/3 — API token
  no token saved yet. let's add one.
  1. open https://api.yo.urspace.net/tokens in your browser and mint a token
  2. paste it at the prompt below

Mint a token at https://api.yo.urspace.net/tokens, then paste it.
token: ys_live_••••••••
saved → /home/me/.yourspace/token

Step 3/3 — deploy
  ship it now? [Y/n]: y

deployed my-blog (v1) at https://my-blog.yo.urspace.net

Setup complete. Updates from here: just `yourspace deploy`.

The walk wrote a yourspace.yml like this:

# yourspace.yml — generated by `yourspace init`
# docs: https://yo.urspace.net/docs
name: my-blog

build:
  dist: dist

After the first deploy, future updates are a single command — yourspace deploy from the same directory. Setup is a first-time convenience, not a steady-state path.

Driving the steps separately

If you'd rather walk each piece by hand — say you're scripting against the API, or already have a token from another machine — the same three subcommands are available individually.

yourspace login

Saves an API token under ~/.yourspace/token so every subsequent command can authenticate against api.yo.urspace.net. Set YOURSPACE_TOKEN in the environment to skip the file (handy for CI).

$ yourspace login
Mint a token at https://api.yo.urspace.net/tokens, then paste it.
token: ys_live_••••••••
saved → /home/me/.yourspace/token

yourspace init

Walks you through a yourspace.yml. The site name defaults to the current directory; if a token is already saved, the API is probed so a collision surfaces now instead of at deploy time. Press enter to accept the defaults.

$ cd my-blog && yourspace init
  site name [my-blog]:
  ✓ my-blog is available
  static output [dist]:
  ✓ wrote yourspace.yml
  next step: run `yourspace deploy` to ship it

yourspace deploy

Bundles the directory named by build.dist, streams it to the API with yourspace.yml, and prints the live URL. Repeat any time to ship a new version.

$ yourspace deploy
deployed my-blog (v1) at https://my-blog.yo.urspace.net

What deploy did

deploy tarred the directory named by build.dist, POSTed the archive with yourspace.yml as a multipart upload, and the API assigned a version and routed my-blog.yo.urspace.net at the bundle. The next deploy replaces the bundle, bumps the version, and the subdomain stays stable.

yourspace.yml is the whole contract: a site name, a directory to ship, and optional declarations for custom domains, redirects, SPA fallback, and per-route headers. Add them to the file and re-run deploy — the API reconciles the edge to whatever the latest file says.

Bundle size has two caps — 10 MB compressed and 25 MB unpacked by default — and the server rejects oversize uploads with a clear message naming the limit. See the CLI reference's bundle size limits section for details and how per-site exemptions work.

From here

  • Init & routing — the fields in yourspace.yml and how paths resolve.
  • Static sites — pointing dist: at the build output your framework emits.
  • DNS & certificates — bind a custom domain, TXT-verify once, TLS is automatic thereafter.
  • CLI reference — every command, flag, and environment variable.
  • API & MCP — deploy from CI or an agent without the CLI at all.

Shell-script reference

This single-file script covers the lifecycle primitives that get you from zero to a live site — login, init, deploy, ls, status. It is not a complete substitute for the binary: the compiled yourspace adds setup (the guided first-run walk), doctor (state checklist), open, logs, domain (bind / verify / remove), short-flag aliases, retry handling on bad token paste, status-aware colouring, and the typed-error surface that propagates the server's IDs through to the operator. The script's role is narrower: a transparent reference for the wire calls behind the lifecycle primitives, useful for auditing what gets sent before you trust the binary, or for running from a box without a Go toolchain.

yourspace.sh
#!/bin/sh
# yourspace.sh — single-file shell CLI (design preview)
# Usage: yourspace <login|init|deploy|ls|status|help>

set -eu

CONFIG_DIR="${YOURSPACE_DIR:-$HOME/.yourspace}"
TOKEN_FILE="$CONFIG_DIR/token"
API="https://api.yo.urspace.net"

log()  { printf '  \033[1;32m✓\033[0m %s\n' "$1"; }
warn() { printf '  \033[1;33m!\033[0m %s\n' "$1" >&2; }
err()  { printf '  \033[1;31m✗\033[0m %s\n' "$1" >&2; exit 1; }
ask()  { printf '  %s ' "$1" >&2; read -r R; printf '%s' "$R"; }

load_token() {
  if [ -n "${YOURSPACE_TOKEN:-}" ]; then TOKEN="$YOURSPACE_TOKEN"; return; fi
  [ -f "$TOKEN_FILE" ] || err "not logged in — run 'yourspace login' first"
  TOKEN="$(cat "$TOKEN_FILE")"
}

# -----------------------------------------------------------------------------
# yourspace login  — one-time token setup
#   Final plan: device-code flow that opens the dashboard in a browser and
#   exchanges a short code for a bearer token.
#   Today (stub): paste a token minted manually at /tokens.
# -----------------------------------------------------------------------------
cmd_login() {
  mkdir -p "$CONFIG_DIR" && chmod 700 "$CONFIG_DIR"
  printf '  Mint a deploy token at %s/tokens, then paste it.\n' "$API"
  TOKEN="$(ask 'token:')"
  [ -n "$TOKEN" ] || err "no token provided"
  printf '%s' "$TOKEN" > "$TOKEN_FILE" && chmod 600 "$TOKEN_FILE"
  log "saved → $TOKEN_FILE"
}

# -----------------------------------------------------------------------------
# yourspace init  — interactive yourspace.yml walkthrough
#   Defaults the site name from $PWD so most users just hit enter. Probes the
#   API so name collisions surface here, not at deploy time. Asks which
#   directory to ship — most static builds emit to ./dist.
#   The native binary's 'init' also accepts --name/--dir/--force for
#   scripting; same YAML shape either way.
# -----------------------------------------------------------------------------
cmd_init() {
  [ -f yourspace.yml ] && err "yourspace.yml already exists (pass --force to overwrite)"
  load_token

  DEFAULT="$(basename "$PWD" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9-' -)"
  NAME="$(ask "site name [$DEFAULT]:")"
  NAME="${NAME:-$DEFAULT}"

  STATUS="$(curl -fsS -o /dev/null -w '%{http_code}' \
    -H "Authorization: Bearer $TOKEN" "$API/v1/sites/$NAME" || true)"
  case "$STATUS" in
    200) err "'$NAME' is taken — try another name" ;;
    404) log "'$NAME' is available" ;;
    *)   warn "could not check availability (HTTP $STATUS); continuing" ;;
  esac

  DIST="$(ask 'static output directory [dist]:')"
  DIST="${DIST:-dist}"

  cat > yourspace.yml <<YAML
name: $NAME
# build is the CLI-side namespace — the server ignores it entirely.
# Keeps the nested shape matching the native CLI so a yourspace.yml
# written by this script can be fed to the Go binary without changes.
build:
  dist: $DIST
# Point custom domains at the yo.urspace.net edge via DNS; the dashboard
# walks you through it.
# custom_domains:
#   - example.com
# domain_redirects:
#   - from: www.example.com
#     to: example.com
YAML
  log "yourspace.yml created (https://$NAME.yo.urspace.net once deployed)"
}

# -----------------------------------------------------------------------------
# yourspace deploy  — bundle $dist and POST it alongside the config
#   Idempotent: repeat deploys replace the bundle for this site name and
#   bump the version counter.
# -----------------------------------------------------------------------------
cmd_deploy() {
  [ -f yourspace.yml ] || err "no yourspace.yml — run 'yourspace init' first"
  load_token

  NAME="$(awk -F: '/^name:/ { gsub(/ /,"",$2); print $2 }' yourspace.yml)"
  # build.dist is nested under the client-side 'build:' block to match the
  # native CLI's contract. Enter the block on ^build:, leave on the
  # next unindented line, and pull the first dist: value inside.
  DIST="$(awk '
    /^build:/                                 { in_build = 1; next }
    /^[^[:space:]]/                            { in_build = 0 }
    in_build && /^[[:space:]]+dist:[[:space:]]*/ {
      sub(/^[[:space:]]+dist:[[:space:]]*/, "")
      sub(/[[:space:]]*#.*$/, "")
      print; exit
    }
  ' yourspace.yml)"
  DIST="${DIST:-dist}"

  [ -d "$DIST" ] || err "$DIST/ not found — build your site before deploying"

  tar -czf dist.tar.gz -C "$DIST" .
  curl -fsSL -X POST "$API/v1/sites" \
    -H "Authorization: Bearer $TOKEN" \
    -F "config=@yourspace.yml" \
    -F "bundle=@dist.tar.gz"

  log "live → https://$NAME.yo.urspace.net"
}

# yourspace ls — sites you own (name, version, node count, last deploy)
cmd_ls() {
  load_token
  curl -fsS "$API/v1/sites" -H "Authorization: Bearer $TOKEN"
}

# yourspace status [name] — one site's live state (defaults to the yml's name)
cmd_status() {
  load_token
  NAME="${1:-$(awk '/^name:/ {print $2; exit}' yourspace.yml)}"
  [ -n "$NAME" ] || { printf 'yourspace status: pass a site name or run from a project with yourspace.yml\n' >&2; exit 2; }
  curl -fsS "$API/v1/sites/$NAME" -H "Authorization: Bearer $TOKEN"
}

case "${1:-help}" in
  login)  cmd_login ;;
  init)   cmd_init ;;
  deploy) cmd_deploy ;;
  ls)     cmd_ls ;;
  status) shift; cmd_status "$@" ;;
  *)
    printf 'Usage: yourspace <login|init|deploy|ls|status>\n'
    ;;
esac

The same script lives at /yourspace.sh for direct download — useful when you want to read it on disk before running it:

curl -fsSO https://yo.urspace.net/yourspace.sh
less yourspace.sh                  # read it before you trust it
chmod +x yourspace.sh
./yourspace.sh login

This is a download-and-review-then-run flow, not a curl | sh installer pipeline. The point is for the script to be readable before it executes; the binary's installer — curl -fsSL https://yo.urspace.net/install.sh | sh — is the path for users who'd rather not read shell.

Endpoints and the config shape may still shift before 1.0.