Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 87 additions & 22 deletions tools/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ The CLI uses a config directory (default `powersync/`) with YAML files:

- Use the **`!env`** tag for secrets, e.g. `uri: !env PS_DATABASE_URI` (or `!env VAR::number` / `!env VAR::boolean` for types).
- Edit files in your IDE, then run `powersync validate` and `powersync deploy`. For schema validation and `!env` support in your editor, run **`powersync configure ide`**; or run **`powersync edit config`** to open Config Studio (built-in web-based editor).
- To use one config directory across multiple instances (e.g. dev, staging, prod), see the CLI usage docs on [configuring multiple instances](https://github.com/powersync-ja/powersync-cli/blob/main/docs/usage.md#configuring-multiple-instances-eg-dev-staging-production).
- To run commands against several instances from one config directory, define named targets in `cli.yaml`. See [Named Targets](#named-targets). The CLI usage docs cover [other layouts](https://github.com/powersync-ja/powersync-cli/blob/main/docs/usage.md#configuring-multiple-instances-eg-dev-staging-production), such as one directory per instance.
- For Cloud secrets in `service.yaml`, use `password: secret: !env VAR` to supply the value from an environment variable at deploy time; after the first deploy you can switch to `secret_ref: default_password` to reuse the stored secret. [Details](https://github.com/powersync-ja/powersync-cli#cloud-secrets-format-serviceyaml)
- `cli.yaml` records the instance ID along with the organization and project IDs. The organization and project IDs act as a cache: when both are present, the CLI uses them directly instead of looking them up from the instance, saving an API request. If they are missing, the CLI resolves them automatically from the instance ID. If they are present but incorrect for the instance, the CLI reports an error rather than overriding them.

Expand Down Expand Up @@ -151,6 +151,23 @@ powersync pull instance --instance-id=<instance-id>

Then edit `service.yaml` and `sync-config.yaml` as needed, run `powersync validate`, and `powersync deploy`. Run `powersync pull instance` again (no IDs if already linked) to refresh from the cloud.

### Preview a Deploy

Add `--dry-run` to `powersync deploy`, `powersync deploy service-config`, or `powersync deploy sync-config` to see what a deploy would do without changing the instance:

```bash
powersync deploy --dry-run
```

The command prints the target instance, runs the same validations as a real deploy, and then summarizes what would change: the `service.yaml` sections that differ from the deployed config, and a diff of the sync config. Nothing is deployed, even when the instance is not provisioned yet.

The service config summary lists section names only, because `service.yaml` holds connection strings and other secrets. To compare the full file, run `powersync pull instance` without `--overwrite`. It writes the deployed config to `service-fetched.yaml` next to your `service.yaml`, so you can diff the two files locally.

<Note>
Connections that pass a password with `secret` always show `replication` as
changed, because the value is sent again on every deploy.
</Note>

### Run Commands Without Local Config

To run commands (e.g. `powersync generate schema`, `powersync status`) against an instance managed elsewhere (e.g. Dashboard):
Expand All @@ -159,14 +176,57 @@ To run commands (e.g. `powersync generate schema`, `powersync status`) against a
- **Or pass each time:** `--instance-id`, or set `INSTANCE_ID` in the environment.

<Info>
The CLI resolves instance and linking context in a fixed order: flags take
precedence, then environment variables, then values in `cli.yaml`. For the
full resolution order and how to set up multiple instances (e.g. dev, staging,
prod), see [supplying linking information for Cloud and self-hosted
The CLI resolves the instance in a fixed order: flags first, then `cli.yaml`
(the selected target, then the top-level fields), then environment
variables. For details, see [supplying linking information for Cloud and
self-hosted
commands](https://github.com/powersync-ja/powersync-cli/blob/main/docs/usage.md#supplying-linking-information-for-cloud-and-self-hosted-commands)
in the CLI usage docs.
</Info>

### Named Targets

Named targets let one config directory point at more than one Cloud instance, such as staging and production. Each target is an entry under `targets` in `cli.yaml` with its own instance, organization, and project IDs. The top-level fields stay the default when you do not select a target.

Link an existing instance under a target name, or create a new instance and link it under one:

```bash
powersync link cloud --target=staging --instance-id=<instance-id>
powersync link cloud --create --target=staging --project-id=<project-id>
```

The resulting `cli.yaml`:

```yaml
type: cloud
instance_id: <production-instance-id>
org_id: <org-id>
project_id: <project-id>
targets:
staging:
instance_id: <staging-instance-id>
org_id: <org-id>
project_id: <project-id>
```

Select a target with `--target` on a command, or set `POWERSYNC_TARGET` for scripts and CI:

```bash
powersync pull instance --target=staging
powersync deploy --target=staging
powersync status --target=staging
POWERSYNC_TARGET=staging powersync deploy sync-config
```

`--instance-id` takes precedence over `POWERSYNC_TARGET`. You cannot combine `--target` with `--instance-id` in one command. `powersync fetch instances` lists the targets of each linked directory. Before `deploy`, `stop`, `destroy`, and `compact` change anything, the CLI prints the instance name and IDs, plus the target name when one is selected.

<Note>
Deploy writes the `name` from `service.yaml` to the instance it targets.
Instances deployed from one `service.yaml` end up with the same name in the
Dashboard, so tell them apart by target name or instance ID rather than
by instance name.
</Note>

## Self-Hosted Workflows

Support is limited: you **link** to an existing PowerSync API and run a **subset of commands**. The CLI does not create, deploy to, or pull config from your server; you manage the server and its config yourself. For local development, use **Docker** to run a PowerSync Service (and optional DB/storage) in containers.
Expand Down Expand Up @@ -249,11 +309,14 @@ Then use the same commands as any self-hosted instance (`powersync status`, `pow
| `powersync configure ide` | IDE: YAML schema validation and `!env` support |
| `powersync link cloud --instance-id=<id>` | Link to existing Cloud instance |
| `powersync link cloud --create --project-id=<id>` | Create new Cloud instance and link |
| `powersync link cloud --target=<name> --instance-id=<id>` | Link an instance as a named target in `cli.yaml` |
| `powersync link self-hosted --api-url=<url>` | Link to self-hosted instance |
| `powersync pull instance --instance-id=<id>` | Download Cloud config to local files |
| `powersync deploy` | Deploy full config to linked Cloud instance |
| `powersync deploy service-config` | [Cloud] Deploy only service config |
| `powersync deploy sync-config` | [Cloud] Deploy only sync config |
| `powersync deploy --dry-run` | [Cloud] Validate and preview what a deploy would change, without deploying |
| `powersync deploy --target=<name>` | [Cloud] Deploy to a named target. `--target` works on every instance command |
| `powersync validate` | Validate config and Sync Streams/Rules |
| `powersync edit config` | Open Config Studio (Monaco editor) |
| `powersync status` | Instance diagnostics (Cloud and self-hosted) |
Expand All @@ -272,7 +335,9 @@ Run `powersync --help` or `powersync <command> --help` for flags. Full [command

You can automate sync config (and full config) deployments using the CLI in CI. Use the config directory as the source of truth: keep `service.yaml` and `sync-config.yaml` in the repo (with secrets via `!env` and CI secrets), then run `powersync deploy` (or `powersync deploy sync-config`).

**Secrets:** Set `PS_ADMIN_TOKEN` to your PowerSync personal access token. If the workflow does not use a linked directory, also set `INSTANCE_ID`. For self-hosted, `API_URL` can specify the PowerSync API base URL.
**Secrets:** Set `PS_ADMIN_TOKEN` to your PowerSync personal access token. If the workflow does not use a linked directory, also set `INSTANCE_ID`. If the linked directory defines [targets](#named-targets), set `POWERSYNC_TARGET` to pick one. For self-hosted, `API_URL` can specify the PowerSync API base URL.

The CLI prints the target instance name and IDs before a deploy starts, so the job log shows which instance changed. For pull request checks, run `powersync deploy --dry-run` to validate the config and preview the changes without deploying.

<Card
title="GitHub Actions Demo"
Expand All @@ -293,29 +358,29 @@ npm install -g @powersync/cli@0.8.0

Otherwise, upgrade to the latest **powersync** npm package and follow the mapping below.

| Previous CLI | New CLI |
| ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `npx powersync init` (enter token, org, project) | **`powersync login`** (token only). Then **`powersync init cloud`** to scaffold config, or **`powersync pull instance --instance-id=...`** to pull an existing instance. |
| `powersync instance set --instanceId=<id>` | **`powersync link cloud --instance-id=<id>`** (writes `cli.yaml` in config directory). Or use `--directory` for a specific folder. |
| `powersync instance deploy` (interactive or long flag list) | Edit **`powersync/service.yaml`** and **`powersync/sync-config.yaml`**, then **`powersync deploy`**. Config is in files, not command args. |
| `powersync instance config` | **`powersync fetch config`** (output as YAML or JSON with `--output`). |
| Deploy only Sync Streams/Rules | **`powersync deploy sync-config`**. |
| `powersync instance schema` | **`powersync generate schema --output=... --output-path=...`** (and/or **`powersync status`** for diagnostics). |
| Org/project stored by init | Not required separately. The CLI determines the organization and project from the instance ID and caches their IDs in `cli.yaml`. For CI, set **`PS_ADMIN_TOKEN`** and **`INSTANCE_ID`**. |
| Previous CLI | New CLI |
| ----------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `npx powersync init` (enter token, org, project) | **`powersync login`** (token only). Then **`powersync init cloud`** to scaffold config, or **`powersync pull instance --instance-id=...`** to pull an existing instance. |
| `powersync instance set --instanceId=<id>` | **`powersync link cloud --instance-id=<id>`** (writes `cli.yaml` in config directory). Or use `--directory` for a specific folder, or `--target=<name>` to keep several instances in one directory. |
| `powersync instance deploy` (interactive or long flag list) | Edit **`powersync/service.yaml`** and **`powersync/sync-config.yaml`**, then **`powersync deploy`**. Config is in files, not command args. |
| `powersync instance config` | **`powersync fetch config`** (output as YAML or JSON with `--output`). |
| Deploy only Sync Streams/Rules | **`powersync deploy sync-config`**. |
| `powersync instance schema` | **`powersync generate schema --output=... --output-path=...`** (and/or **`powersync status`** for diagnostics). |
| Org/project stored by init | Not required separately. The CLI determines the organization and project from the instance ID and caches their IDs in `cli.yaml`. For CI, set **`PS_ADMIN_TOKEN`** and **`INSTANCE_ID`**. |

**Summary:** Authenticate with **`powersync login`** (or `PS_ADMIN_TOKEN` in CI). Use a **config directory** with `service.yaml` and `sync-config.yaml` as the source of truth. **Link** with **`powersync link cloud`** or **`powersync pull instance`**, then run **`powersync deploy`** or **`powersync deploy sync-config`**. No more setting “current instance” separately from config—the directory and `cli.yaml` define the target.

## Additional Documentation (CLI Repository)

More information is available in the [PowerSync CLI repository](https://github.com/powersync-ja/powersync-cli).

| Resource | Description |
| ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [CLI README](https://github.com/powersync-ja/powersync-cli/blob/main/cli/README.md) | Getting started, Cloud and self-hosted overview, and full **command reference** with all flags. |
| [General usage](https://github.com/powersync-ja/powersync-cli/blob/main/docs/usage.md) | **How the CLI works**: local config vs linking, resolution order (flags → env vars → `cli.yaml`), and **configuring multiple instances** (e.g. dev/staging/prod with separate directories or `!env` in `cli.yaml`). |
| [Docker (local development)](https://github.com/powersync-ja/powersync-cli/blob/main/docs/usage-docker.md) | Self-hosted Docker workflow, configure/start/stop/reset, database and storage modules, and template layout. |
| [Config Studio (editor)](https://github.com/powersync-ja/powersync-cli/tree/main/packages/editor) | Built-in Monaco-powered editor for `service.yaml` and `sync-config.yaml` (`powersync edit config`), schema validation, and local development. |
| [Examples](https://github.com/powersync-ja/powersync-cli/blob/main/examples/README.md) | Sample projects initialized with the CLI (e.g. Cloud pull, self-hosted Postgres, self-hosted Supabase). |
| Resource | Description |
| ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [CLI README](https://github.com/powersync-ja/powersync-cli/blob/main/cli/README.md) | Getting started, Cloud and self-hosted overview, and full **command reference** with all flags. |
| [General usage](https://github.com/powersync-ja/powersync-cli/blob/main/docs/usage.md) | **How the CLI works**: local config vs linking, resolution order (flags → `cli.yaml` → env vars), and **configuring multiple instances** (named targets in `cli.yaml`, separate directories, or `!env`). |
| [Docker (local development)](https://github.com/powersync-ja/powersync-cli/blob/main/docs/usage-docker.md) | Self-hosted Docker workflow, configure/start/stop/reset, database and storage modules, and template layout. |
| [Config Studio (editor)](https://github.com/powersync-ja/powersync-cli/tree/main/packages/editor) | Built-in Monaco-powered editor for `service.yaml` and `sync-config.yaml` (`powersync edit config`), schema validation, and local development. |
| [Examples](https://github.com/powersync-ja/powersync-cli/blob/main/examples/README.md) | Sample projects initialized with the CLI (e.g. Cloud pull, self-hosted Postgres, self-hosted Supabase). |

## Known Issues and Limitations

Expand Down
Loading