https://github.com/cap-go/capacitor-supabase
Native Supabase authentication, JWT access, and basic database helpers for Capacitor.
https://github.com/cap-go/capacitor-supabase
capacitor capacitor-plugin
Last synced: 11 days ago
JSON representation
Native Supabase authentication, JWT access, and basic database helpers for Capacitor.
- Host: GitHub
- URL: https://github.com/cap-go/capacitor-supabase
- Owner: Cap-go
- License: mpl-2.0
- Created: 2025-11-29T02:36:13.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2026-06-15T23:03:49.000Z (12 days ago)
- Last Synced: 2026-06-16T00:11:09.508Z (11 days ago)
- Topics: capacitor, capacitor-plugin
- Language: Swift
- Homepage: https://github.com/Cap-go/capacitor-supabase
- Size: 813 KB
- Stars: 7
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
Native Supabase SDK integration for Capacitor - Auth, Database, and JWT access.
## Why Capacitor Supabase?
A native Supabase SDK integration that provides **real native authentication** with JWT token access for your Capacitor apps:
- **Native SDK integration** - Full access to Supabase's native iOS and Android SDKs
- **JWT token access** - Get JWT tokens from native auth for use in JavaScript/web layers
- **Complete auth methods** - Email/password, OAuth, OTP, magic links, and more
- **Session management** - Native session handling with automatic token refresh
- **Database operations** - Native CRUD operations for Supabase tables
- **Auth state listeners** - Real-time auth state change events
- **Hybrid approach** - Use native auth with supabase-js for database queries
- **Free and open source** - No paid services required
Perfect for apps that need secure native authentication while leveraging Supabase's powerful backend services.
**Why only Auth and basic DB operations?** The Supabase JS SDK already works great in Capacitor for most features (Realtime, Storage, Edge Functions, etc.). Building native bridges for every feature would add complexity without real benefits. This plugin focuses on **authentication** where native SDKs provide actual value (secure token storage, OAuth flows, biometrics). For everything else, just use `@supabase/supabase-js` with the JWT from native auth.
**Why not bridge everything natively?**
- **No performance gain** - The bridge overhead (JSON serialization/deserialization between JS and native) negates any benefit from skipping HTTP preflight requests. You're just moving the transformation cost from network to CPU.
- **Type safety issue** - Native SDKs require typed models for every table/query. You'd need to define Swift/Kotlin types for your entire database schema and keep them in sync. With JS, you get dynamic typing that just works.
- **Maintenance burden** - Every Supabase SDK update would require updating 3 codebases (JS, iOS, Android) instead of just one. The JS SDK is already well-maintained by Supabase.
## Documentation
The most complete doc is available here: https://capgo.app/docs/plugins/supabase/
## Compatibility
| Plugin version | Capacitor compatibility | Maintained |
| -------------- | ----------------------- | ---------- |
| v8.\*.\* | v8.\*.\* | ✅ |
| v7.\*.\* | v7.\*.\* | On demand |
| v6.\*.\* | v6.\*.\* | ❌ |
| v5.\*.\* | v5.\*.\* | ❌ |
> **Note:** The major version of this plugin follows the major version of Capacitor. Use the version that matches your Capacitor installation (e.g., plugin v8 for Capacitor 8). Only the latest major version is actively maintained.
## Install
```bash
npm install @capgo/capacitor-supabase
npx cap sync
```
## iOS Setup
No additional setup required. The plugin uses Swift Package Manager to include the Supabase Swift SDK.
## Android Setup
The plugin requires a minimum SDK of 26 (Android 8.0). Make sure your `android/variables.gradle` has:
```gradle
minSdkVersion = 26
```
## Usage
### Initialize the Client
```typescript
import { CapacitorSupabase } from '@capgo/capacitor-supabase';
await CapacitorSupabase.initialize({
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key'
});
```
### Authentication
#### Sign In with Email/Password
```typescript
const { session, user } = await CapacitorSupabase.signInWithPassword({
email: 'user@example.com',
password: 'password123'
});
// Access the JWT token
console.log('JWT:', session?.accessToken);
```
#### Sign Up
```typescript
const { session, user } = await CapacitorSupabase.signUp({
email: 'newuser@example.com',
password: 'password123',
data: { name: 'John Doe' }
});
```
#### OAuth Sign In
```typescript
await CapacitorSupabase.signInWithOAuth({
provider: 'google',
redirectTo: 'myapp://callback'
});
```
#### OTP Sign In
```typescript
// Send OTP
await CapacitorSupabase.signInWithOtp({
email: 'user@example.com'
});
// Verify OTP
const { session, user } = await CapacitorSupabase.verifyOtp({
email: 'user@example.com',
token: '123456',
type: 'email'
});
```
#### Sign Out
```typescript
await CapacitorSupabase.signOut();
```
### Session Management
#### Get Current Session
```typescript
const { session } = await CapacitorSupabase.getSession();
if (session) {
console.log('JWT:', session.accessToken);
console.log('Refresh Token:', session.refreshToken);
console.log('Expires At:', session.expiresAt);
}
```
#### Refresh Session
```typescript
const { session } = await CapacitorSupabase.refreshSession();
```
#### Get Current User
```typescript
const { user } = await CapacitorSupabase.getUser();
if (user) {
console.log('User ID:', user.id);
console.log('Email:', user.email);
}
```
#### Set Session Manually
```typescript
const { session } = await CapacitorSupabase.setSession({
accessToken: 'eyJ...',
refreshToken: 'abc123'
});
```
### Listen to Auth State Changes
```typescript
const listener = await CapacitorSupabase.addListener(
'authStateChange',
({ event, session }) => {
console.log('Auth event:', event);
// Events: INITIAL_SESSION, SIGNED_IN, SIGNED_OUT, TOKEN_REFRESHED, USER_UPDATED
if (session) {
console.log('JWT:', session.accessToken);
}
}
);
// Later, remove the listener
listener.remove();
```
### Using JWT with @supabase/supabase-js
The main use case is to get the JWT from native auth and use it with the JavaScript Supabase client:
```typescript
import { createClient } from '@supabase/supabase-js';
import { CapacitorSupabase } from '@capgo/capacitor-supabase';
// Initialize native client
await CapacitorSupabase.initialize({
supabaseUrl: 'https://your-project.supabase.co',
supabaseKey: 'your-anon-key'
});
// Sign in natively
await CapacitorSupabase.signInWithPassword({
email: 'user@example.com',
password: 'password'
});
// Get session with JWT
const { session } = await CapacitorSupabase.getSession();
// Create JS client with the native session
const supabase = createClient(
'https://your-project.supabase.co',
'your-anon-key',
{
global: {
headers: {
Authorization: `Bearer ${session?.accessToken}`
}
}
}
);
// Now use supabase-js as normal
const { data } = await supabase.from('table').select('*');
```
### Database Operations (Native)
The plugin also supports native database operations:
#### Select
```typescript
const { data, error } = await CapacitorSupabase.select({
table: 'users',
columns: 'id, name, email',
filter: { active: true },
limit: 10,
orderBy: 'created_at',
ascending: false
});
```
#### Insert
```typescript
const { data, error } = await CapacitorSupabase.insert({
table: 'posts',
values: { title: 'Hello', content: 'World' }
});
```
#### Update
```typescript
const { data, error } = await CapacitorSupabase.update({
table: 'posts',
values: { title: 'Updated Title' },
filter: { id: 1 }
});
```
#### Delete
```typescript
const { data, error } = await CapacitorSupabase.delete({
table: 'posts',
filter: { id: 1 }
});
```
## API
* [`initialize(...)`](#initialize)
* [`signInWithPassword(...)`](#signinwithpassword)
* [`signUp(...)`](#signup)
* [`signInWithOAuth(...)`](#signinwithoauth)
* [`signInWithOtp(...)`](#signinwithotp)
* [`verifyOtp(...)`](#verifyotp)
* [`signOut()`](#signout)
* [`getSession()`](#getsession)
* [`refreshSession()`](#refreshsession)
* [`getUser()`](#getuser)
* [`setSession(...)`](#setsession)
* [`addListener('authStateChange', ...)`](#addlistenerauthstatechange-)
* [`removeAllListeners()`](#removealllisteners)
* [`select(...)`](#select)
* [`insert(...)`](#insert)
* [`update(...)`](#update)
* [`delete(...)`](#delete)
* [`getPluginVersion()`](#getpluginversion)
* [Interfaces](#interfaces)
* [Type Aliases](#type-aliases)
Capacitor Supabase Plugin for native Supabase SDK integration.
This plugin provides native iOS and Android Supabase SDK functionality
with the ability to retrieve JWT tokens for use in JavaScript/web layers.
### initialize(...)
```typescript
initialize(options: SupabaseConfig) => Promise
```
Initialize the Supabase client with your project credentials.
Must be called before any other methods.
| Param | Type | Description |
| ------------- | --------------------------------------------------------- | ------------------------------------------------- |
| **`options`** | SupabaseConfig | - Configuration options including URL and API key |
**Since:** 0.0.1
--------------------
### signInWithPassword(...)
```typescript
signInWithPassword(options: SignInWithPasswordOptions) => Promise
```
Sign in with email and password.
| Param | Type | Description |
| ------------- | ------------------------------------------------------------------------------- | -------------------------------- |
| **`options`** | SignInWithPasswordOptions | - Email and password credentials |
**Returns:** Promise<AuthResult>
**Since:** 0.0.1
--------------------
### signUp(...)
```typescript
signUp(options: SignUpOptions) => Promise
```
Sign up a new user with email and password.
| Param | Type | Description |
| ------------- | ------------------------------------------------------- | --------------------------------------------- |
| **`options`** | SignUpOptions | - Email, password, and optional user metadata |
**Returns:** Promise<AuthResult>
**Since:** 0.0.1
--------------------
### signInWithOAuth(...)
```typescript
signInWithOAuth(options: SignInWithOAuthOptions) => Promise
```
Sign in with an OAuth provider.
Opens the provider's authentication page.
| Param | Type | Description |
| ------------- | ------------------------------------------------------------------------- | ------------------------------------------ |
| **`options`** | SignInWithOAuthOptions | - OAuth provider and optional redirect URL |
**Since:** 0.0.1
--------------------
### signInWithOtp(...)
```typescript
signInWithOtp(options: SignInWithOtpOptions) => Promise
```
Sign in with OTP (One-Time Password) sent via email or SMS.
| Param | Type | Description |
| ------------- | --------------------------------------------------------------------- | -------------------------------------- |
| **`options`** | SignInWithOtpOptions | - Email or phone number to send OTP to |
**Since:** 0.0.1
--------------------
### verifyOtp(...)
```typescript
verifyOtp(options: VerifyOtpOptions) => Promise
```
Verify an OTP token.
| Param | Type | Description |
| ------------- | ------------------------------------------------------------- | ------------------------------------------- |
| **`options`** | VerifyOtpOptions | - Email/phone, token, and verification type |
**Returns:** Promise<AuthResult>
**Since:** 0.0.1
--------------------
### signOut()
```typescript
signOut() => Promise
```
Sign out the current user.
**Since:** 0.0.1
--------------------
### getSession()
```typescript
getSession() => Promise<{ session: Session | null; }>
```
Get the current session if one exists.
Returns the session with JWT access token.
**Returns:** Promise<{ session: Session | null; }>
**Since:** 0.0.1
--------------------
### refreshSession()
```typescript
refreshSession() => Promise<{ session: Session | null; }>
```
Refresh the current session and get new tokens.
**Returns:** Promise<{ session: Session | null; }>
**Since:** 0.0.1
--------------------
### getUser()
```typescript
getUser() => Promise<{ user: User | null; }>
```
Get the currently authenticated user.
**Returns:** Promise<{ user: User | null; }>
**Since:** 0.0.1
--------------------
### setSession(...)
```typescript
setSession(options: SetSessionOptions) => Promise<{ session: Session | null; }>
```
Set the session manually with access and refresh tokens.
Useful for restoring a session or integrating with external auth.
| Param | Type | Description |
| ------------- | --------------------------------------------------------------- | --------------------------- |
| **`options`** | SetSessionOptions | - Access and refresh tokens |
**Returns:** Promise<{ session: Session | null; }>
**Since:** 0.0.1
--------------------
### addListener('authStateChange', ...)
```typescript
addListener(eventName: 'authStateChange', listenerFunc: (data: AuthStateChange) => void) => Promise
```
Listen to authentication state changes.
| Param | Type | Description |
| ------------------ | ------------------------------------------------------------------------------ | ------------------------------------------ |
| **`eventName`** | 'authStateChange' | - Must be 'authStateChange' |
| **`listenerFunc`** | (data: AuthStateChange) => void | - Callback function for auth state changes |
**Returns:** Promise<PluginListenerHandle>
**Since:** 0.0.1
--------------------
### removeAllListeners()
```typescript
removeAllListeners() => Promise
```
Remove all listeners for auth state changes.
**Since:** 0.0.1
--------------------
### select(...)
```typescript
select(options: SelectOptions) => Promise>
```
Execute a SELECT query on a table.
| Param | Type | Description |
| ------------- | ------------------------------------------------------- | ------------------------------------------------- |
| **`options`** | SelectOptions | - Query options including table, columns, filters |
**Returns:** Promise<QueryResult<T[]>>
**Since:** 0.0.1
--------------------
### insert(...)
```typescript
insert(options: InsertOptions) => Promise>
```
Insert data into a table.
| Param | Type | Description |
| ------------- | ------------------------------------------------------- | --------------------------------- |
| **`options`** | InsertOptions | - Table name and values to insert |
**Returns:** Promise<QueryResult<T>>
**Since:** 0.0.1
--------------------
### update(...)
```typescript
update(options: UpdateOptions) => Promise>
```
Update data in a table.
| Param | Type | Description |
| ------------- | ------------------------------------------------------- | ----------------------------------------------------- |
| **`options`** | UpdateOptions | - Table name, values to update, and filter conditions |
**Returns:** Promise<QueryResult<T>>
**Since:** 0.0.1
--------------------
### delete(...)
```typescript
delete(options: DeleteOptions) => Promise>
```
Delete data from a table.
| Param | Type | Description |
| ------------- | ------------------------------------------------------- | ---------------------------------- |
| **`options`** | DeleteOptions | - Table name and filter conditions |
**Returns:** Promise<QueryResult<T>>
**Since:** 0.0.1
--------------------
### getPluginVersion()
```typescript
getPluginVersion() => Promise<{ version: string; }>
```
Get the native Capacitor plugin version.
**Returns:** Promise<{ version: string; }>
**Since:** 0.0.1
--------------------
### Interfaces
#### SupabaseConfig
Configuration options for initializing the Supabase client.
| Prop | Type | Description | Since |
| ----------------- | ------------------- | ---------------------------------- | ----- |
| **`supabaseUrl`** | string | The Supabase project URL. | 0.0.1 |
| **`supabaseKey`** | string | The Supabase anonymous/public key. | 0.0.1 |
#### AuthResult
Result of authentication operations that return a session.
| Prop | Type | Description | Since |
| ------------- | --------------------------------------------------- | --------------------------------------------- | ----- |
| **`session`** | Session \| null | The session if authentication was successful. | 0.0.1 |
| **`user`** | User \| null | The authenticated user if successful. | 0.0.1 |
#### Session
Session object containing authentication tokens.
| Prop | Type | Description | Since |
| ------------------ | ------------------------------------- | -------------------------------------------------------------- | ----- |
| **`accessToken`** | string | The JWT access token. Use this for authenticated API requests. | 0.0.1 |
| **`refreshToken`** | string | The refresh token for obtaining new access tokens. | 0.0.1 |
| **`tokenType`** | string | Token type (usually "bearer"). | 0.0.1 |
| **`expiresIn`** | number | Number of seconds until the access token expires. | 0.0.1 |
| **`expiresAt`** | number | Unix timestamp when the token expires. | 0.0.1 |
| **`user`** | User | The authenticated user. | 0.0.1 |
#### User
User object returned from authentication operations.
| Prop | Type | Description | Since |
| ------------------ | ---------------------------------------------------------------- | -------------------------------------------------- | ----- |
| **`id`** | string | Unique identifier for the user. | 0.0.1 |
| **`email`** | string | User's email address. | 0.0.1 |
| **`phone`** | string | User's phone number. | 0.0.1 |
| **`createdAt`** | string | Timestamp when the user was created. | 0.0.1 |
| **`lastSignInAt`** | string | Timestamp when the user last signed in. | 0.0.1 |
| **`userMetadata`** | Record<string, unknown> | User metadata (custom fields). | 0.0.1 |
| **`appMetadata`** | Record<string, unknown> | App metadata. | 0.0.1 |
#### SignInWithPasswordOptions
Options for email/password sign-in.
| Prop | Type | Description | Since |
| -------------- | ------------------- | ----------------------------------------- | ----- |
| **`email`** | string | User's email address. | 0.0.1 |
| **`password`** | string | User's password. | 0.0.1 |
#### SignUpOptions
Options for email/password sign-up.
| Prop | Type | Description | Since |
| -------------- | ---------------------------------------------------------------- | ---------------------------------------------- | ----- |
| **`email`** | string | User's email address. | 0.0.1 |
| **`password`** | string | User's password. | 0.0.1 |
| **`data`** | Record<string, unknown> | Optional user metadata to store with the user. | 0.0.1 |
#### SignInWithOAuthOptions
Options for OAuth sign-in.
| Prop | Type | Description | Since |
| ---------------- | ------------------------------------------------------- | ---------------------------------------- | ----- |
| **`provider`** | OAuthProvider | The OAuth provider to use. | 0.0.1 |
| **`redirectTo`** | string | URL to redirect to after authentication. | 0.0.1 |
| **`scopes`** | string | OAuth scopes to request. | 0.0.1 |
#### SignInWithOtpOptions
Options for OTP sign-in.
| Prop | Type | Description | Since |
| ----------- | ------------------- | ----------------------------------------------------------------------------- | ----- |
| **`email`** | string | User's email address (required if phone is not provided). | 0.0.1 |
| **`phone`** | string | User's phone number (required if email is not provided). | 0.0.1 |
#### VerifyOtpOptions
Options for verifying OTP.
| Prop | Type | Description | Since |
| ----------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----- |
| **`email`** | string | User's email address (required if phone is not provided). | 0.0.1 |
| **`phone`** | string | User's phone number (required if email is not provided). | 0.0.1 |
| **`token`** | string | The OTP token received via email/SMS. | 0.0.1 |
| **`type`** | 'sms' \| 'email' \| 'magiclink' \| 'signup' \| 'recovery' | The type of OTP verification. | 0.0.1 |
#### SetSessionOptions
Options for setting a session manually.
| Prop | Type | Description | Since |
| ------------------ | ------------------- | ------------------ | ----- |
| **`accessToken`** | string | The access token. | 0.0.1 |
| **`refreshToken`** | string | The refresh token. | 0.0.1 |
#### PluginListenerHandle
| Prop | Type |
| ------------ | ----------------------------------------- |
| **`remove`** | () => Promise<void> |
#### AuthStateChange
Auth state change callback data.
| Prop | Type | Description | Since |
| ------------- | ----------------------------------------------------------- | ----------------------------------------- | ----- |
| **`event`** | AuthChangeEvent | The type of auth event. | 0.0.1 |
| **`session`** | Session \| null | The current session (null if signed out). | 0.0.1 |
#### QueryResult
Result of database queries.
| Prop | Type | Description | Since |
| ----------- | --------------------------- | --------------------------------------------------- | ----- |
| **`data`** | T \| null | The query result data. | 0.0.1 |
| **`error`** | string \| null | Error message if the query failed. | 0.0.1 |
| **`count`** | number | Number of affected rows (for insert/update/delete). | 0.0.1 |
#### SelectOptions
Options for database select queries.
| Prop | Type | Description | Since |
| --------------- | ---------------------------------------------------------------- | ---------------------------------------- | ----- |
| **`table`** | string | The table name to query. | 0.0.1 |
| **`columns`** | string | Columns to select (default: "*"). | 0.0.1 |
| **`filter`** | Record<string, unknown> | Filter conditions as key-value pairs. | 0.0.1 |
| **`limit`** | number | Maximum number of rows to return. | 0.0.1 |
| **`offset`** | number | Number of rows to skip. | 0.0.1 |
| **`orderBy`** | string | Column to order by. | 0.0.1 |
| **`ascending`** | boolean | Order direction. | 0.0.1 |
| **`single`** | boolean | Return a single row instead of an array. | 0.0.1 |
#### InsertOptions
Options for database insert queries.
| Prop | Type | Description | Since |
| ------------ | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ----- |
| **`table`** | string | The table name to insert into. | 0.0.1 |
| **`values`** | Record<string, unknown> \| Record<string, unknown>[] | The data to insert (single object or array of objects). | 0.0.1 |
#### UpdateOptions
Options for database update queries.
| Prop | Type | Description | Since |
| ------------ | ---------------------------------------------------------------- | ------------------------------------------ | ----- |
| **`table`** | string | The table name to update. | 0.0.1 |
| **`values`** | Record<string, unknown> | The data to update. | 0.0.1 |
| **`filter`** | Record<string, unknown> | Filter conditions to match rows to update. | 0.0.1 |
#### DeleteOptions
Options for database delete queries.
| Prop | Type | Description | Since |
| ------------ | ---------------------------------------------------------------- | ------------------------------------------ | ----- |
| **`table`** | string | The table name to delete from. | 0.0.1 |
| **`filter`** | Record<string, unknown> | Filter conditions to match rows to delete. | 0.0.1 |
### Type Aliases
#### Record
Construct a type with a set of properties K of type T
{
[P in K]: T;
}
#### OAuthProvider
Supported OAuth providers.
'apple' | 'azure' | 'bitbucket' | 'discord' | 'facebook' | 'figma' | 'github' | 'gitlab' | 'google' | 'kakao' | 'keycloak' | 'linkedin' | 'linkedin_oidc' | 'notion' | 'slack' | 'slack_oidc' | 'spotify' | 'twitch' | 'twitter' | 'workos' | 'zoom'
#### AuthChangeEvent
Auth state change event types.
'INITIAL_SESSION' | 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'USER_UPDATED' | 'PASSWORD_RECOVERY'
## License
MPL-2.0