Skip to content

Commit e1ff4fd

Browse files
authored
Merge pull request #801 from powersync-ja/neon-demo
Add Neon data API and Neon Auth demo
2 parents c438980 + df2a7f5 commit e1ff4fd

45 files changed

Lines changed: 10491 additions & 756 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.prettierignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@
1212
**/assets/**
1313
**/bin/**
1414
**/ios/**
15+
**/coverage/**
16+
**/routeTree.gen.ts
1517

1618
pnpm-lock.yaml
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# NEON_DATA_API_URL, required, the URL of your Neon Data API
2+
VITE_NEON_DATA_API_URL=https://data-api-url
3+
# NEON_AUTH_URL, required, your Neon Auth URL
4+
VITE_NEON_AUTH_URL=https://neon-auth-url
5+
6+
# DATABASE_URL, optional, only if you want to run drizzle migrations with bun db:migrate
7+
DATABASE_URL=your-database-url
8+
9+
10+
# PowerSync instance URL, for PowerSync Cloud obtain from dashboard. Otherwise, the URL of your self-hosted PowerSync Service
11+
VITE_POWERSYNC_URL=https://foo.powersync.journeyapps.com
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?
25+
26+
# Environment variables
27+
.env
28+
.env.local
29+
.env.development
30+
.env.production
31+
32+
# Ignored by parent .gitignore
33+
!src/lib
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
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)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "new-york",
4+
"rsc": false,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "",
8+
"css": "src/index.css",
9+
"baseColor": "neutral",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils",
16+
"ui": "@/components/ui",
17+
"lib": "@/lib",
18+
"hooks": "@/hooks"
19+
},
20+
"iconLibrary": "lucide"
21+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import 'dotenv/config';
2+
import { defineConfig } from 'drizzle-kit';
3+
4+
export default defineConfig({
5+
out: './drizzle',
6+
schema: './src/db/schema.ts',
7+
dialect: 'postgresql',
8+
dbCredentials: {
9+
url: process.env.DATABASE_URL!
10+
}
11+
});

0 commit comments

Comments
 (0)