diff --git a/configuration/auth/development-tokens.mdx b/configuration/auth/development-tokens.mdx
index d9b053dc..e3dce902 100644
--- a/configuration/auth/development-tokens.mdx
+++ b/configuration/auth/development-tokens.mdx
@@ -30,8 +30,7 @@ This can also be used to generate a token for a specific user to debug issues.
- For self-hosted setups, you can generate development tokens using the [powersync-service test-client](https://github.com/powersync-ja/powersync-service/tree/main/test-client):
-
+ Follow the steps below. Steps 1 and 2 configure signing keys and your PowerSync Service config; in Step 3 you can use the PowerSync CLI (recommended) or the [test-client](https://github.com/powersync-ja/powersync-service/tree/main/test-client) to generate the token.
diff --git a/configuration/source-db/setup.mdx b/configuration/source-db/setup.mdx
index 054f3e78..0bf8b080 100644
--- a/configuration/source-db/setup.mdx
+++ b/configuration/source-db/setup.mdx
@@ -615,7 +615,7 @@ Due to the fundamental differences in how CDC works compared to logical replicat
2. **Polling Interval**: The frequency at which PowerSync polls the CDC change tables for changes. The default value is once every 1000ms. This can be changed by setting the `pollingIntervalMs` parameter in the PowerSync configuration.
-Configuration parameters for SQL Server like `pollingIntervalMs` and `pollingBatchSize` (see below) can currently only be [set when self-hosting](/intro/setup-guide#self-hosted-2) PowerSync. We are working on exposing these settings for SQL Server source database connections in the PowerSync Dashboard for PowerSync Cloud instances.
+Configuration parameters for SQL Server like `pollingIntervalMs` and `pollingBatchSize` (see below) can currently only be set when self-hosting PowerSync (e.g. via your config file or the [PowerSync CLI](/tools/cli)). We are working on exposing these settings in the PowerSync Dashboard for PowerSync Cloud instances.
### Memory Management
diff --git a/intro/self-hosting.mdx b/intro/self-hosting.mdx
index ec8e9fce..08637b53 100644
--- a/intro/self-hosting.mdx
+++ b/intro/self-hosting.mdx
@@ -9,7 +9,6 @@ The [PowerSync Service](https://github.com/powersync-ja/powersync-service) can b
* Note that the [PowerSync Dashboard](https://dashboard.powersync.com/) is currently not available when self-hosting PowerSync.
- * The PowerSync Open Edition is currently considered a beta release as it still requires more detailed documentation and guides. From a stability perspective, the Open Edition is production-ready. It uses the same codebase as our Cloud version. See [Feature Status](/resources/feature-status) for how we define beta releases.
* Please reach out on our [Discord](https://discord.gg/powersync) if you have any questions not yet covered in these docs.
@@ -27,9 +26,9 @@ The quickest way to get a feel for the system is to run our example project on y
-## Local Development With Docker Compose
+## Local Development
-If you plan to self-host for development purposes only, see [Local Development](/tools/local-development) for how to easily do this using Docker Compose.
+To run PowerSync locally, see [Local Development](/tools/local-development). The easiest path is the [PowerSync CLI](/tools/cli), which sets up a Docker Compose stack for you.
## Full Installation
diff --git a/intro/setup-guide.mdx b/intro/setup-guide.mdx
index d9e821b1..a08ec8db 100644
--- a/intro/setup-guide.mdx
+++ b/intro/setup-guide.mdx
@@ -1,7 +1,7 @@
---
title: "PowerSync Setup Guide"
sidebarTitle: "Setup Guide"
-description: "This guide walks you through adding PowerSync to your app project step-by-step. "
+description: "This guide walks you through adding PowerSync to your app project step-by-step."
---
import LocalOnly from '/snippets/local-only-escape.mdx';
@@ -20,6 +20,10 @@ import DevTokenSelfHostedSteps from '/snippets/dev-token-self-hosted-steps.mdx';
PowerSync needs to connect to your source database (Postgres, MongoDB, MySQL or SQL Server) to replicate data. Before setting up PowerSync, you need to configure your database with the appropriate permissions and replication settings.
+
+Using the [PowerSync CLI](/tools/cli) and want an automatically integrated Postgres instance for local development? You can skip to [Step 2](#2-set-up-powersync-service-instance) and set one up with the **CLI (Self-Hosted)** tab.
+
+
Configuring Postgres for PowerSync involves three main tasks:
@@ -176,101 +180,168 @@ PowerSync needs to connect to your source database (Postgres, MongoDB, MySQL or
PowerSync is available as a cloud-hosted service (PowerSync Cloud) or can be self-hosted (PowerSync Open Edition or PowerSync Enterprise Self-Hosted Edition).
-
- If you haven't yet, sign up for a free PowerSync Cloud account [here](https://accounts.powersync.com/portal/powersync-signup?s=docs).
+
+ If you haven't yet, sign up for a free PowerSync Cloud account [here](https://accounts.powersync.com/portal/powersync-signup?s=docs).
- After signing up, you will be taken to the [PowerSync Dashboard](https://dashboard.powersync.com/).
-
- Here, create a new project. _Development_ and _Production_ instances of the PowerSync Service will be created by default in the project.
-
+ After signing up, you will be taken to the [PowerSync Dashboard](https://dashboard.powersync.com/).
-
- Self-hosted PowerSync runs via Docker.
-
- Below is a minimal example of setting up the PowerSync Service with Postgres as the [bucket storage](/architecture/powersync-service#bucket-storage) database and example Sync Streams. MongoDB is also supported as a bucket storage database (docs are linked at the end of this step), and you will learn more about Sync Streams in a later step.
-
- ```bash
- # 1. Create a directory for your config
- mkdir powersync-service && cd powersync-service
-
- # 2. Set up bucket storage (Postgres and MongoDB are supported)
- docker run -d \
- --name powersync-postgres-storage \
- --network powersync-network \
- -p 5433:5432 \
- -e POSTGRES_PASSWORD="my_secure_storage_password" \
- -e POSTGRES_DB=powersync_storage \
- postgres:18
-
- ## Set up Postgres storage user
- docker exec -it powersync-postgres-storage psql -U postgres -d powersync_storage -c "
- CREATE USER powersync_storage_user WITH PASSWORD 'my_secure_user_password';
- GRANT CREATE ON DATABASE powersync_storage TO powersync_storage_user;"
-
- # 3. Create config.yaml (see below)
-
- # 4. Run PowerSync Service
- # The Service config can be specified as an environment variable (shown below), as a filepath, or as a command line parameter
- # See these docs for more details: https://docs.powersync.com/configuration/powersync-service/self-hosted-instances
- docker run -d \
- --name powersync \
- --network powersync-network \
- -p 8080:8080 \
- -e POWERSYNC_CONFIG_B64="$(base64 -i ./config.yaml)" \
- journeyapps/powersync-service:latest
- ```
+ Here, create a new project. _Development_ and _Production_ instances of the PowerSync Service will be created by default in the project.
+
- **Basic `config.yaml` structure:**
-
- ```yaml
- # Source database connection (see the next step for more details)
- replication:
- connections:
- - type: postgresql # or mongodb, mysql, mssql
- uri: postgresql://powersync_role:myhighlyrandompassword@powersync-postgres:5432/postgres
- sslmode: disable # Only for local/private networks
-
- # Bucket storage connection (Postgres and MongoDB are supported)
- storage:
- type: postgresql
- uri: postgresql://powersync_storage_user:my_secure_user_password@powersync-postgres-storage:5432/powersync_storage
- sslmode: disable # Use 'disable' only for local/private networks
-
- # Sync Streams (explained in a later step)
- sync_config:
- content: |
- config:
- edition: 3
- streams:
- shared_data:
- auto_subscribe: true
- queries:
- - SELECT * FROM lists
- - SELECT * FROM todos
- ```
+
+ If you haven't yet, sign up for a free PowerSync Cloud account [here](https://accounts.powersync.com/portal/powersync-signup?s=docs).
-
- **Note**: This example assumes you've configured your source database with the required user and publication (see the previous step)
- and are running it via Docker in the `powersync-network` network.
-
- If you are not using Docker, you will need to specify the connection details in the `config.yaml` file manually (see next step for more details).
-
+ Install the [PowerSync CLI](/tools/cli) (requires Node.js/npm), then log in and scaffold the config directory:
-
- **Learn More**
- * [Self-Hosting Introduction](/intro/self-hosting)
- * [Self-Host Demo App](https://github.com/powersync-ja/self-host-demo) for complete working examples.
- * [Self-Hosted Service Configuration](/configuration/powersync-service/self-hosted-instances) for more details on the config file structure.
-
-
-
+ ```bash
+ npm install -g powersync
+ powersync login
+ powersync init cloud
+ ```
+
+ This creates a `powersync/` directory with `service.yaml` (instance name, region, connection, auth) and `sync-config.yaml` (sync config). Edit `powersync/service.yaml` to set your instance name and region — you'll configure the database connection in the next step.
+
+ Then create the Cloud instance:
+
+ ```bash
+ powersync link cloud --create --project-id=
+ ```
+
+ Find your project ID in the [PowerSync Dashboard](https://dashboard.powersync.com) URL, or run `powersync fetch instances` after logging in.
+
+
+
+ Recommended for getting started: the CLI scaffolds your config directory and generates the Docker Compose stack (including a Postgres instance for the source database and storage) so you can run PowerSync locally with minimal setup. For custom setups use the **Manual (Self-Hosted)** tab. Install the [PowerSync CLI](/tools/cli) (requires Node.js/npm); alternative installation options (e.g. installers via GitHub releases) will be available in the near future. Then run:
+
+ ```bash
+ npm install -g powersync
+ powersync init self-hosted
+ powersync docker configure --database postgres --storage postgres
+ ```
+
+ Docker sets up Postgres for both the source database and bucket storage and creates `powersync/docker/docker-compose.yaml`. Other databases are supported as well, you will learn more about this in the next step. Before starting, replace `powersync/sync-config.yaml` with this minimal sync config:
+
+ ```yaml
+ config:
+ edition: 2
+
+ streams:
+ todos:
+ # Streams without parameters sync the same data to all users
+ auto_subscribe: true
+ query: "SELECT * FROM todos"
+ ```
+
+ You'll update this with your actual tables/collections in a later step.
+
+ The Docker Postgres instance runs init scripts only on first start. Create your specific tables before running `powersync docker start` for the first time. See the [Docker usage docs](https://github.com/powersync-ja/powersync-cli/blob/main/docs/usage-docker.md) in the PowerSync CLI repository for more details.
+
+ Then start the PowerSync Service:
+
+ ```bash
+ powersync docker start
+ ```
+
+ Run `powersync status` to verify it's running.
+
+
+ **Learn More**
+ * [Self-Hosting Introduction](/intro/self-hosting)
+ * [Self-Host Demo App](https://github.com/powersync-ja/self-host-demo) for complete working examples.
+ * [Self-Hosted Service Configuration](/configuration/powersync-service/self-hosted-instances) for more details on the config file structure.
+ * [CLI documentation](/tools/cli)
+
+
+
+
+ Self-hosted PowerSync runs via Docker. The commands below illustrate the basic PowerSync Service requirements.
+
+ Below is a minimal example using Postgres for bucket storage. MongoDB is also supported as bucket storage. The source database connection is configured in the next step — you can use the Docker-managed Postgres from Step 1 or point to an external database instead.
+
+ ```bash
+ # 1. Create a directory for your config
+ mkdir powersync-service && cd powersync-service
+
+ # 2. Set up bucket storage (Postgres and MongoDB are supported)
+ docker run -d \
+ --name powersync-postgres-storage \
+ --network powersync-network \
+ -p 5433:5432 \
+ -e POSTGRES_PASSWORD="my_secure_storage_password" \
+ -e POSTGRES_DB=powersync_storage \
+ postgres:18
+
+ ## Set up Postgres storage user
+ docker exec -it powersync-postgres-storage psql -U postgres -d powersync_storage -c "
+ CREATE USER powersync_storage_user WITH PASSWORD 'my_secure_user_password';
+ GRANT CREATE ON DATABASE powersync_storage TO powersync_storage_user;"
+
+ # 3. Create config.yaml (see below)
+
+ # 4. Run PowerSync Service
+ # The Service config can be specified as an environment variable (shown below), as a filepath, or as a command line parameter
+ # See these docs for more details: https://docs.powersync.com/configuration/powersync-service/self-hosted-instances
+ docker run -d \
+ --name powersync \
+ --network powersync-network \
+ -p 8080:8080 \
+ -e POWERSYNC_CONFIG_B64="$(base64 -i ./config.yaml)" \
+ journeyapps/powersync-service:latest
+ ```
+
+ **Basic `config.yaml` structure:**
+
+ ```yaml
+ # Source database connection (see the next step for more details)
+ replication:
+ connections:
+ - type: postgresql # or mongodb, mysql, mssql
+ uri: postgresql://powersync_role:myhighlyrandompassword@powersync-postgres:5432/postgres
+ sslmode: disable # Only for local/private networks
+
+ # Connection settings for bucket storage (Postgres and MongoDB are supported)
+ storage:
+ type: postgresql
+ uri: postgresql://powersync_storage_user:my_secure_user_password@powersync-postgres-storage:5432/powersync_storage
+ sslmode: disable # Use 'disable' only for local/private networks
+
+ # Sync Streams config (defined in a later step)
+ sync_config:
+ content: |
+ config:
+ edition: 3
+ streams:
+ shared_data:
+ auto_subscribe: true
+ queries:
+ - SELECT * FROM lists
+ - SELECT * FROM todos
+ ```
+
+
+ **Note**: This example assumes you've configured your source database with the required user and publication (see the previous step)
+ and are running it via Docker in the 'powersync-network' network.
+
+ If you are not using Docker, you will need to specify the connection details in the `config.yaml` file manually (see next step for more details).
+
+
+
+ **Learn More**
+ * [Self-Hosting Introduction](/intro/self-hosting)
+ * [Self-Host Demo App](https://github.com/powersync-ja/self-host-demo) for complete working examples.
+ * [Self-Hosted Service Configuration](/configuration/powersync-service/self-hosted-instances) for more details on the config file structure.
+ * [CLI documentation](/tools/cli)
+
+
+
+
# 3. Connect PowerSync to Your Source Database
The next step is to connect your PowerSync Service instance to your source database.
-
+
In the [PowerSync Dashboard](https://dashboard.powersync.com/), select your project and instance, then go to **Database Connections**:
1. Click **Connect to Source Database**
@@ -290,34 +361,88 @@ The next step is to connect your PowerSync Service instance to your source datab
**Learn More**
-
+
For more details on database connections, including provider-specific connection details (Supabase, AWS RDS, MongoDB Atlas, etc.), see [Source Database Connection](/configuration/source-db/connection).
-
- For self-hosted setups, configure the source database connection in your `config.yaml` file (as you did in the previous step). Examples for the different database types are below.
+
+ Edit `powersync/service.yaml` (created in the previous step) with your connection details. Use `!env` for secrets:
**Note**: Use the username (e.g., `powersync_role`) and password you created in Step 1: Configure your Source Database.
- ```yaml Postgres
- replication:
- connections:
- - type: postgresql # or mongodb, mysql, mssql
- uri: postgresql://powersync_role:myhighlyrandompassword@powersync-postgres:5432/postgres # The connection URI or individual parameters can be specified.
- sslmode: disable # 'verify-full' (default) or 'verify-ca' or 'disable'
- # Note: 'disable' is only suitable for local/private networks, not for public networks
+ ```yaml Postgres
+ replication:
+ connections:
+ - type: postgresql
+ uri: postgresql://powersync_role:myhighlyrandompassword@host:5432/postgres
+ sslmode: disable # 'verify-full' (default) or 'verify-ca' or 'disable'
+ # Note: 'disable' is only suitable for local/private networks
+ ```
+
+ ```yaml MongoDB
+ replication:
+ connections:
+ - type: mongodb
+ uri: mongodb+srv://user:password@cluster.mongodb.net/database
+ post_images: auto_configure
+ ```
+
+ ```yaml MySQL
+ replication:
+ connections:
+ - type: mysql
+ uri: mysql://repl_user:password@host:3306/database
+ ```
+
+ ```yaml SQL Server
+ replication:
+ connections:
+ - type: mssql
+ uri: mssql://user:password@host:1433/database
+ schema: dbo
+ ```
+
+
+ You will run `powersync deploy` in a later step to deploy your config to the PowerSync Cloud instance.
+
+
+ **Learn More**
+
+ For more details on database connections, including provider-specific connection details (Supabase, AWS RDS, MongoDB Atlas, etc.), see [Source Database Connection](/configuration/source-db/connection).
+
+
+
+
+ If you used Docker in the previous step, the source database connection is already configured. `service.yaml` reads the connection URI from `!env PS_DATA_SOURCE_URI`. The Docker-managed Postgres (`pg-db`) was also pre-configured with `wal_level=logical` and a `powersync` publication by the init scripts.
+
+ If you want to use an **external database** instead, update `PS_DATA_SOURCE_URI` in `powersync/docker/.env` with your connection details, then restart:
+
+ ```bash
+ powersync docker reset
```
- ```yaml MongoDB
- replication:
- connections:
- - type: mongodb
- uri: mongodb+srv://user:password@cluster.mongodb.net/database
- post_images: auto_configure
+ You'll also need to complete the source database setup from Step 1 (replication user, publication) on your external database before this will work.
+
+
+
+ Configure the source database connection in your `config.yaml` file (as you did in the previous step). Examples for the different database types are below.
+
+
+ **Note**: Use the username (e.g., `powersync_role`) and password you created in Step 1: Configure your Source Database.
+
+
+
+ ```yaml Postgres
+ replication:
+ connections:
+ - type: postgresql
+ uri: postgresql://powersync_role:myhighlyrandompassword@powersync-postgres:5432/postgres
+ sslmode: disable # 'verify-full' (default) or 'verify-ca' or 'disable'
+ # Note: 'disable' is only suitable for local/private networks, not for public networks
```
```yaml MySQL
@@ -342,7 +467,7 @@ The next step is to connect your PowerSync Service instance to your source datab
**Learn More**
-
+
See the [self-host-demo app](https://github.com/powersync-ja/self-host-demo) for complete working examples of the different database types.
@@ -354,130 +479,151 @@ The next step is to connect your PowerSync Service instance to your source datab
PowerSync uses either **Sync Streams** (or legacy **Sync Rules**) to control which data gets synced to which users/devices. Both use SQL-like queries defined in YAML format.
-
+
+
+ Sync Streams are now in beta and production-ready. We recommend Sync Streams for new projects — they offer a simpler syntax and support on-demand syncing for web apps.
+
+ Start with simple **auto-subscribed streams** that sync data to all users by default:
+
+
+ ```yaml Postgres Example
+ config:
+ edition: 3
+ streams:
+ shared_data:
+ auto_subscribe: true
+ queries:
+ - SELECT * FROM todos
+ - SELECT * FROM lists WHERE NOT archived
+ ```
-Sync Streams are now in beta and production-ready. We recommend Sync Streams for new projects — they offer a simpler syntax and support on-demand syncing for web apps.
+ ```yaml MongoDB Example
+ config:
+ edition: 3
+ streams:
+ shared_data:
+ auto_subscribe: true
+ # MongoDB uses "_id" but PowerSync uses "id" on the client
+ queries:
+ - SELECT _id as id, * FROM lists
+ - SELECT _id as id, * FROM todos WHERE archived = false
+ ```
-Start with simple **auto-subscribed streams** that sync data to all users by default:
+ ```yaml MySQL Example
+ config:
+ edition: 3
+ streams:
+ shared_data:
+ auto_subscribe: true
+ queries:
+ - SELECT * FROM todos
+ - SELECT * FROM lists WHERE NOT archived
+ ```
-
-```yaml Postgres Example
-config:
- edition: 3
-streams:
- shared_data:
- auto_subscribe: true
- queries:
- - SELECT * FROM todos
- - SELECT * FROM lists WHERE NOT archived
-```
-
-```yaml MongoDB Example
-config:
- edition: 3
-streams:
- shared_data:
- auto_subscribe: true
- # MongoDB uses "_id" but PowerSync uses "id" on the client
- queries:
- - SELECT _id as id, * FROM lists
- - SELECT _id as id, * FROM todos WHERE archived = false
-```
-
-```yaml MySQL Example
-config:
- edition: 3
-streams:
- shared_data:
- auto_subscribe: true
- queries:
- - SELECT * FROM todos
- - SELECT * FROM lists WHERE NOT archived
-```
-
-```yaml SQL Server Example
-config:
- edition: 3
-streams:
- shared_data:
- auto_subscribe: true
- queries:
- - SELECT * FROM todos
- - SELECT * FROM lists WHERE NOT archived
-```
-
+ ```yaml SQL Server Example
+ config:
+ edition: 3
+ streams:
+ shared_data:
+ auto_subscribe: true
+ queries:
+ - SELECT * FROM todos
+ - SELECT * FROM lists WHERE NOT archived
+ ```
+
-**Learn more:** [Sync Streams documentation](/sync/streams/overview)
+ **Learn more:** [Sync Streams documentation](/sync/streams/overview)
-
+
-
+
-Sync Rules is the original system for controlling data sync. Use this if you prefer a fully released (non-beta) solution.
+ Sync Rules is the original system for controlling data sync. Use this if you prefer a fully released (non-beta) solution.
-
-```yaml Postgres Example
-bucket_definitions:
- global:
- data:
- - SELECT * FROM todos
- - SELECT * FROM lists WHERE archived = false
-```
-
-```yaml MongoDB Example
-bucket_definitions:
- global:
- data:
- # MongoDB uses "_id" but PowerSync uses "id" on the client
- - SELECT _id as id, * FROM lists
- - SELECT _id as id, * FROM todos WHERE archived = false
-```
-
-```yaml MySQL Example
-bucket_definitions:
- global:
- data:
- - SELECT * FROM todos
- - SELECT * FROM lists WHERE archived = 0
-```
-
-```yaml SQL Server Example
-bucket_definitions:
- global:
- data:
- - SELECT * FROM todos
- - SELECT * FROM lists WHERE archived = 0
-```
-
+
+ ```yaml Postgres Example
+ bucket_definitions:
+ global:
+ data:
+ - SELECT * FROM todos
+ - SELECT * FROM lists WHERE archived = false
+ ```
+
+ ```yaml MongoDB Example
+ bucket_definitions:
+ global:
+ data:
+ # MongoDB uses "_id" but PowerSync uses "id" on the client
+ - SELECT _id as id, * FROM lists
+ - SELECT _id as id, * FROM todos WHERE archived = false
+ ```
+
+ ```yaml MySQL Example
+ bucket_definitions:
+ global:
+ data:
+ - SELECT * FROM todos
+ - SELECT * FROM lists WHERE archived = 0
+ ```
+
+ ```yaml SQL Server Example
+ bucket_definitions:
+ global:
+ data:
+ - SELECT * FROM todos
+ - SELECT * FROM lists WHERE archived = 0
+ ```
+
-**Learn more:** [Sync Rules documentation](/sync/rules/overview)
+ **Learn more:** [Sync Rules documentation](/sync/rules/overview)
-
+
+
### Deploy Your Configuration
-
-In the [PowerSync Dashboard](https://dashboard.powersync.com/):
-
-1. Select your project and instance
-2. Go to the **Sync Streams** or **Sync Rules** view (depending on which you're using)
-3. Edit the YAML directly in the dashboard
-4. Click **Deploy** to validate and deploy
-
-
-
-Add a `sync_config` section to your `config.yaml`. Using a separate file (recommended) keeps the main config tidy:
-
-**Recommended — reference a separate file:**
-```yaml config.yaml
-sync_config:
- path: sync-config.yaml
-```
-
-Put your streams or rules in `sync-config.yaml` (see [Self-Hosted Instance Configuration](/configuration/powersync-service/self-hosted-instances#sync-streams--sync-rules) for full examples). Alternatively, you can use inline `content: |` with the YAML nested under `sync_config`.
-
+
+ In the [PowerSync Dashboard](https://dashboard.powersync.com/):
+
+ 1. Select your project and instance
+ 2. Go to the **Sync Streams** or **Sync Rules** view (depending on which you’re using)
+ 3. Edit the YAML directly in the dashboard
+ 4. Click **Deploy** to validate and deploy your Sync Rules
+
+
+
+ Edit `powersync/sync-config.yaml` with your sync config, then validate and deploy to the linked Cloud instance:
+
+ ```bash
+ powersync validate
+ powersync deploy
+ ```
+
+ This deploys your full config (connection, auth, and sync config). For subsequent sync-only changes, use `powersync deploy sync-config` instead.
+
+
+
+ Edit `powersync/sync-config.yaml` with your sync config. The default file has a placeholder (`SELECT * FROM todos`) — replace it with your actual table/collection names. Then apply the changes:
+
+ ```bash
+ powersync validate
+ powersync docker reset
+ ```
+
+
+
+ Add a `sync_config` section to your `config.yaml`. Using a separate file (recommended) keeps the main config tidy:
+
+ **Recommended — reference a separate file:**
+ ```yaml config.yaml
+ sync_config:
+ path: sync-config.yaml
+ ```
+
+ Put your streams or rules in `sync-config.yaml` (see [Self-Hosted Instance Configuration](/configuration/powersync-service/self-hosted-instances#sync-streams--sync-rules) for full examples). Alternatively, you can use inline `content: |` with the YAML nested under `sync_config`.
+
@@ -494,7 +640,7 @@ You'll use this token for two purposes:
- **Connecting your app** (in a later step) to test the client SDK integration
-
+
1. In the [PowerSync Dashboard](https://dashboard.powersync.com/), select your project and instance
2. Go to the **Client Auth** view
3. Check the **Development tokens** setting and save your changes
@@ -507,17 +653,37 @@ You'll use this token for two purposes:
-
- For self-hosted setups, you can generate development tokens using the [powersync-service test-client](https://github.com/powersync-ja/powersync-service/tree/main/test-client):
+
+ Generate a development token with:
-
+ ```bash
+ powersync generate token --subject=test-user
+ ```
-
+ Replace `test-user` with a user ID of your choice (this would normally be the user ID you want to test with).
+
+ Requires `allow_temporary_tokens` to be enabled on the instance. Add it to `powersync/service.yaml` if you haven't already, then redeploy:
+
+ ```yaml
+ client_auth:
+ allow_temporary_tokens: true
+ ```
+
+ ```bash
+ powersync deploy
+ ```
-
+
+ Development tokens expire after 12 hours.
+
-
+
+ Follow the steps below. Steps 1 and 2 configure signing keys and your PowerSync config; in Step 3 you can use the **CLI (recommended)** or the test-client to generate the token.
+
+
+
+
# 6. [Optional] Test Sync with the Sync Diagnostics Client
diff --git a/maintenance-ops/self-hosting/diagnostics.mdx b/maintenance-ops/self-hosting/diagnostics.mdx
index 1d7a076d..eb09afbc 100644
--- a/maintenance-ops/self-hosting/diagnostics.mdx
+++ b/maintenance-ops/self-hosting/diagnostics.mdx
@@ -9,6 +9,19 @@ This API provides the following diagnostic information:
- Connections → Connected backend source database and any active errors associated with the connection.
- Active Sync Streams / Sync Rules → Currently deployed Sync Streams (or legacy Sync Rules) and its status.
+## CLI
+
+If you have the [PowerSync CLI](/tools/cli) installed, use `powersync status` to check instance status without calling the API directly. This works with any running PowerSync instance — local or remote.
+
+```bash
+powersync status
+
+# Extract a specific field
+powersync status --output=json | jq '.connections[0]'
+```
+
+## Diagnostics API
+
# Configuration
1. To enable the Diagnostics API, specify an API token in your PowerSync YAML file:
diff --git a/maintenance-ops/self-hosting/overview.mdx b/maintenance-ops/self-hosting/overview.mdx
index a45fd284..b1adc3d5 100644
--- a/maintenance-ops/self-hosting/overview.mdx
+++ b/maintenance-ops/self-hosting/overview.mdx
@@ -6,6 +6,10 @@ sidebarTitle: Overview
import SelfHostDeploymentPlatformsCards from '/snippets/self-host-deployment-platforms-cards.mdx';
+
+ The [PowerSync CLI](/tools/cli) provides commands that work alongside any running self-hosted instance: `powersync status`, `powersync validate`, `powersync generate schema`, `powersync generate token`. You don't need to have set up the instance with the CLI to use these.
+
+
## Production Topics
Details for production self-hosted PowerSync deployments, including architecture/setup recommendations, security, health checks, maintenance, and monitoring.
@@ -13,7 +17,7 @@ Details for production self-hosted PowerSync deployments, including architecture
-
+
diff --git a/maintenance-ops/self-hosting/update-sync-rules.mdx b/maintenance-ops/self-hosting/update-sync-rules.mdx
index 43cef2e6..79ad63a4 100644
--- a/maintenance-ops/self-hosting/update-sync-rules.mdx
+++ b/maintenance-ops/self-hosting/update-sync-rules.mdx
@@ -1,25 +1,46 @@
---
-title: "Update Sync Streams"
-sidebarTitle: "Update Sync Streams/Rules"
+title: "Update Sync Streams (Sync Config)"
description: "How to update Sync Streams (or legacy Sync Rules) in a self-hosted PowerSync deployment"
---
-There are two ways to update Sync Streams (or legacy Sync Rules) in a self-hosted deployment:
+There are three ways to update your sync config in a self-hosted deployment:
-1. **Config file** - Update your config and restart the service
-2. **API endpoint** - Deploy at runtime without restarting
+1. **CLI** — Edit your config and apply with `powersync docker reset`
+2. **Config file** — Update your config and restart the service
+3. **API endpoint** — Deploy at runtime without restarting
- During deployment, the existing version of your Sync Streams / Sync Rules continue serving clients while the new version is processed.
- Clients seamlessly transition once [initial replication](/architecture/powersync-service#initial-replication-vs-incremental-replication)
- completes.
+ During deployment, existing Sync Streams/Sync Rules continue serving clients while new sync config processes. Clients seamlessly transition once [initial replication](/architecture/powersync-service#initial-replication-vs-incremental-replication) completes.
-## Option 1: Config File (Recommended)
+
+ Run `powersync validate` in the CLI before deploying to catch errors in your sync config without applying changes.
+
-Define Sync Streams (or legacy Sync Rules) in your `powersync.yaml` via a separate file (recommended) or inline.
+## Option 1: CLI
-See [Self-Hosted Instance Configuration](/configuration/powersync-service/self-hosted-instances) for the full config reference and [Sync Streams](/sync/streams/overview) (or legacy [Sync Rules](/sync/rules/overview)) for syntax.
+If you set up PowerSync using the CLI (`powersync docker`), update your sync config and apply it without a full service restart:
+
+
+
+ Update `powersync/sync-config.yaml` in your project directory.
+
+
+ ```bash
+ powersync validate
+ ```
+
+
+ ```bash
+ powersync docker reset
+ ```
+ This restarts the PowerSync Service and applies your updated sync config.
+
+
+
+## Option 2: Config File
+
+Define your sync config in `powersync.yaml` either inline or via a separate file. See [Self-Hosted Instance Configuration](/configuration/powersync-service/self-hosted-instances) for the full config reference.
@@ -64,13 +85,13 @@ See [Self-Hosted Instance Configuration](/configuration/powersync-service/self-h
docker compose restart powersync
```
- Once the service starts up, it will load the updated Sync Streams / Sync Rules and begin processing them while continuing to serve the existing version until initial replication completes.
+ Once the service starts up, it will load the updated sync config and begin processing it while continuing to serve the existing config until initial replication completes.
-## Option 2: Deploy via API
+## Option 3: Deploy via API
-Deploy Sync Streams (or legacy Sync Rules) at runtime without restarting. Useful for quick iterations during development.
+Deploy sync config at runtime without restarting. Useful for quick iterations during development.
The API is disabled when Sync Streams (or legacy Sync Rules) are defined in `powersync.yaml`.
diff --git a/snippets/dev-token-self-hosted-steps.mdx b/snippets/dev-token-self-hosted-steps.mdx
index 6d456fc1..61abeacf 100644
--- a/snippets/dev-token-self-hosted-steps.mdx
+++ b/snippets/dev-token-self-hosted-steps.mdx
@@ -36,8 +36,8 @@
-
- Add the `client_auth` section to your `config.yaml`:
+
+ Add the `client_auth` parameter to your PowerSync config (e.g. `service.yaml`):
@@ -80,25 +80,37 @@
- 1. If you have not done so already, clone the [`powersync-service` repo](https://github.com/powersync-ja/powersync-service/tree/main)
- 2. Install the dependencies:
- - In the project root, run the following commands:
+ Choose either the [PowerSync CLI](/tools/cli) (recommended) or the test-client:
+
+
+
+ Apply your config changes (e.g. restart your PowerSync Service or run `powersync docker reset` if running locally with Docker), then run:
+
```bash
- pnpm install
- pnpm build
+ powersync generate token --subject=test-user
```
- - In the `test-client` directory, run the following commands:
+
+ Replace `test-user` with the user ID you want to authenticate:
+ - If your Sync Streams/Rules data isn't filtered by user (same data syncs to all users), you can use any value (e.g., `test-user`).
+ - If your data is filtered by parameters, use a user ID that matches a user in your database. PowerSync uses this (e.g. `auth.user_id()` in Sync Streams or `request.user_id()` in Sync Rules) to determine what to sync.
+
+
+
+ 1. If you have not done so already, clone the [`powersync-service` repo](https://github.com/powersync-ja/powersync-service/tree/main)
+ 2. Install and build:
+ - In the project root: `pnpm install` and `pnpm build`
+ - In the `test-client` directory: `pnpm build`
+ 3. Generate a token from the `test-client` directory, pointing at your config file:
+
```bash
- pnpm build
+ node dist/bin.js generate-token --config path/to/config.yaml --sub test-user
```
- 3. Generate a new token by running the following command in the `test-client` directory with your updated `config.yaml` file:
- ```bash
- node dist/bin.js generate-token --config path/to/config.yaml --sub test-user
- ```
-
- Replace `test-user` with the user ID you want to authenticate:
- - If your Sync Streams/Rules data isn't filtered by user (same data syncs to all users), you can use any value (e.g., `test-user`).
- - If your data is filtered by parameters, use a user ID that matches a user in your database. PowerSync uses this (e.g. `auth.user_id()` in Sync Streams or `request.user_id()` in Sync Rules) to determine what to sync.
+
+ Replace `test-user` with the user ID you want to authenticate:
+ - If your Sync Streams/Rules data isn't filtered by user (same data syncs to all users), you can use any value (e.g., `test-user`).
+ - If your data is filtered by parameters, use a user ID that matches a user in your database. PowerSync uses this (e.g. `auth.user_id()` in Sync Streams or `request.user_id()` in Sync Rules) to determine what to sync.
+
+
diff --git a/tools/cli.mdx b/tools/cli.mdx
index 391c275e..759fd81b 100644
--- a/tools/cli.mdx
+++ b/tools/cli.mdx
@@ -1,69 +1,256 @@
---
-title: "CLI (Beta)"
-description: "Manage your PowerSync Cloud environment programmatically"
+title: "CLI"
+description: "Manage PowerSync Cloud and self-hosted instances from the command line."
---
-You can use the [PowerSync CLI](https://www.npmjs.com/package/powersync) to manage your PowerSync Cloud instances from your machine. Specifically, you can:
+The PowerSync CLI lets you manage PowerSync Service instances, deploy sync config (your Sync Streams or Sync Rules), generate client schemas, run diagnostics, and more. It is distributed as the [powersync](https://www.npmjs.com/package/powersync) npm package.
-* Manage your [PowerSync instances ](/architecture/powersync-service)(PowerSync Cloud)
-* Validate and deploy [Sync Rules](/sync/rules/overview) to an instance from a local file
-* Generate the [client-side schema](/intro/setup-guide#define-your-client-side-schema)
+
+ The CLI is currently in [beta](/resources/feature-status). We recommend it for new and existing projects; the 0.9.0+ design is the supported path going forward.
+
+
+**Cloud:** Full support for PowerSync Cloud. Log in with a personal access token, then define your instance config in a `powersync/` directory (`service.yaml`, `sync-config.yaml`) in your project and deploy with `powersync deploy`.
+
+**Self-hosted:** You can link to an existing PowerSync Service instance and run a subset of commands (e.g. `powersync status`, `powersync generate schema`, `powersync validate`). The CLI does not provision or deploy to a remote server; for development, you can use **Docker** to bootstrap a new self-hosted project and run a local PowerSync Service (and optional DB/storage) on your machine.
+
+
+ For a full step-by-step flow using the CLI, use the [Setup Guide](/intro/setup-guide): choose the **CLI (Cloud)** or **CLI (Self-Hosted)** tab in steps 2–5 to configure your instance, connect the source database, deploy sync config, and generate development tokens.
+
- The PowerSync CLI is not yet compatible with managing self-hosted PowerSync instances (PowerSync Open Edition and PowerSync Enterprise Self-Hosted Edition). This is on our roadmap.
+ The PowerSync CLI was overhauled in version 0.9.0. The redesign is based on this [design proposal](https://docs.google.com/document/d/1iqpJF2gog2jB-ZWeN8TBEjcad8aBKNKbue2yJ21q_-s/edit).
+
+ **Main improvements:**
+ - **Project-based config** — A `powersync/` directory in your repo holds `service.yaml` and `sync-config.yaml`, so you version and review config with your app code.
+ - **Self-hosted support** — Most commands work against any linked instance, PowerSyncCloud and self-hosted. You can also use `powersync docker configure` to scaffold a local PowerSync stack with no manual setup.
+ - **Better validation** — `powersync validate` checks your config before deploy and reports errors with line and column numbers.
+ - **Config Studio** — `powersync edit config` opens a built-in editor with schema validation, autocomplete, inline errors, and more. See the [Config Studio README](https://github.com/powersync-ja/powersync-cli/tree/main/packages/editor).
+ - **Browser login** — `powersync login` opens a browser to create or paste a PAT and stores it; in CI use `PS_ADMIN_TOKEN`.
+ - **Plugins** — npm-based plugin system ([OCLIF](https://oclif.io)); install with `powersync plugins install ` or build with `@powersync/cli-core`.
+ - **Open source** — Source and advanced docs are in the [PowerSync CLI repo](https://github.com/powersync-ja/powersync-cli).
+
+ See [Migrating from the previous CLI](#migrating-from-the-previous-cli) if you used the older flow.
-### Getting started
+## Installation
+
+Install globally or run via `npx`:
+
+```bash
+npm install -g powersync
+```
+
+```bash
+npx powersync@0.9.0 # 0.9.0 is the first version with the new CLI
+```
+
+## Authentication (Cloud)
+
+Cloud commands require a PowerSync **personal access token (PAT)**.
+
+**Interactive login (recommended for local use):**
+
+```bash
+powersync login
+```
+
+You can open a browser to [create a token in the PowerSync Dashboard](https://dashboard.powersync.com/account/access-tokens) or paste an existing token. The CLI stores the token in secure storage when available (e.g. macOS Keychain), or in a config file after confirmation.
+
+**CI and scripts:** Set the `PS_ADMIN_TOKEN` environment variable. The CLI uses `PS_ADMIN_TOKEN` when set; otherwise it uses the token from `powersync login`.
-To begin, initialize the CLI via `npx`:
+```bash
+export PS_ADMIN_TOKEN=your-personal-access-token
+powersync fetch instances --project-id=
+```
+
+To clear stored credentials: `powersync logout`.
+
+## Config files
+
+Define your instance and sync config in YAML files so you can version them in git, review changes before deploying, and run `powersync validate` before `powersync deploy`. The CLI uses a **config directory** (default `powersync/`) that holds:
+
+| File | Purpose |
+|------|---------|
+| `service.yaml` | Instance configuration: name, region, replication DB connection, client auth |
+| `sync-config.yaml` | Sync Streams (or Sync Rules) configuration |
+| `cli.yaml` | Link file (written by `powersync link`); ties this directory to an instance |
+
+All YAML files support the **`!env`** custom tag for secrets and environment-specific values, e.g. `uri: !env PS_DATABASE_URI`. Use `!env VAR::number` or `!env VAR::boolean` for typed substitution. For using one config directory across multiple instances (e.g. dev/staging/prod) via `!env` in `cli.yaml`, see the [CLI usage docs](https://github.com/powersync-ja/powersync-cli/blob/main/docs/usage.md#configuring-multiple-instances-eg-dev-staging-production).
+
+Edit these files in your IDE, then run `powersync validate` and `powersync deploy`. For better IDE support (YAML schema validation, `!env` custom tag, autocomplete), run **`powersync configure ide`**. Alternatively, use **Config Studio**: run **`powersync edit config`** to open a built-in web editor that edits `service.yaml` and `sync-config.yaml` with schema-aware validation, autocomplete, and inline sync config errors. The editor writes changes back to your config directory. See the [Config Studio README](https://github.com/powersync-ja/powersync-cli/tree/main/packages/editor) for details.
+
+
+ **Cloud secrets:** For Cloud `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 without re-supplying it. See the [CLI README](https://github.com/powersync-ja/powersync-cli#cloud-secrets-format-serviceyaml) for details.
+
+
+## Cloud workflows
+
+### Create a new instance
```bash
-npx powersync init
+# Step 1: Log in and scaffold the config directory
+powersync login
+powersync init cloud
+
+# Step 2: Edit powersync/service.yaml (name, region, replication, auth) and sync config in sync-config.yaml; use !env for secrets
+
+# Step 3: Create a new Cloud instance from your config and save its ID to cli.yaml
+powersync link cloud --create --project-id=
+# If your token has multiple orgs: add --org-id=
+
+# Step 4: Validate your config and deploy it to the new Cloud instance
+powersync validate
+powersync deploy
+```
+
+Use `--directory=` for a different config folder (e.g. `--directory=powersync-prod`).
+
+### Use an existing instance (pull config)
+
+For an instance that already exists (e.g. created in the Dashboard), pull its config into a local directory:
+
+```bash
+powersync login
+powersync pull instance --project-id= --instance-id=
+# Edit powersync/service.yaml and powersync/sync-config.yaml as needed
+powersync validate
+powersync deploy
```
-### Personal Access Token
+This creates the config directory, writes `cli.yaml`, and downloads `service.yaml` and `sync-config.yaml`. Run `powersync pull instance` again (without IDs if already linked) to refresh local config from the cloud.
+
+### Run commands without local config
+
+You can run commands (e.g. `powersync generate schema`, `powersync generate token`, `powersync status`) against an instance whose config is managed elsewhere (e.g. the Dashboard). Either link once with `powersync link cloud --instance-id= --project-id=`, or pass `--instance-id` and `--project-id` (and `--org-id` when your token has multiple orgs) on each command. You can also set `INSTANCE_ID`, `PROJECT_ID`, and optionally `ORG_ID` in the environment. For how the CLI resolves context (flags vs environment variables vs `cli.yaml`), and for multiple instances (e.g. dev/staging/prod with separate directories or `!env`), see the [CLI usage docs](https://github.com/powersync-ja/powersync-cli/blob/main/docs/usage.md#supplying-linking-information-for-cloud-and-self-hosted-commands) in the PowerSync CLI repository.
+
+## Self-hosted workflows
+
+Run **`powersync init self-hosted`** to scaffold a config directory. Edit `service.yaml` with your instance details (including `api.tokens` for API key auth) and use **`powersync link self-hosted --api-url `** to link to an existing running PowerSync Service. The link writes `cli.yaml`; set **`api_key`** in `cli.yaml` (e.g. `api_key: !env PS_ADMIN_TOKEN`) or set the **`PS_ADMIN_TOKEN`** environment variable so the CLI can authenticate. When using Docker (see below), **`powersync docker configure`** links to the local API automatically. The CLI does not create or deploy to self-hosted instances; you manage the server and its config yourself.
+
+Supported self-hosted commands include: `powersync status`, `powersync generate schema`, `powersync generate token`, `powersync validate`, and `powersync fetch instances` (lists linked instances by scanning the current directory for folders with `cli.yaml`). Cloud-only commands (`powersync deploy`, `powersync pull instance`, `powersync fetch config`, `powersync destroy`, `powersync stop`, etc.) do not apply.
+
+### Docker (local development)
+
+The CLI can start a PowerSync Service via **Docker**: it runs the service (and optionally a source database and bucket storage) in containers on your machine. That gives you a real API to develop against without deploying to any server.
```bash
-npx powersync init
+powersync init self-hosted
+powersync docker configure
+powersync docker start
+```
+
+**`powersync docker configure`** links to the local API automatically. After `powersync docker start`, use the same commands as for any self-hosted instance (`powersync status`, `powersync generate schema`, etc.). Use **`powersync docker stop`** to stop the stack (add `--remove` to remove containers, `--remove-volumes` to reset so init scripts run again on next start). Use **`powersync docker reset`** when you need a clean state (stop and remove, then start). For the full workflow, flags (`--database`, `--storage`, `--remove`, `--remove-volumes`), and how the Docker setup uses templates and init scripts, see the [Docker usage docs](https://github.com/powersync-ja/powersync-cli/blob/main/docs/usage-docker.md) in the PowerSync CLI repository. You can also run `powersync docker --help` for command options.
+
+## Common commands
+
+| Command | Description |
+|---------|-------------|
+| `powersync login` | Store PAT for Cloud (interactive or paste token) |
+| `powersync logout` | Remove stored token |
+| `powersync init cloud` | Scaffold Cloud config directory |
+| `powersync init self-hosted` | Scaffold self-hosted config directory |
+| `powersync configure ide` | Configure IDE for YAML schema validation and `!env` support |
+| `powersync link cloud --project-id=` | Link to an existing Cloud instance |
+| `powersync link cloud --create --project-id=` | Create a new Cloud instance and link |
+| `powersync link self-hosted --api-url=` | Link to a self-hosted instance by API URL |
+| `powersync pull instance --project-id= --instance-id=` | Download Cloud config into local files |
+| `powersync deploy` | Deploy full config to linked Cloud instance |
+| `powersync deploy service-config` | Deploy only service config (no sync config) |
+| `powersync deploy sync-config` | Deploy only sync config (optional `--sync-config-file-path`) |
+| `powersync validate` | Validate config and sync rules/streams |
+| `powersync edit config` | Open Config Studio (Monaco editor for service.yaml and sync-config.yaml) |
+| `powersync migrate sync-rules` | Migrate Sync Rules to Sync Streams |
+| `powersync fetch instances` | List Cloud and linked instances (optionally by project/org) |
+| `powersync fetch config` | Print linked Cloud instance config (YAML/JSON) |
+| `powersync status` | Instance diagnostics (connections, replication); Cloud and self-hosted |
+| `powersync generate schema --output=ts --output-path=schema.ts` | Generate client-side schema |
+| `powersync generate token --subject=user-123` | Generate a development JWT |
+| `powersync destroy --confirm=yes` | [Cloud only] Permanently destroy the linked instance |
+| `powersync stop --confirm=yes` | [Cloud only] Stop the linked instance (restart with deploy) |
+
+For full usage and flags, run `powersync --help` or `powersync --help`. A complete [command reference](https://github.com/powersync-ja/powersync-cli/blob/main/cli/README.md#commands) is available in the PowerSync CLI repository; see also the [powersync npm package](https://www.npmjs.com/package/powersync).
+
+## Deploying from CI (e.g. GitHub Actions)
+
+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` and `PROJECT_ID` (and `ORG_ID` only if your token has multiple organizations). For self-hosted, `API_URL` can specify the PowerSync API base URL.
+
+
+ Example: deploy sync config on push to main
+
+
+
+## Migrating from the previous CLI
-? Enter your API token: [hidden]
+If you used the older PowerSync CLI (e.g. `npx powersync init` to set token and org/project, then `powersync instance set`, `powersync instance deploy`, etc.), the new CLI uses a different flow. Version 0.9.0 and above are **not backwards compatible** with 0.8.0. If you are not ready to migrate, you can stay on the old CLI:
+
+```bash
+npm install -g @powersync/cli@0.8.0
```
-You need to provide an access (API) token to initialize the CLI. These can be created in your [Account Settings](https://dashboard.powersync.com/account/access-tokens) in the PowerSync Dashboard.
+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 --project-id=... --instance-id=...`** to pull an existing instance. |
+| `powersync instance set --instanceId=` | **`powersync link cloud --instance-id= --project-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 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 | Pass **`--org-id`** and **`--project-id`** when needed, or use **`powersync link cloud`** so they are stored in **`powersync/cli.yaml`**. For CI, use env vars: **`PS_ADMIN_TOKEN`**, **`INSTANCE_ID`**, **`PROJECT_ID`**, **`ORG_ID`** (optional). |
+
+**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). |
+
+## Known issues and limitations
-Here you can also revoke access by deleting the token.
+- When secure storage is unavailable, `powersync login` may store the token in a plaintext config file after explicit confirmation.
+- Self-hosted: the CLI does not create or manage instances on your server, or deploy config to it; it only links to an existing API and runs a subset of commands (status, generate schema/token, validate). The sole exception is **Docker**: it starts a local PowerSync Service (and optional DB/storage) in containers on your machine for development — not a remote or production instance.
+- Some validation checks require a connected instance to complete successfully; validation of an unprovisioned instance may show errors that resolve after the first deployment.
-### Usage
+## Reference
-For more information on the CLI's available commands, please refer to:
-npm
+ Package and version history
-### Deploying Sync Rules with GitHub Actions
-
-You can automate Sync Rule deployments using the PowerSync CLI in your CI/CD pipeline. This is useful for ensuring your Sync Rules are automatically deployed whenever changes are pushed to a repository.
+
+ Create or revoke tokens in the PowerSync Dashboard
+
-See a complete example of deploying Sync Rules with GitHub Actions
+ Source code, usage docs, Docker usage, and examples
-
-The example repository demonstrates how to:
-* Set up a GitHub Actions workflow to deploy Sync Rules on push to the `main` branch
-* Configure required repository secrets (`POWERSYNC_AUTH_TOKEN`, `POWERSYNC_INSTANCE_ID`, `POWERSYNC_PROJECT_ID`, `POWERSYNC_ORG_ID`)
-* Automatically deploy `sync-rules.yaml` changes
-
-### Known issues and limitations
-
-* Certificates cannot currently be managed from the CLI.
-* The PowerSync CLI is not yet compatible with managing self-hosted PowerSync instances (PowerSync Open Edition and PowerSync Enterprise Self-Hosted Edition). This is on our roadmap.
diff --git a/tools/local-development.mdx b/tools/local-development.mdx
index c570bc77..1b349b6f 100644
--- a/tools/local-development.mdx
+++ b/tools/local-development.mdx
@@ -1,19 +1,28 @@
---
title: "Local Development"
-description: "Using Docker Compose to self-host PowerSync for development purposes."
+description: "Getting started with self-hosted PowerSync on your development machine."
---
-It's possible to host the full PowerSync Service stack on your development machine using pure Docker, but Docker Compose can simplify things.
+The easiest way to run PowerSync locally is with the [PowerSync CLI](/tools/cli), which scaffolds and manages a Docker Compose stack for you.
-Below is a minimal Docker Compose setup for self-hosting PowerSync on your development machine. Note that Docker Compose is primarily designed for development and testing environments.
+See the [Setup Guide](/intro/setup-guide) for step-by-step CLI instructions: `powersync init self-hosted` + `powersync docker configure` + `powersync docker start`.
-1. Create a new folder to work in:
+If you'd prefer to write your own Docker Compose setup, here's a minimal example.
+
+## Docker Compose Example
+
+Create a working directory with three files:
-```bash
-mkdir powersync-service && cd powersync-service
```
+powersync/
+ docker-compose.yaml
+ service.yaml
+ sync-config.yaml
+```
+
+### `docker-compose.yaml`
-1. Create a `docker-compose.yml` file with the below contents:
+This example uses Postgres as the source database and MongoDB as bucket storage. Postgres is also supported as bucket storage — see [Self-Hosted Instance Configuration](/configuration/powersync-service/self-hosted-instances) for details.
```yaml
services:
@@ -22,17 +31,19 @@ services:
depends_on:
mongo-rs-init:
condition: service_completed_successfully
- postgres: # This is not required, but is nice to have
+ postgres:
condition: service_healthy
image: journeyapps/powersync-service:latest
command: ["start", "-r", "unified"]
volumes:
- - ./config/config.yaml:/config/config.yaml
+ - ./service.yaml:/config/service.yaml
+ - ./sync-config.yaml:/config/sync-config.yaml
environment:
- POWERSYNC_CONFIG_PATH: /config/config.yaml
+ POWERSYNC_CONFIG_PATH: /config/service.yaml
ports:
- 8080:8080
+ # Source database (Postgres with logical replication enabled)
postgres:
image: postgres:latest
restart: always
@@ -52,7 +63,7 @@ services:
timeout: 5s
retries: 5
- # MongoDB Service used internally
+ # MongoDB used internally for bucket storage
mongo:
image: mongo:7.0
command: --replSet rs0 --bind_ip_all --quiet
@@ -61,7 +72,8 @@ services:
- 27017:27017
volumes:
- mongo_storage:/data/db
- # Initializes the MongoDB replica set. This service will not usually be actively running
+
+ # Initializes the MongoDB replica set. This service will not usually be actively running
mongo-rs-init:
image: mongo:7.0
depends_on:
@@ -75,85 +87,76 @@ services:
volumes:
mongo_storage:
pg_data:
-
```
-1. Create a config volume that contains a `config.yaml` file, this configures the PowerSync Service itself
+### `service.yaml`
-```bash
-mkdir config && cd config
-```
-
-Put the below into `/config/config.yaml` :
+The main PowerSync Service configuration. See [Self-Hosted Instance Configuration](/configuration/powersync-service/self-hosted-instances) for the full reference.
```yaml
+# Source database connection
replication:
connections:
- type: postgresql
uri: postgresql://postgres:postgres@postgres:5432/postgres
+ sslmode: disable # verify-full, verify-ca, or disable
- # SSL settings
- sslmode: disable # 'verify-full' (default) or 'verify-ca' or 'disable'
-
-# Connection settings for bucket storage
+# Bucket storage (MongoDB shown; Postgres is also supported)
storage:
type: mongodb
- uri: mongodb://mongo:27017/powersync_demo
+ uri: mongodb://mongo:27017/powersync_storage
# The port which the PowerSync API server will listen on
port: 8080
-# Specify sync config (Sync Streams recommended for new projects)
+# Points to the sync config file
sync_config:
- content: |
- config:
- edition: 3
- streams:
- shared_data:
- auto_subscribe: true
- queries:
- - SELECT * FROM lists
- - SELECT * FROM todos
+ path: sync-config.yaml
# Settings for client authentication
client_auth:
# Enable this if using Supabase Auth
supabase: false
-
- # JWKS URIs can be specified here.
- jwks_uri: [TODO]
+ # Or enter a static collection of public keys for JWT verification, and generate a development token using the CLI (`powersync generate token`)
+ # jwks:
+ # keys:
+ # - kty: 'RSA'
+ # n: '[rsa-modulus]'
+ # e: '[rsa-exponent]'
+ # alg: 'RS256'
+ # kid: '[key-id]'
# JWKS audience
- audience: ['powersync-dev', 'powersync']
-
- # Settings for telemetry reporting
- # See https://docs.powersync.com/self-hosting/telemetry
- telemetry:
- # Opt out of reporting anonymized usage metrics to PowerSync telemetry service
- disable_telemetry_sharing: false
+ # audience: ['powersync-dev', 'powersync', 'http://localhost:8080']
```
-For some additional details on this file, see [Service Configuration](/configuration/powersync-service/self-hosted-instances).
-
-Next, the `client_auth` sections needs to be completed.
+### `sync-config.yaml`
-The PowerSync Service can verify JWTs from client applications using either HMAC (HS\*) or RSA (RS\*) based algorithms. It can also obtain the necessary settings from Supabase automatically if you are using it.
+Defines what data syncs to clients. See [Sync Streams](/sync/streams/overview) for full syntax.
-1. In the case of Supabase, simply set the `supabase` key to `true`
-2. In the case of HS\* algorithms, specify the secret as base64 encoded in the `k` field.
-3. In the case of RS\* based algorithms, the public key(s) can be specified either by supplying a JWKS URI or hard coding the public key in the config file.
- 1. If using a JWKS URI, we have an example endpoint available [here](https://hlstmcktecziostiaplz.supabase.co/functions/v1/powersync-jwks); ensure that your response looks similar.
- 2. If hardcoding, see the syntax below. We also have an example [key generator](https://github.com/powersync-ja/self-host-demo/tree/main/key-generator) script.
+```yaml
+config:
+ edition: 3
+
+streams:
+ global:
+ # Streams without parameters sync the same data to all users
+ auto_subscribe: true
+ queries:
+ - SELECT * FROM todos
+ - SELECT * FROM lists
+```
-example of hard coded HS256 config
+### Start the stack
-```yaml
-client_auth:
- jwks:
- keys:
- - kty: 'RSA'
- n: 't-3d9e6XGtVsDB49CxVPn6P4OK6ir-wHP0CtTTq3VK6ofz2TWNrcHbCks6MszyWuBN1qb1ir_qudwwIeS69InEFm9WOYG1jIp6OBUNY4LPvkWfhSqcU6BasRAkYllC65CnSiVuTs4TlVgE-CBZQwQCvyrYgQgczC-GnI2HEB2SGTnXnBTXmAFEAd7xh_IROURZm1C6RnD2fXmiR1PxJsBn1w2hWYk0L8rQPlkthXwHNKd964rDir2qSTzVaHVvrFaxKiTlTe8uP4PR6OZT4pE0NDI2KNkyPauIeXp8HrwpZiUd8Znc8LQ-mj-hxfxtynYhxvcd6O_jyxa_41wjPeeQ'
- e: 'AQAB'
- alg: 'RS256'
- kid: 'powersync-0abb8a873a'
+```bash
+docker compose up
```
+
+## Resources
+
+- [PowerSync CLI](https://github.com/powersync-ja/powersync-cli) — open source CLI; use it to scaffold and run a Docker-based local stack
+- [self-host-demo](https://github.com/powersync-ja/self-host-demo) — complete working examples with Docker Compose
+- [Self-Hosted Instance Configuration](/configuration/powersync-service/self-hosted-instances) — full `service.yaml` reference
+- [Sync Streams](/sync/streams/overview) — sync config syntax
+- [Generate a Development Token](/intro/setup-guide#5-generate-a-development-token) — for testing without a full auth setup
diff --git a/tools/overview.mdx b/tools/overview.mdx
index ef6aae05..c54334df 100644
--- a/tools/overview.mdx
+++ b/tools/overview.mdx
@@ -8,8 +8,8 @@ sidebarTitle: Overview
Dashboard for PowerSync Cloud. Allows managing your PowerSync organization, projects and instances.
-
- Manage your PowerSync Cloud instances from the command line.
+
+ Manage PowerSync Cloud and self-hosted instances from the command line.
Web app to inspect and debug syncing. Works with both cloud and self-hosted PowerSync Service instances.