|
| 1 | +# note. |
| 2 | + |
| 3 | +This project demonstrates how to build a note-taking application using Neon's Data API (powered by PostgREST), Neon Auth for authentication and PowerSync for real-time updates and offline support. Instead of using traditional database access via a backend, or even a backend at all, this demo showcases how to leverage PowerSync for SQLite queries of replicated Postgres data with a very elegant JS SDK. |
| 4 | + |
| 5 | +**Note:** this demo was forked from [neon-data-api-neon-auth](https://github.com/neondatabase-labs/neon-data-api-neon-auth) to provide Neon users with a migration example of how to add PowerSync to an existing Neon project. This README provides only basic instructions for setting up the demo. Please refer to the [PowerSync / Neon integration guide](https://docs.powersync.com/integration-guides/neon-+-powersync) for more complete instructions. |
| 6 | + |
| 7 | +**PowerSync JS SDK** |
| 8 | + |
| 9 | +- SQLite queries of replicated dynamic subsets of Postgres data |
| 10 | +- Real-time updates and offline support |
| 11 | +- ORM support |
| 12 | + |
| 13 | +**Neon Data API (PostgREST-compatible)** |
| 14 | + |
| 15 | +- Instant REST API for your Postgres database |
| 16 | +- Built-in filtering, pagination, and relationships |
| 17 | +- Automatic OpenAPI documentation |
| 18 | + |
| 19 | +This demo is built with: |
| 20 | + |
| 21 | +- [Neon](https://neon.tech) — Serverless Postgres |
| 22 | +- [Neon Auth](https://neon.com/docs/auth/overview) — Authentication with automatic JWT integration |
| 23 | +- [Neon Data API](https://neon.com/docs/data-api/get-started) — Direct database access from the frontend, used for sending client mutations (that PowerSync queues in SQLite) to the backend |
| 24 | +- [PowerSync Cloud](https://powersync.com) — Backend DB to SQLite Sync Engine |
| 25 | +- [PowerSync JS SDK](https://powersync.com/docs/js-sdk/get-started) — Client SQLite interface to synced data |
| 26 | +- [PowerSync TanStack Query](https://docs.powersync.com/client-sdk-references/javascript-web/javascript-spa-frameworks#tanstack-query) — Brings TanStack’s advanced asynchronous state management features to the PowerSync JS SDK |
| 27 | +- [PowerSync Drizzle Driver](https://docs.powersync.com/client-sdk-references/javascript-web/javascript-orm/drizzle) - ORM driver for Drizzle |
| 28 | + |
| 29 | +## Prerequisites |
| 30 | + |
| 31 | +Before you begin, ensure you have: |
| 32 | + |
| 33 | +- [pnpm](https://pnpm.io/) (v9.0 or newer) installed |
| 34 | +- A [Neon account](https://console.neon.tech/signup) (free tier works) |
| 35 | +- A [PowerSync account](https://powersync.com) (free tier works, self hosting also available) |
| 36 | + |
| 37 | +## Getting Started |
| 38 | + |
| 39 | +### 1. Create a Neon Project with Auth and Data API |
| 40 | + |
| 41 | +1. Go to [pg.new](https://pg.new) to create a new Neon project |
| 42 | +2. In the Neon Console, navigate to your project and enable: |
| 43 | + - **Neon Auth** — Go to the **Auth** page in the left sidebar and follow the setup wizard |
| 44 | + - **Data API** — Go to the **Data API** page in the left sidebar and enable it |
| 45 | + |
| 46 | +For detailed instructions, see: |
| 47 | + |
| 48 | +- [Getting started with Neon Auth](https://neon.com/docs/auth/overview) |
| 49 | +- [Getting started with Data API](https://neon.com/docs/data-api/get-started) |
| 50 | + |
| 51 | +### 2. Clone and Install |
| 52 | + |
| 53 | +```bash |
| 54 | +git clone https://github.com/powersync-ja/powersync-js.git |
| 55 | +cd powersync-js |
| 56 | +pnpm install |
| 57 | +pnpm build:packages |
| 58 | +cd demos/react-neon-tanstack-query-notes |
| 59 | +``` |
| 60 | + |
| 61 | +### 3. Configure Environment Variables |
| 62 | + |
| 63 | +Create a `.env` file in the project root: |
| 64 | + |
| 65 | +```env |
| 66 | +# Neon Data API URL |
| 67 | +# Find this in Neon Console → Data API page → "Data API URL" |
| 68 | +VITE_NEON_DATA_API_URL=https://your-project-id.data-api.neon.tech |
| 69 | +
|
| 70 | +# Neon Auth Base URL |
| 71 | +# Find this in Neon Console → Auth page → "Auth Base URL" |
| 72 | +# Note this comment: https://github.com/neondatabase/neon-data-api-neon-auth/pull/10#discussion_r2614978813 |
| 73 | +VITE_NEON_AUTH_URL=https://your-project-id.auth.neon.tech |
| 74 | +
|
| 75 | +# Database Connection String (for migrations) |
| 76 | +# Find this in Neon Console → Dashboard → Connection string (select "Pooled connection") |
| 77 | +DATABASE_URL=postgresql://user:password@your-project-id.pooler.region.neon.tech/neondb?sslmode=require |
| 78 | +
|
| 79 | +####### PowerSync Config ########## |
| 80 | +# PowerSync instance URL, for PowerSync Cloud obtain from dashboard otherwise url of your self-hosted PowerSync Service |
| 81 | +VITE_POWERSYNC_URL=https://foo.powersync.journeyapps.com |
| 82 | +``` |
| 83 | + |
| 84 | +### 4. Set Up the Database |
| 85 | + |
| 86 | +Run the migration to create the tables and RLS policies: |
| 87 | + |
| 88 | +```bash |
| 89 | +pnpm db:migrate |
| 90 | +``` |
| 91 | + |
| 92 | +This will: |
| 93 | + |
| 94 | +- Grant appropriate permissions to the `authenticated` and `anonymous` database roles |
| 95 | +- Create the `notes` and `paragraphs` tables with RLS policies |
| 96 | + |
| 97 | +### 5. Configure logical replication for PowerSync |
| 98 | + |
| 99 | +PowerSync uses logical replication to sync data from your Neon project to your PowerSync instance, which is then synced to your SQLite database in the client. To configure logical replication follow the instructions in the [PowerSync documentation](https://docs.powersync.com/installation/database-setup#neon). |
| 100 | + |
| 101 | +### 6. Connect PowerSync to your Neon project |
| 102 | + |
| 103 | +In the PowerSync dashboard, create a project, an instance and then create a database connection to your Neon database using the credentials from the "Connect" button in the Neon Console. |
| 104 | + |
| 105 | +### 7. Configure PowerSync auth and Sync Rules |
| 106 | + |
| 107 | +### Auth |
| 108 | + |
| 109 | +Navigate to "Client Auth" in the PowerSync dashboard and configure: |
| 110 | + |
| 111 | +- Select "Enable development tokens" |
| 112 | +- Populate the "JWKS URI" with the value from the "JWKS URL" field in the Neon Console → Auth page |
| 113 | +- Populate the "JWT Audience" with your project root URL (e.g., `https://ep-restless-resonance-adom1z4w.neonauth.c-2.us-east-1.aws.neon.tech/`) |
| 114 | + |
| 115 | +### Sync Rules |
| 116 | + |
| 117 | +Navigate to "Sync Rules" in the PowerSync dashboard and configure these sync rules: |
| 118 | + |
| 119 | +```yaml |
| 120 | +config: |
| 121 | + edition: 2 |
| 122 | + |
| 123 | +bucket_definitions: |
| 124 | + by_user: |
| 125 | + # Only sync rows belonging to the user |
| 126 | + parameters: SELECT id as note_id FROM notes WHERE owner_id = request.user_id() |
| 127 | + data: |
| 128 | + - SELECT * FROM notes WHERE id = bucket.note_id |
| 129 | + - SELECT * FROM paragraphs WHERE note_id = bucket.note_id |
| 130 | + # Sync all shared notes to all users (not recommended for production) |
| 131 | + shared_notes: |
| 132 | + parameters: SELECT id as note_id from notes where shared = TRUE |
| 133 | + data: |
| 134 | + - SELECT * FROM notes WHERE id = bucket.note_id |
| 135 | + - SELECT * FROM paragraphs WHERE note_id = bucket.note_id |
| 136 | +``` |
| 137 | +
|
| 138 | +### 8. Test Sync |
| 139 | +
|
| 140 | +You can use the Sync Test to validate your Sync Rules, but since your app won't have any data at this point yet, you can skip this step for now. |
| 141 | +
|
| 142 | +Click on "Sync Test" test in the PowerSync dashboard, and enter the UUID of a user in your Neon Auth database to generate a test JWT. Then, click "Launch Sync Diagnostics Client" to test the sync rules. |
| 143 | +
|
| 144 | +### 9. Start the Development Server |
| 145 | +
|
| 146 | +```bash |
| 147 | +pnpm dev |
| 148 | +``` |
| 149 | + |
| 150 | +Open [http://localhost:5173](http://localhost:5173) in your browser. |
| 151 | + |
| 152 | +## Deployment on Vercel |
| 153 | + |
| 154 | +### 1. Push to GitHub |
| 155 | + |
| 156 | +If you haven't already, push your code to a GitHub repository: |
| 157 | + |
| 158 | +```bash |
| 159 | +git init |
| 160 | +git add . |
| 161 | +git commit -m "Initial commit" |
| 162 | +git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPO.git |
| 163 | +git push -u origin main |
| 164 | +``` |
| 165 | + |
| 166 | +### 2. Import Project in Vercel |
| 167 | + |
| 168 | +1. Go to [vercel.com](https://vercel.com) and sign in (or create an account) |
| 169 | +2. Click **"Add New..."** → **"Project"** |
| 170 | +3. Select **"Import Git Repository"** and choose your repository |
| 171 | +4. Vercel will auto-detect the Vite framework |
| 172 | + |
| 173 | +### 3. Configure Environment Variables |
| 174 | + |
| 175 | +In the Vercel project settings, add these environment variables: |
| 176 | + |
| 177 | +| Variable | Value | Where to find it | |
| 178 | +| ------------------------ | -------------------------------------------- | ----------------------------- | |
| 179 | +| `VITE_NEON_DATA_API_URL` | `https://your-project-id.data-api.neon.tech` | Neon Console → Data API page | |
| 180 | +| `VITE_NEON_AUTH_URL` | `https://your-project-id.auth.neon.tech` | Neon Console → Auth page | |
| 181 | +| `VITE_POWERSYNC_URL` | `https://foo.powersync.journeyapps.com` | PowerSync Dashboard → Connect | |
| 182 | + |
| 183 | +> **Note:** You don't need `DATABASE_URL` on Vercel — migrations are run locally during development. |
| 184 | +
|
| 185 | +### 4. Deploy |
| 186 | + |
| 187 | +Click **"Deploy"** and wait for the build to complete. Your app will be live at `your-project.vercel.app`. |
| 188 | + |
| 189 | +### 5. Update Allowed Origins (Important!) |
| 190 | + |
| 191 | +After deployment, update your Neon Auth settings to allow your Vercel domain: |
| 192 | + |
| 193 | +1. Go to Neon Console → Auth page |
| 194 | +2. Add your Vercel URL (e.g., `https://your-project.vercel.app`) to the allowed origins |
| 195 | + |
| 196 | +## Development Notes |
| 197 | + |
| 198 | +### Schema Changes |
| 199 | + |
| 200 | +If you modify `src/db/schema.ts`, generate new migrations with: |
| 201 | + |
| 202 | +```bash |
| 203 | +pnpm db:generate |
| 204 | +pnpm db:migrate |
| 205 | +``` |
| 206 | + |
| 207 | +The `db:generate` command creates SQL migration files in the `/drizzle` folder based on your schema changes. You only need this when changing the database schema. |
| 208 | + |
| 209 | +## Learn More |
| 210 | + |
| 211 | +- [Neon Data API Documentation](https://neon.com/docs/data-api/get-started) |
| 212 | +- [Neon Data API Tutorial](https://neon.com/docs/data-api/demo) |
| 213 | +- [Neon Auth Documentation](https://neon.com/docs/auth/overview) |
| 214 | +- [PowerSync Documentation](https://docs.powersync.com) |
0 commit comments