> ## Documentation Index
> Fetch the complete documentation index at: https://docs.edgespark.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Start an EdgeSpark project from a template

> Clone an EdgeSpark template into a new platform project with one edgespark init command and finish setup with a short, conditional next-steps list.

Starting a new EdgeSpark project from a template is a single command. The shape is:

```bash theme={null}
edgespark init <project-name> --agent <agent> --template <template>
```

Filled in with a real project directory name, the `claude` agent identifier, and the official `bounty-tasks` template it becomes:

```bash theme={null}
edgespark init my-app --agent claude --template bounty-tasks
```

Three things to substitute:

* `<project-name>` — the directory to create the project in. Must start with a letter or number, and contain only letters, numbers, hyphens, and underscores.
* `<agent>` — your own agent identifier: `claude` for Claude Code, `codex` for OpenAI Codex, `gemini` for Gemini CLI, `cursor` for Cursor, `copilot` for GitHub Copilot, or any other short agent name. This determines which instructions file the CLI writes — `CLAUDE.md` for `claude`, `GEMINI.md` for `gemini`, `AGENTS.md` for every other value.
* `<template>` — any [supported source](#supported-template-sources): an official shorthand like `fullstack` or `bounty-tasks`, a `github:owner/repo` reference, a tarball URL, an SSH URL, or a local path.

Under the hood the CLI fetches the template, strips anything environment-specific, creates a new platform project, pulls the project's schema, generated types, and default email/password auth config, inspects `server/src/defs/runtime.ts` for required vars and secrets, and prints a short next-steps list tailored to that template.

Running `edgespark init <project-name> --agent <agent>` without `--template` is unchanged — you still get the built-in greenfield scaffold.

## Prompt your agent for the full flow

EdgeSpark's CLI is agent-native, and the whole flow — install, login, `init --template`, vars, secrets, apply, deploy — is designed to run end to end in one agent session. The only two places the agent pauses for you are `edgespark login` (browser OAuth) and `edgespark secret set` (secure browser URL for secret values).

Paste this prompt into Claude Code, OpenAI Codex, Gemini CLI, Cursor, GitHub Copilot, or any other AI coding agent. The agent fills in the agent name itself — you only need to pick a project name and a template:

```text theme={null}
Set up a new EdgeSpark project for me in a directory called `my-app`
from the `bounty-tasks` template.

1. Run `edgespark --version`. If the command is not found, install the CLI
   with `npm install -g @edgespark/cli` and verify it prints a version.
2. Run `edgespark whoami`. If it fails with an auth error, run
   `edgespark login`, print the URL for me to open, and wait for my
   confirmation. The next edgespark command completes the login.
3. Run `edgespark init my-app --agent <YOUR-AGENT-NAME> --template bounty-tasks`.
   Substitute `<YOUR-AGENT-NAME>` with the short identifier of the agent
   you are (`claude` for Claude Code, `codex` for OpenAI Codex, `gemini`
   for Gemini CLI, `cursor` for Cursor, `copilot` for GitHub Copilot, or
   the matching short name for whatever you are). Do not leave the angle
   brackets in the actual command.
4. The "Next steps" block prints one or two
   `cd my-app/<dir> && <pm> install` lines (one for `server/`, and one
   for `web/` if the template has a frontend). Run them in order so
   dependencies are installed before any apply command.
5. Read the rest of the "Next steps" block. For each
   `edgespark var set K=<ask your user>` line, ask me for the value of
   `K` and run the command with the real value (drop the `<ask your
   user>` placeholder). For each `edgespark secret set K` line, run
   the command yourself — it opens a browser URL where I enter the
   secret value; resume when I confirm.
6. Run the remaining `edgespark db migrate`, `edgespark storage apply`,
   and `edgespark auth apply` commands in the order printed, if they
   were emitted.
7. Run `edgespark deploy --dry-run`. If it succeeds, run
   `edgespark deploy`.
```

Before pasting, change `my-app` to your project directory name and `bounty-tasks` to another [template source](#supported-template-sources) if you want — another official shorthand like `fullstack`, a GitHub reference like `github:acme/starter`, a tarball URL, an SSH URL, or a local directory path.

If the template has no required vars or secrets, step 5 collapses — no `var set` or `secret set` commands are emitted, and the agent goes straight from install to the remaining apply commands and `deploy`.

## What the command does

Every template run executes the same six steps:

1. Fetch the template source (via [`giget`](https://github.com/unjs/giget), a raw tarball fetch, SSH `git clone`, or a local directory copy).
2. Sanitize the copy — strip version control, build artifacts, and `.env*` files; reject symlinked trees (see [What gets sanitized](#what-gets-sanitized)).
3. Rename any agent instructions file the template ships (`CLAUDE.md`, `GEMINI.md`, `AGENTS.md`) to match your `--agent` choice.
4. Validate `edgespark.toml`, create a new platform project, and write the fresh `project_id` into the toml.
5. Pull schema, generated types, and the default `configs/auth-config.yaml` for the new project.
6. Read `server/src/defs/runtime.ts` and emit a conditional "Next steps" list with exactly the `var set`, `secret set`, `db migrate`, `storage apply`, `auth apply`, and `deploy` commands that have work to do for this template.

The command always exits promptly. The agent orchestrates the emitted commands in separate bash calls — `init` does not run them inline and never invokes `deploy` for you.

## Supported template sources

Pass the source to `-t` (or `--template`). The first pattern that matches wins:

| Source type                | Example                                                                                    |
| -------------------------- | ------------------------------------------------------------------------------------------ |
| Official shorthand         | `-t fullstack`, `-t bounty-tasks`, `-t bounty-tasks#main`                                  |
| GitHub repo (giget syntax) | `-t github:acme/starter`, `-t github:acme/starter/subdir`, `-t github:acme/starter#v1.0.0` |
| Full HTTPS URL             | `-t https://github.com/acme/starter`                                                       |
| Raw tarball URL            | `-t https://example.com/template.tar.gz`                                                   |
| SSH URL                    | `-t git@github.com:acme/starter.git`                                                       |
| Local directory            | `-t ./my-template`, `-t /abs/path/to/template`, `-t ~/templates/app`                       |

Official shorthands resolve to `github:edgesparkhq/official-templates/<name>`. The catalog is a single repo with one subdirectory per template — see [edgesparkhq/official-templates](https://github.com/edgesparkhq/official-templates) for what is currently shipped (today: `fullstack` and `bounty-tasks`). Community templates are any git repo — point `-t` at the URL.

Full examples:

```bash theme={null}
edgespark init my-app --agent claude -t fullstack
edgespark init my-app --agent claude -t bounty-tasks
edgespark init my-app --agent claude -t bounty-tasks#main
edgespark init my-app --agent claude -t github:acme/starter
edgespark init my-app --agent claude -t github:acme/starter/subdir
edgespark init my-app --agent claude -t github:acme/starter#v1.0.0
edgespark init my-app --agent claude -t https://github.com/acme/starter
edgespark init my-app --agent claude -t https://example.com/template.tar.gz
edgespark init my-app --agent claude -t git@github.com:acme/starter.git
edgespark init my-app --agent claude -t ./my-template
```

## What gets sanitized

After fetching, the CLI cleans the directory before doing anything else:

**Removed:**

* `.git/` — template author's history
* `node_modules/`, `dist/`, `build/`, `*.tsbuildinfo` — build artifacts
* `.env`, `.env.local`, `.env.*.local`, `.env.<anything>` — the template author's machine-specific values

**Kept:**

* `pnpm-lock.yaml`, `package-lock.json`, `yarn.lock` — preserves the template author's tested dependency tree
* `.env.example`, `.env.sample`, `.env.template` — example files the template ships on purpose

**Mutated:**

* Any committed `edgespark.toml` has its `project_id = "…"` line replaced with the fresh ID returned by the platform.
* Any agent instructions file shipped by the template (`CLAUDE.md` / `GEMINI.md` / `AGENTS.md`) is renamed to match `--agent` — pick `--agent claude` and a `GEMINI.md` becomes `CLAUDE.md`.

**Rejected:** templates containing symlinked trees fail with an error before any project is created on the platform.

## Private template credentials

Credential handling differs by fetch path:

**GitHub paths** (official shorthand, `github:owner/repo`, `https://github.com/owner/repo`, GitHub-hosted tarball URLs) read a token in this priority order. The first non-empty value wins:

1. `GIGET_AUTH`
2. `GITHUB_TOKEN`
3. `GH_TOKEN`
4. `gh auth token` output (only if the `gh` binary is on `PATH` and logged in)

**Other HTTP paths** (non-GitHub `gitlab:`, `bitbucket:`, self-hosted giget sources, non-GitHub tarball URLs) read **only `GIGET_AUTH`**. The CLI does not fall back to `GITHUB_TOKEN` / `GH_TOKEN` / `gh auth token` for non-GitHub hosts so a GitHub-scoped token never leaks to an unrelated provider.

If no applicable token is set, fetch proceeds unauthenticated — fine for public repos.

**SSH paths (`git@host:…`, `ssh://…`)** shell out to `git clone --depth 1`. Your existing SSH configuration (`~/.ssh/config`, `ssh-agent`, keys) is used transparently. No token plumbing, no credentials flow through the CLI. This path requires the `git` binary on `PATH`.

Private repos on GitHub return `404` for both "does not exist" and "no access". If fetch fails with no credential configured, the CLI prints an actionable hint suggesting `gh auth login`, a `GITHUB_TOKEN` export, or an SSH URL.

## The next-steps list

After scaffolding, `init` conditionally emits commands you still need to run. An entry only appears if it has work to do for this specific template:

| Entry                                      | Emitted when                                                                                                                                                  |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cd <project-name>/server && <pm> install` | `server/package.json` exists in the template (always for standard templates)                                                                                  |
| `cd <project-name>/web && <pm> install`    | `web/package.json` exists in the template (frontend templates)                                                                                                |
| `edgespark var set <K>=<ask your user>`    | one line per key in the `VarKey` union in `runtime.ts`                                                                                                        |
| `edgespark secret set <K>`                 | one line per key in the `SecretKey` union in `runtime.ts`                                                                                                     |
| `edgespark db migrate`                     | `drizzle/` directory exists and contains `.sql` files                                                                                                         |
| `edgespark storage apply`                  | `server/src/defs/storage_schema.ts` exists and declares at least one bucket                                                                                   |
| `edgespark auth apply`                     | `configs/auth-config.yaml` exists in the new project (true after the default auth-config pull succeeds; otherwise true if the template ships a fallback yaml) |
| `edgespark deploy`                         | always (final entry)                                                                                                                                          |

`<pm>` is auto-detected from the template (npm / pnpm / yarn / bun). Each `var set` and `secret set` line is emitted **per key** with hint text the agent should follow — `var set` carries "request `<K>` from your user, then run this command", and `secret set` carries "run this yourself and share only the returned URL with your user".

Example output for a template with two vars, one secret, migrations, and no storage (`server/` + `web/` layout, pnpm detected):

```text theme={null}
Next steps:
  cd my-app/server && pnpm install
  cd my-app/web && pnpm install

  edgespark var set LOG_LEVEL=<ask your user>
      request LOG_LEVEL from your user, then run this command
  edgespark var set API_BASE_URL=<ask your user>
      request API_BASE_URL from your user, then run this command

  edgespark secret set STRIPE_KEY
      run this yourself and share only the returned URL with your user

  edgespark db migrate
  edgespark auth apply

  edgespark deploy
      after making your project-specific changes, run dev, test the app, then deploy
```

<Warning>
  `edgespark secret set` opens a secure EdgeSpark browser URL for the human owner to paste the secret value. Secret values never pass through terminal output, agent context, or third-party LLM APIs such as Anthropic, Google, or OpenAI.
</Warning>

`deploy` is never run automatically — it remains a deliberate step. If any of the emitted apply commands fails, the scaffold is preserved on disk so retrying the exact command works.

## Template layout expectations

Templates must follow the standard EdgeSpark project layout so `init` can find the files it reads:

* `edgespark.toml` at the repo root — the `project_id` line is stripped and rewritten. `[server]` and `[web]` path entries are kept.
* `server/src/defs/runtime.ts` — the source of truth for required `VarKey` and `SecretKey` values.
* `server/src/defs/storage_schema.ts` — optional; when present, its bucket declarations drive `storage apply` emission.
* `drizzle/` — optional; when present with `.sql` files, drives `db migrate` emission.
* `configs/auth-config.yaml` — optional. The committed yaml is kept only as a fallback if the platform's default-auth pull fails; otherwise it is overwritten with email/password defaults.

Templates may also ship a `server/dev/seed.ts` for local development. See [develop locally](/guides/local-mode) for how seed data is used.

## Troubleshooting

| Symptom                                       | Likely cause                                                                                   | Fix                                                                                                               |
| --------------------------------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `404` on a GitHub repo that exists            | Repo is private and no token was picked up                                                     | Run `gh auth login`, or `export GITHUB_TOKEN=<pat>`, or switch to the SSH form (`git@github.com:owner/repo.git`). |
| SSH clone fails with `git: command not found` | `git` binary not on `PATH`                                                                     | Install git, or use an HTTPS / tarball source so the CLI does not shell out.                                      |
| Auth config warning, email/password only      | Default-auth pull failed; CLI fell back to the template's committed `configs/auth-config.yaml` | Re-run `edgespark auth pull` on the new project, then `edgespark auth apply`.                                     |
| Provider buttons missing after deploy         | Template's committed yaml enabled a provider but you have not set the secrets                  | Follow [add social login](/guides/social-login) to register an OAuth app and set the credentials.                 |
| `init` exits without emitting `db migrate`    | Template has no `drizzle/` directory with `.sql` files                                         | Generate migrations in your new project with `edgespark db generate` and run `edgespark db migrate`.              |
| `Template contains a symlink: …`              | The template fetched (or local source) has a symlinked file or directory                       | Fix the template tree to be standalone, or copy it to a flat directory and pass that path with `-t`.              |

For platform-wide naming and quota limits, see [platform limits](/reference/limits).

## See also

<Columns cols={2}>
  <Card title="Development workflow" icon="workflow" href="/guides/development-workflow">
    The day-to-day loop for schema, storage, vars, secrets, and deploys after `init`.
  </Card>

  <Card title="Project structure" icon="folder" href="/guides/project-structure">
    What `server/`, `web/`, `configs/`, and `server/src/defs/` look like in every EdgeSpark project.
  </Card>
</Columns>
