@supabase/lite 0.9.0 → 0.9.1-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FEATURES.md +176 -0
- package/LIMITATIONS.md +9 -6
- package/PATTERNS.md +66 -6
- package/README.md +16 -8
- package/STATUS.md +33 -20
- package/dist/{Connection-ZWTDByQ5.d.ts → Connection-f_d5HhQ0.d.ts} +301 -293
- package/dist/cli/index.js +127 -124
- package/dist/cli/lib.d.ts +1 -12
- package/dist/cli/lib.js +44 -39
- package/dist/db/fallback.d.ts +1 -1
- package/dist/db/postgres/PostgresConnection.js +18 -18
- package/dist/db/postgres/pglite/PgliteConnection.js +17 -17
- package/dist/index.d.ts +116 -40
- package/dist/index.js +181 -73
- package/dist/static/.vite/manifest.json +34 -2
- package/dist/static/assets/InterVariable-Dx4kXJAl.woff2 +0 -0
- package/dist/static/assets/InterVariable-Italic-DpCbqKDY.woff2 +0 -0
- package/dist/static/assets/SourceCodePro-Variable-BP8Zz55n.woff2 +0 -0
- package/dist/static/assets/SourceCodePro-Variable-Italic-eALmlzX7.woff2 +0 -0
- package/dist/static/assets/main-BY4iigay.css +1 -0
- package/dist/static/assets/main-BnQ-v4V9.js +199 -0
- package/dist/static/assets/manrope-latin-ext-wght-normal-Ch3YOpNY.woff2 +0 -0
- package/dist/static/assets/manrope-latin-wght-normal-DHIcAJRg.woff2 +0 -0
- package/dist/vite/index.d.ts +627 -31
- package/dist/vite/index.js +2 -2
- package/docs/auth/email.mdx +214 -0
- package/docs/auth/not-supported.mdx +57 -0
- package/docs/auth/overview.mdx +52 -0
- package/docs/auth/supported-flows.mdx +120 -0
- package/docs/cli/overview.mdx +112 -0
- package/docs/cli/telemetry.mdx +34 -0
- package/docs/compatibility.mdx +115 -0
- package/docs/database/backends.mdx +118 -0
- package/docs/database/data-api.mdx +90 -0
- package/docs/database/functions-triggers.mdx +93 -0
- package/docs/database/migrations.mdx +95 -0
- package/docs/database/overview.mdx +66 -0
- package/docs/database/postgres-sqlite-translation.mdx +130 -0
- package/docs/database/rls.mdx +161 -0
- package/docs/database/schemas.mdx +58 -0
- package/docs/index.mdx +49 -0
- package/docs/integrations/embedded.mdx +100 -0
- package/docs/integrations/frameworks.mdx +83 -0
- package/docs/integrations/vite.mdx +87 -0
- package/docs/llms.txt +52 -0
- package/docs/other/edge-functions.mdx +34 -0
- package/docs/other/realtime.mdx +22 -0
- package/docs/quickstart.mdx +150 -0
- package/docs/running.mdx +127 -0
- package/docs/storage/adapters.mdx +75 -0
- package/docs/storage/limitations.mdx +21 -0
- package/docs/storage/overview.mdx +88 -0
- package/docs/upgrade.mdx +108 -0
- package/package.json +5 -1
- package/skills/supalite/SKILL.md +6 -4
- package/dist/static/assets/main-1bwWb_1q.js +0 -40996
- package/dist/static/assets/main-BDsRycsc.css +0 -4045
- package/dist/static/fonts/CustomFont-Black.woff2 +0 -0
- package/dist/static/fonts/CustomFont-BlackItalic.woff2 +0 -0
- package/dist/static/fonts/CustomFont-Bold.woff2 +0 -0
- package/dist/static/fonts/CustomFont-BoldItalic.woff2 +0 -0
- package/dist/static/fonts/CustomFont-Book.woff2 +0 -0
- package/dist/static/fonts/CustomFont-BookItalic.woff2 +0 -0
- package/dist/static/fonts/CustomFont-Medium.woff2 +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Vite plugin"
|
|
3
|
+
description: "Run Supabase Lite in-process inside the Vite dev server. The recommended path for Vite frontends."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
import { Aside } from '@astrojs/starlight/components';
|
|
7
|
+
|
|
8
|
+
If your frontend uses Vite, this is the recommended way to run Supabase Lite: no separate CLI process, no Docker, no proxy config. The `@supabase/lite/vite` plugin runs the backend inline inside the Vite dev server, so one process serves both your app and the API.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
// vite.config.ts
|
|
12
|
+
import { defineConfig } from "vite";
|
|
13
|
+
import { supalite } from "@supabase/lite/vite";
|
|
14
|
+
|
|
15
|
+
export default defineConfig({
|
|
16
|
+
plugins: [supalite()],
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
<Aside type="caution">
|
|
21
|
+
Run exactly one backend per project. Don't run `lite dev` or `lite start` at the same time as this plugin, and don't run both CLI backends together. It isn't necessarily a port conflict: two backends driving the same `supabase/` project and SQLite file race migrations and declarative metadata reconciliation. Pick one process model per project; see [Running Supabase Lite](/running).
|
|
22
|
+
</Aside>
|
|
23
|
+
|
|
24
|
+
## What it does
|
|
25
|
+
|
|
26
|
+
- Auto-resolves `./supabase/config.toml` from the project root.
|
|
27
|
+
- Applies pending imperative migrations, then the declarative schema diff, on boot.
|
|
28
|
+
- Watches `schemas/*.sql` (and the migrations directory) for hot-reload during `vite`/`vite dev`.
|
|
29
|
+
- Mounts `/auth/v1`, `/rest/v1`, and `/_system` as middleware on the Vite dev/preview server.
|
|
30
|
+
- Injects `VITE_SUPABASE_URL` (the current browser origin, via `window.location.origin`) and the project's resolved `sb_publishable_*` key as `VITE_SUPABASE_ANON_KEY` into `import.meta.env`, so the canonical client snippet works with zero `.env` setup, even with key enforcement on.
|
|
31
|
+
|
|
32
|
+
<Aside type="caution">
|
|
33
|
+
`vite preview` mounts the API and runs boot-time migrations, but does **not** watch schemas (it simulates production). `vite build` and any standalone production server do not mount the API at all. Use `lite start`, hosted Supabase, or an embedded app there.
|
|
34
|
+
</Aside>
|
|
35
|
+
|
|
36
|
+
## Client setup
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { createClient } from "@supabase/supabase-js";
|
|
40
|
+
|
|
41
|
+
const client = createClient(
|
|
42
|
+
import.meta.env.VITE_SUPABASE_URL,
|
|
43
|
+
import.meta.env.VITE_SUPABASE_ANON_KEY,
|
|
44
|
+
);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Equivalently, since the plugin's default URL is always the current origin:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
const client = createClient(window.location.origin, "<sb_publishable_...>");
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The plugin resolves the project's real `auth.publishable_key` (see [API keys](/auth/overview#api-keys)) and injects it as `VITE_SUPABASE_ANON_KEY`, so a `lite init`'d project works with zero `.env` setup even with key enforcement on. The placeholder `"sb-lite-anon-key"` is only used as a fallback when no project/key is found.
|
|
54
|
+
|
|
55
|
+
A `.env` value for either `VITE_SUPABASE_URL` or `VITE_SUPABASE_ANON_KEY` always overrides the plugin's injected default. The plugin only fills in what you haven't set, and it resolves your `root`/`envDir`/`envPrefix` the same way Vite itself does, so a value that Vite would expose is a value the plugin sees.
|
|
56
|
+
|
|
57
|
+
## Options
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
supalite({
|
|
61
|
+
config: "./supabase/config.toml",
|
|
62
|
+
migrateOnBoot: true,
|
|
63
|
+
watchSchema: true,
|
|
64
|
+
forceSchema: false,
|
|
65
|
+
initOnBoot: true,
|
|
66
|
+
prefixes: ["/auth/v1", "/rest/v1", "/_system"],
|
|
67
|
+
admin: true,
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
| Option | Type | Default | Description |
|
|
72
|
+
|---|---|---|---|
|
|
73
|
+
| `config` | string | auto-resolved `./supabase/config.toml` | Path to the project's `config.toml`. Defaults to auto-resolving `./supabase/config.toml` relative to where Vite runs. |
|
|
74
|
+
| `migrateOnBoot` | boolean | `true` | Apply pending imperative migrations, then run the declarative schema diff, when the dev/preview server starts. |
|
|
75
|
+
| `watchSchema` | boolean | `true` | Watch `schemas/*.sql` and the migrations directory for changes and hot-reload the schema. Only takes effect during `vite`/`vite dev`; `vite preview` never watches, regardless of this option. |
|
|
76
|
+
| `forceSchema` | boolean | `false` | Allow the declarative schema diff to apply changes that would otherwise be blocked as data-loss. Logs a warning on boot when enabled. |
|
|
77
|
+
| `initOnBoot` | boolean | `true` | Scaffold the initial `supabase/` structure if it doesn't exist yet, equivalent to `lite init`, before starting. |
|
|
78
|
+
| `prefixes` | string[] | `["/auth/v1", "/rest/v1", "/_system"]` | Which path prefixes the plugin mounts on the Vite server. Only override this if you need to move the API off its default paths. |
|
|
79
|
+
| `admin` | boolean | `true` on loopback | [Admin mode](/running#admin-mode): serve keyless, same-origin, loopback `/rest/v1` requests as `service_role`. A non-loopback Vite host (including bare `vite --host`) defaults it off and requires explicit `admin: true`; config cannot silently re-enable an exposed listener. Preview always disables it. Admin also covers `/storage/v1`, but that prefix is not mounted by default. |
|
|
80
|
+
|
|
81
|
+
Vite and the Lite CLI use the same host posture: local binding keeps the local admin default, while `vite --host` / `lite dev --host` exposes the listener and disables admin unless explicitly enabled. If a sandbox or tunnel publishes the port, leave admin off even when its local forwarding socket appears loopback.
|
|
82
|
+
|
|
83
|
+
## Related
|
|
84
|
+
|
|
85
|
+
- [Running Supabase Lite](/running): how this compares to `lite dev`/`lite start`/embedding.
|
|
86
|
+
- [Embedded / programmatic](/integrations/embedded): the same boot sequence, driven manually instead of by the plugin.
|
|
87
|
+
- Upstream: [Supabase local development](https://supabase.com/docs/guides/local-development), the Docker-based equivalent this plugin replaces for Vite apps.
|
package/docs/llms.txt
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Supabase Lite docs
|
|
2
|
+
|
|
3
|
+
Bundled with @supabase/lite 0.9.1-next.2. Same content as https://docs.lite.dev, which tracks the latest release.
|
|
4
|
+
Files are MDX source (Astro Starlight). Site path -> file: `/` -> `index.mdx`, `/database/rls` -> `database/rls.mdx`.
|
|
5
|
+
|
|
6
|
+
## Start
|
|
7
|
+
|
|
8
|
+
- [Introduction](index.mdx): What Supabase Lite is, what's supported today, and how it relates to hosted Supabase.
|
|
9
|
+
- [Quickstart](quickstart.mdx): Install Supabase Lite, scaffold a project, write a schema, and run your first query.
|
|
10
|
+
- [Compatibility](compatibility.mdx): Capability-level support matrix for the Data API, Auth, Storage, RLS, Realtime, and Edge Functions across SQLite, PGlite, and Postgres.
|
|
11
|
+
- [Running Supabase Lite](running.mdx): Choose between the Vite plugin, lite dev, lite start, and embedded/programmatic usage.
|
|
12
|
+
- [Upgrading to Supabase](upgrade.mdx): Migrate a Supabase Lite project to hosted or local Supabase with lite upgrade.
|
|
13
|
+
|
|
14
|
+
## Database
|
|
15
|
+
|
|
16
|
+
- [Database overview](database/overview.mdx): How Supabase Lite's Postgres-shaped Data API maps onto SQLite, PGlite, and Postgres.
|
|
17
|
+
- [Backends](database/backends.mdx): SQLite drivers vs PGlite/Postgres: how Supabase Lite picks a database, and how to switch.
|
|
18
|
+
- [Data API divergences](database/data-api.mdx): Where the PostgREST-compatible Data API and supabase-js diverge on SQLite, and the workarounds.
|
|
19
|
+
- [Row Level Security](database/rls.mdx): RLS works on every Supabase Lite backend; SQLite enforces it at the application layer with specific caveats.
|
|
20
|
+
- [Declarative schemas](database/schemas.mdx): Writing Postgres DDL in supabase/schemas/*.sql, and how it maps onto SQLite's single-namespace model.
|
|
21
|
+
- [Migrations](database/migrations.mdx): lite migration and lite db commands, the declarative diff flow, and how they differ from supabase db.
|
|
22
|
+
- [Functions & triggers](database/functions-triggers.mdx): The PL/pgSQL trigger subset supported on SQLite, and what runs unmodified on Postgres backends.
|
|
23
|
+
- [Postgres → SQLite translation](database/postgres-sqlite-translation.mdx): How Supabase Lite auto-translates Postgres DDL to SQLite, and the exact errors you'll see when something isn't supported.
|
|
24
|
+
|
|
25
|
+
## Auth
|
|
26
|
+
|
|
27
|
+
- [Auth overview](auth/overview.mdx): GoTrue-compatible Auth API for @supabase/lite: what's implemented, what's planned, and how it fits into supabase-js.
|
|
28
|
+
- [Supported auth flows](auth/supported-flows.mdx): The 13 GoTrue-compatible Auth endpoints Supabase Lite implements, with supabase-js examples.
|
|
29
|
+
- [Email delivery & templates](auth/email.mdx): Configure the email driver, verification links, and customizable transactional email templates for Supabase Lite Auth.
|
|
30
|
+
- [Auth: not supported](auth/not-supported.mdx): Anonymous sign-in, manual identity linking, the admin API, MFA, and OAuth providers beyond github/google are not implemented yet. What's planned vs. not planned, and the hosted-Supabase workaround.
|
|
31
|
+
|
|
32
|
+
## Storage
|
|
33
|
+
|
|
34
|
+
- [Storage overview](storage/overview.mdx): Storage API for @supabase/lite: experimental flag, endpoint coverage, and supabase-js parity.
|
|
35
|
+
- [Storage adapters](storage/adapters.mdx): Pluggable storage backends (filesystem, S3-compatible) and transformation adapters (Noop, Sharp, Cloudflare) for Supabase Lite Storage.
|
|
36
|
+
- [Storage limitations](storage/limitations.mdx): What's not yet implemented in Supabase Lite Storage: TUS uploads, webhooks, bucket-list query params, and the S3-compatible server protocol.
|
|
37
|
+
|
|
38
|
+
## Integrations
|
|
39
|
+
|
|
40
|
+
- [Vite plugin](integrations/vite.mdx): Run Supabase Lite in-process inside the Vite dev server. The recommended path for Vite frontends.
|
|
41
|
+
- [Embedded / programmatic](integrations/embedded.mdx): Use the App class directly in Bun, Node, browser, or edge runtimes, without the CLI.
|
|
42
|
+
- [Framework guides](integrations/frameworks.mdx): Running Supabase Lite inside Next.js, Cloudflare Workers, and Docker.
|
|
43
|
+
|
|
44
|
+
## CLI
|
|
45
|
+
|
|
46
|
+
- [CLI overview](cli/overview.mdx): The lite CLI versus the supabase CLI: parity, gaps, and what's still experimental.
|
|
47
|
+
- [Telemetry](cli/telemetry.mdx): The lite CLI sends anonymous usage telemetry by default. How to disable it.
|
|
48
|
+
|
|
49
|
+
## Other
|
|
50
|
+
|
|
51
|
+
- [Edge Functions](other/edge-functions.mdx): Supabase Edge Functions (Deno runtime) are not supported in @supabase/lite. Run a regular server endpoint instead.
|
|
52
|
+
- [Realtime](other/realtime.mdx): Supabase Realtime (channels, presence, broadcast, Postgres Changes) is not implemented in @supabase/lite yet.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Edge Functions"
|
|
3
|
+
description: "Supabase Edge Functions (Deno runtime) are not supported in @supabase/lite. Run a regular server endpoint instead."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
import { Aside } from '@astrojs/starlight/components';
|
|
7
|
+
|
|
8
|
+
<Aside type="caution">
|
|
9
|
+
Edge Functions are not supported. Supabase Lite does not bundle a Deno or edge runtime, and there is no `/functions/v1/*` route.
|
|
10
|
+
</Aside>
|
|
11
|
+
|
|
12
|
+
A config schema for functions exists in `app/src/config/functions.ts` (per-function JWT verification, entrypoints), but nothing executes against it: `supabase/functions/*` in your project is not picked up or served by Supabase Lite.
|
|
13
|
+
|
|
14
|
+
## Workaround
|
|
15
|
+
|
|
16
|
+
Supabase Lite is a plain HTTP server (`app.fetch`), so anything you'd put in an Edge Function can live in a normal server endpoint instead, called directly from your client:
|
|
17
|
+
|
|
18
|
+
- A [Hono](https://hono.dev/) or Express route mounted alongside your app
|
|
19
|
+
- A Next.js App Router route handler
|
|
20
|
+
- Vite middleware, in the same process as the [Vite plugin](/integrations/vite)
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
// Instead of supabase.functions.invoke("my-function", { body }):
|
|
24
|
+
const res = await fetch("/api/my-function", {
|
|
25
|
+
method: "POST",
|
|
26
|
+
body: JSON.stringify(body),
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Since Supabase Lite already runs your Data API and Auth in-process (`app.fetch`), a hand-rolled endpoint has direct access to `app.getClient()` for database/auth calls without an extra network hop. See [Embedded / programmatic usage](/integrations/embedded) for wiring that up.
|
|
31
|
+
|
|
32
|
+
If you specifically need Deno-compatible Edge Functions (for parity with a production Supabase project, or because you rely on Deno-only APIs), run those against hosted Supabase and keep the rest of your app on Supabase Lite.
|
|
33
|
+
|
|
34
|
+
For the Edge Functions model this replaces, see the [Supabase Edge Functions docs](https://supabase.com/docs/guides/functions). See [Compatibility](/compatibility) for how this tracks against other services.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Realtime"
|
|
3
|
+
description: "Supabase Realtime (channels, presence, broadcast, Postgres Changes) is not implemented in @supabase/lite yet."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
import { Aside } from '@astrojs/starlight/components';
|
|
7
|
+
|
|
8
|
+
<Aside type="caution">
|
|
9
|
+
Realtime is not implemented. There is no WebSocket server, no channels, and no Postgres Changes stream in Supabase Lite yet.
|
|
10
|
+
</Aside>
|
|
11
|
+
|
|
12
|
+
A config schema for Realtime exists in `app/src/config/realtime.ts`, but it isn't wired to any runtime behavior. Setting `[realtime]` keys in `config.toml` has no effect today. Calling `supabase.channel(...)`, `.on("postgres_changes", ...)`, presence, or broadcast against a Supabase Lite instance will not connect to anything on the server side.
|
|
13
|
+
|
|
14
|
+
## Workaround
|
|
15
|
+
|
|
16
|
+
Run the realtime-dependent parts of your app against hosted Supabase. Supabase Lite can still serve the Data API and Auth for the rest of the app; there's no requirement to run a single backend for every product.
|
|
17
|
+
|
|
18
|
+
## What it would look like
|
|
19
|
+
|
|
20
|
+
When implemented, Realtime would need to cover the same three primitives upstream does: Postgres Changes (streaming row-level INSERT/UPDATE/DELETE events), Broadcast (ephemeral pub/sub over a channel), and Presence (shared client state per channel). None of this exists yet, so check `STATUS.md` in the installed package for current status before building around an assumed timeline.
|
|
21
|
+
|
|
22
|
+
For the concepts and client API this would eventually support unchanged, see the [Supabase Realtime docs](https://supabase.com/docs/guides/realtime). See [Compatibility](/compatibility) for how Realtime tracks against everything else.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Quickstart"
|
|
3
|
+
description: "Install Supabase Lite, scaffold a project, write a schema, and run your first query."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
import { Steps, Tabs, TabItem } from '@astrojs/starlight/components';
|
|
7
|
+
|
|
8
|
+
This walks through the minimal path: install, scaffold, write a schema, run a server, query it with `supabase-js`. For the general Supabase local-dev flow this mirrors, see the [Supabase local development guide](https://supabase.com/docs/guides/local-development).
|
|
9
|
+
|
|
10
|
+
<Steps>
|
|
11
|
+
|
|
12
|
+
1. **Install**
|
|
13
|
+
|
|
14
|
+
Install both `@supabase/lite` and `@supabase/supabase-js`.
|
|
15
|
+
|
|
16
|
+
<Tabs sync="pkg-manager">
|
|
17
|
+
<TabItem label="bun">
|
|
18
|
+
```bash
|
|
19
|
+
bun add @supabase/lite @supabase/supabase-js
|
|
20
|
+
```
|
|
21
|
+
</TabItem>
|
|
22
|
+
<TabItem label="npm">
|
|
23
|
+
```
|
|
24
|
+
npm install @supabase/lite @supabase/supabase-js
|
|
25
|
+
```
|
|
26
|
+
</TabItem>
|
|
27
|
+
<TabItem label="pnpm">
|
|
28
|
+
```bash
|
|
29
|
+
pnpm add @supabase/lite @supabase/supabase-js
|
|
30
|
+
```
|
|
31
|
+
</TabItem>
|
|
32
|
+
</Tabs>
|
|
33
|
+
|
|
34
|
+
Add the `-g` flag if you want the `lite` CLI available system-wide instead of per-project.
|
|
35
|
+
|
|
36
|
+
1. **Scaffold a project**
|
|
37
|
+
|
|
38
|
+
<Tabs sync="pkg-manager">
|
|
39
|
+
<TabItem label="bun">
|
|
40
|
+
```bash
|
|
41
|
+
bunx lite init
|
|
42
|
+
```
|
|
43
|
+
</TabItem>
|
|
44
|
+
<TabItem label="npm">
|
|
45
|
+
```bash
|
|
46
|
+
npx lite init
|
|
47
|
+
```
|
|
48
|
+
</TabItem>
|
|
49
|
+
<TabItem label="pnpm">
|
|
50
|
+
```bash
|
|
51
|
+
pnpm exec lite init
|
|
52
|
+
```
|
|
53
|
+
</TabItem>
|
|
54
|
+
</Tabs>
|
|
55
|
+
|
|
56
|
+
This creates a Supabase-compatible `supabase/` directory: `config.toml`, `schemas/schema.sql`, `seed.sql`, and a git-ignored `.temp/data.db` SQLite file.
|
|
57
|
+
|
|
58
|
+
`lite dev` scaffolds the same structure on boot if it's missing, so you can skip straight to it in an empty directory. `lite start` requires the scaffold to exist — run `init` first.
|
|
59
|
+
|
|
60
|
+
1. **Write your schema**
|
|
61
|
+
|
|
62
|
+
Write plain Postgres DDL in `supabase/schemas/schema.sql`. On the SQLite path it's translated automatically (`SERIAL` → `INTEGER PRIMARY KEY AUTOINCREMENT`, `NOW()` → `datetime('now')`, and so on).
|
|
63
|
+
|
|
64
|
+
A small per-user todos example with RLS enabled:
|
|
65
|
+
|
|
66
|
+
```sql
|
|
67
|
+
create table todos (
|
|
68
|
+
id uuid primary key default gen_random_uuid(),
|
|
69
|
+
user_id uuid not null references auth.users(id) on delete cascade,
|
|
70
|
+
task text not null,
|
|
71
|
+
is_complete boolean not null default false,
|
|
72
|
+
created_at timestamptz not null default now()
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
alter table todos enable row level security;
|
|
76
|
+
|
|
77
|
+
create policy "select own todos" on todos for select to authenticated using (auth.uid() = user_id);
|
|
78
|
+
create policy "insert own todos" on todos for insert to authenticated with check (auth.uid() = user_id);
|
|
79
|
+
create policy "update own todos" on todos for update to authenticated using (auth.uid() = user_id) with check (auth.uid() = user_id);
|
|
80
|
+
create policy "delete own todos" on todos for delete to authenticated using (auth.uid() = user_id);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Currently, default values using functions support is limited, therefore `DEFAULT auth.uid()` is not supported on the SQLite path. You must supply `user_id` by the client on insert; the `WITH CHECK` policy enforces ownership server-side. The `PATTERNS.md` file shipped in the package has more recipes.
|
|
84
|
+
|
|
85
|
+
1. **Pick how you run it**
|
|
86
|
+
|
|
87
|
+
If your frontend uses Vite, use the [Vite plugin](/integrations/vite): it runs Supabase Lite inline in the Vite dev server, no separate process. Otherwise, use the `lite` CLI directly: see [Running Supabase Lite](/running) to choose between `lite dev` (auto schema-reload) and `lite start` (no watch, CI/prod-like).
|
|
88
|
+
|
|
89
|
+
<Tabs sync="pkg-manager">
|
|
90
|
+
<TabItem label="bun">
|
|
91
|
+
```bash
|
|
92
|
+
bunx lite dev
|
|
93
|
+
```
|
|
94
|
+
</TabItem>
|
|
95
|
+
<TabItem label="npm">
|
|
96
|
+
```bash
|
|
97
|
+
npx lite dev
|
|
98
|
+
```
|
|
99
|
+
</TabItem>
|
|
100
|
+
<TabItem label="pnpm">
|
|
101
|
+
```bash
|
|
102
|
+
pnpm exec lite dev
|
|
103
|
+
```
|
|
104
|
+
</TabItem>
|
|
105
|
+
</Tabs>
|
|
106
|
+
|
|
107
|
+
The API is now running at `http://127.0.0.1:54321`. `lite init` also generated a publishable/secret API key pair into root `.env` and printed them.
|
|
108
|
+
|
|
109
|
+
1. **Create a client**
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { createClient } from "@supabase/supabase-js";
|
|
113
|
+
|
|
114
|
+
const supabase = createClient(
|
|
115
|
+
"http://127.0.0.1:54321",
|
|
116
|
+
"<sb_publishable_...>"
|
|
117
|
+
);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Use the printed `sb_publishable_*` key as the anon key. If no keys are configured, `/rest/v1`/`/auth/v1` accept any/no `apikey` (unchanged old behavior). See [API keys](/auth/overview#api-keys).
|
|
121
|
+
|
|
122
|
+
If you're using the [Vite plugin](/integrations/vite) instead, the plugin injects `VITE_SUPABASE_URL` (`window.location.origin`) and a dev `VITE_SUPABASE_ANON_KEY`, so the canonical form works with no manual setup:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { createClient } from "@supabase/supabase-js";
|
|
126
|
+
|
|
127
|
+
const supabase = createClient(
|
|
128
|
+
import.meta.env.VITE_SUPABASE_URL,
|
|
129
|
+
import.meta.env.VITE_SUPABASE_ANON_KEY,
|
|
130
|
+
);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
1. **Run a query**
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
const { data: { session } } = await supabase.auth.getSession();
|
|
137
|
+
|
|
138
|
+
await supabase.from("todos").insert({
|
|
139
|
+
user_id: session.user.id,
|
|
140
|
+
task: "Ship the quickstart",
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const { data, error } = await supabase.from("todos").select("*");
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
This is standard `supabase-js`, no Supabase Lite-specific API. See [Compatibility](/compatibility) for what else is supported.
|
|
147
|
+
|
|
148
|
+
</Steps>
|
|
149
|
+
|
|
150
|
+
For the full Supabase quickstart flow (project structure, general CLI usage) that this mirrors, see the [Supabase local development guide](https://supabase.com/docs/guides/local-development).
|
package/docs/running.mdx
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Running Supabase Lite"
|
|
3
|
+
description: "Choose between the Vite plugin, lite dev, lite start, and embedded/programmatic usage."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
How you run Supabase Lite is a Supabase Lite-specific concept with no direct Supabase equivalent: since there's no Docker stack, "running Supabase locally" (see the [Supabase local development guide](https://supabase.com/docs/guides/local-development)) becomes a choice between running an in-process plugin, a small CLI server, or embedding the app directly in your own runtime.
|
|
7
|
+
|
|
8
|
+
## Options at a glance
|
|
9
|
+
|
|
10
|
+
| Mode | Process model | Schema reload | Best for |
|
|
11
|
+
|---|---|---|---|
|
|
12
|
+
| [Vite plugin](/integrations/vite) | In-process, mounted on the Vite dev server | Watches `schemas/*.sql` in `vite`/`vite dev`; not in `vite preview` or `vite build` | Any Vite frontend (React/Vue/Svelte/…). Recommended default if you're on Vite. |
|
|
13
|
+
| `lite dev` | Separate process | Watches `schemas/*.sql`, auto-applies on change | Non-Vite apps during active development |
|
|
14
|
+
| `lite start` | Separate process | None: no watch, no auto-migrate | CI, staging, or anything that should behave like production |
|
|
15
|
+
| [Embedded / programmatic](/integrations/embedded) | In-process, inside your own Bun/Node/edge runtime | Manual: you call `createMigrator(...).migrate()` yourself | Custom servers, edge functions, or when you need full control over boot sequence |
|
|
16
|
+
|
|
17
|
+
## Vite plugin
|
|
18
|
+
|
|
19
|
+
If your frontend uses Vite, this is the recommended path: skip the separate CLI process entirely. The `@supabase/lite/vite` plugin mounts `/auth/v1`, `/rest/v1`, and `/_system` directly on the Vite dev server, so one process serves both your app and the API.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// vite.config.ts
|
|
23
|
+
import { defineConfig } from "vite";
|
|
24
|
+
import { supalite } from "@supabase/lite/vite";
|
|
25
|
+
|
|
26
|
+
export default defineConfig({
|
|
27
|
+
plugins: [supalite()],
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Active in `vite` / `vite dev` (watches schemas, hot-reloads) and `vite preview` (mounts the API and runs boot migrations, but does not watch schemas, it simulates production). `vite build` and any standalone production server do not mount the API; use `lite start`, hosted Supabase, or an equivalent there.
|
|
32
|
+
|
|
33
|
+
Full setup and env-var injection details: [Vite integration](/integrations/vite).
|
|
34
|
+
|
|
35
|
+
## `lite dev`
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
lite dev
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Starts the API server as its own process and watches `supabase/schemas/*.sql`, re-applying the schema automatically on every change. Use this for non-Vite apps (plain Node/Bun backends, mobile clients hitting a local API, etc.) during active development.
|
|
42
|
+
|
|
43
|
+
Both CLI servers bind `127.0.0.1` by default. The host flag matches Vite: `--host` listens on `0.0.0.0`, while `--host <address>` selects a specific interface.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
lite dev --host --no-admin # reachable from containers/LAN; normal auth only
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
By default, auth emails (signup confirmation, magic link, password recovery, and so on) are printed to this server console rather than actually sent. See [Email delivery & templates](/auth/email).
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
lite db reset --hard # delete the DB file, replay migrations + seed
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## `lite start`
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
lite start
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Starts the API server with no file watching and no auto-migration. This is the closest Supabase Lite gets to a production-like posture: you control exactly when migrations run (`lite migration up`, `lite db reset`), and the server won't silently reapply schema changes. Use this for CI pipelines and any environment meant to behave like production.
|
|
62
|
+
|
|
63
|
+
On the `sqlite-postgres` driver, the ordered SQL in `supabase_migrations.schema_migrations` is the sole startup authority. `lite start` hashes the recorded `{version, statements}` values, restores a matching migration-derived `supabase/.temp/.runtime-metadata-cache.json`, or fully rebuilds fields, enums, constraints, comments, variables, relationships, RLS tables, and policies from that history. It never reads migration files or `supabase/schemas/*.sql`, so pending files and edits or deletions of already-applied files have no effect.
|
|
64
|
+
|
|
65
|
+
The runtime metadata cache is disposable. Missing, corrupt, old, stale, or tampered files rebuild automatically. During a rebuild, Supabase Lite also replays the recorded SQL into an in-memory SQLite database and compares that raw structure with the live database. Invalid history or out-of-band structural DDL makes `lite start` exit with a `lite db reset` hint; live introspection is never used as a metadata source.
|
|
66
|
+
|
|
67
|
+
`lite dev` and the Vite plugin remain declarative workflows: they apply pending migrations, reconcile the current `schemas/*.sql`, and replace runtime metadata from the schema they actually applied. `lite start` ignores that declarative state. If declarative changes made the live structure differ from applied migration history, generate a migration with `lite db diff -f <name>` and use `lite db reset` to establish a clean migration-derived database before running `lite start`.
|
|
68
|
+
|
|
69
|
+
## Admin mode
|
|
70
|
+
|
|
71
|
+
Loopback `lite dev`, `lite start`, and Vite dev listeners run with **admin mode on**. A request that arrives with no credential at all (no `apikey` header or query parameter, no `Authorization` header) is served as `service_role`, so a local admin UI like the built-in studio can read and edit any table without a secret key ever reaching the browser. This mirrors self-hosted Supabase Studio, where the Next.js server holds the service key and does the privileged work on the client's behalf.
|
|
72
|
+
|
|
73
|
+
Elevation is deliberately narrow. A request is only elevated when all of these hold:
|
|
74
|
+
|
|
75
|
+
- the path is under `/rest/v1` or `/storage/v1` (`/auth/v1` is never elevated). The Vite plugin does not mount `/storage/v1` by default, so there it's `/rest/v1` only
|
|
76
|
+
- it carries no `apikey` and no `Authorization`
|
|
77
|
+
- it is same-origin, or has no `Origin` header at all (so `curl` works, but another website open in your browser does not)
|
|
78
|
+
- it arrived from a loopback socket **and** names a loopback host. Both are required: the peer address stops a machine on your network spoofing `Host: localhost`, and the hostname stops DNS rebinding, where a hostile page re-resolves its own domain to `127.0.0.1` so the socket really is loopback while `Host` and `Origin` stay theirs
|
|
79
|
+
|
|
80
|
+
Anything else falls through to normal [API key enforcement](/auth/overview#api-keys).
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
lite start --no-admin # loopback, admin explicitly off
|
|
84
|
+
lite start --host # all interfaces, admin defaults off and warns
|
|
85
|
+
lite start --host --no-admin # all interfaces, explicit/silent opt-out
|
|
86
|
+
lite start --host --admin # all interfaces, local peers retain admin
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Two things to know:
|
|
90
|
+
|
|
91
|
+
1. **Keyless traffic does not go through RLS while admin mode is on.** To exercise your policies, send an `apikey` — the publishable key for `anon`, or the publishable key **plus** `Authorization: Bearer <user JWT>` for `authenticated`. Those requests are never elevated, so both roles behave exactly as they do in production. That is the whole reason elevation is credential-aware rather than blanket. A bearer token on its own is not enough: with keys configured, a request without an `apikey` is rejected before RLS is reached (401 `UNAUTHORIZED_MISSING_API_KEY`), matching upstream.
|
|
92
|
+
2. **Exposing a server changes the default.** A non-loopback `--host` disables admin mode unless `--admin` is explicit. With neither admin flag, Lite warns that exposure disabled admin and shows both choices. Vite applies the same rule when its resolved host is non-loopback.
|
|
93
|
+
3. **A public tunnel erases locality.** A sandbox or tunnel can publish a loopback listener and forward traffic over a local socket. Run with `--no-admin` whenever another system exposes the port; socket locality cannot authenticate the original remote user through a proxy.
|
|
94
|
+
|
|
95
|
+
On a loopback CLI listener, precedence is explicit `--admin`/`--no-admin`, then `options.server.admin`, then the on-by-default launcher value. A non-loopback `--host` forces admin off unless `--admin` is present, so config cannot silently re-enable it. For Vite, an exposed host similarly requires the explicit `supalite({ admin: true })` option.
|
|
96
|
+
|
|
97
|
+
Embedding `App` without request context applies only the hostname check. An adapter that owns a listener should call `app.fetch(request, { peerAddress })`; a null peer fails closed. Only enable admin on a loopback-bound server.
|
|
98
|
+
|
|
99
|
+
With admin mode off, the bundled studio connects with the publishable key instead and shows you what `anon` can see under RLS, with a banner saying so — it stays usable, just scoped.
|
|
100
|
+
|
|
101
|
+
## Embedded / programmatic
|
|
102
|
+
|
|
103
|
+
For full control, skip the CLI entirely and embed the app directly in your own Bun, Node, browser, or edge runtime:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { App } from "@supabase/lite";
|
|
107
|
+
import { createConnection } from "@supabase/lite/sqlite";
|
|
108
|
+
|
|
109
|
+
const connection = await createConnection({ url: "file:./data.db" });
|
|
110
|
+
const app = new App({ connection, auth: { enabled: true } });
|
|
111
|
+
|
|
112
|
+
const schema = await Bun.file("./schema.sql").text();
|
|
113
|
+
await app.connection.createMigrator(schema).migrate();
|
|
114
|
+
|
|
115
|
+
export default app; // app.fetch handles requests
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This is the path for custom server frameworks, Cloudflare Workers/Durable Objects, or any setup where you need to control the boot sequence yourself rather than delegating to the CLI or the Vite plugin. See [Embedded / programmatic](/integrations/embedded) for supported runtimes and drivers.
|
|
119
|
+
|
|
120
|
+
## Choosing
|
|
121
|
+
|
|
122
|
+
- Building a Vite app? Use the [Vite plugin](/integrations/vite). Stop here.
|
|
123
|
+
- Building anything else, and want schema changes to apply automatically while you iterate? Use `lite dev`.
|
|
124
|
+
- Deploying, running in CI, or want explicit control over migrations? Use `lite start`.
|
|
125
|
+
- Building your own server, or targeting a runtime the CLI doesn't drive directly (Workers, Durable Objects)? Use the [embedded API](/integrations/embedded).
|
|
126
|
+
|
|
127
|
+
Whichever mode you pick, run exactly one backend per project. Never run `lite dev` and `lite start` together, or either alongside the Vite plugin. Two backends over the same SQLite file race migrations and schema watchers even when they do not share a port.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Storage adapters"
|
|
3
|
+
description: "Pluggable storage backends (filesystem, S3-compatible) and transformation adapters (Noop, Sharp, Cloudflare) for Supabase Lite Storage."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
import { Aside } from '@astrojs/starlight/components';
|
|
7
|
+
|
|
8
|
+
Supabase Lite's Storage API separates *where bytes live* (storage adapters) from *how images get resized* (transformation adapters). Both are supabase-js-invisible: the same `supabase.storage.from(...).upload()` call works no matter which adapter is wired up server-side. This adapter split is a Supabase Lite-specific implementation detail; there's no equivalent concept to configure in hosted Supabase.
|
|
9
|
+
|
|
10
|
+
<Aside type="note">
|
|
11
|
+
Storage is experimental. See [Storage overview](/storage/overview) for the `EXPERIMENTAL_STORAGE` flag and the config required before any adapter matters.
|
|
12
|
+
</Aside>
|
|
13
|
+
|
|
14
|
+
## Storage adapters
|
|
15
|
+
|
|
16
|
+
Where object bytes are physically stored.
|
|
17
|
+
|
|
18
|
+
| Adapter | Status | Notes |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| Filesystem | Supported | Local disk. Default for `lite dev` / `lite start` under `.temp/storage`. |
|
|
21
|
+
| S3 / S3-compatible | Supported | MinIO, AWS S3, Cloudflare R2, via [`aws4fetch`](https://github.com/lquixada/aws4fetch), not the AWS SDK. |
|
|
22
|
+
| Cloudflare R2 | Supported | Uses the S3 adapter with R2's S3-compatible endpoint. |
|
|
23
|
+
|
|
24
|
+
### Filesystem
|
|
25
|
+
|
|
26
|
+
Set programmatically on the `App` instance:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { FilesystemStorageAdapter } from "@supabase/lite/storage/adapters/FilesystemStorageAdapter";
|
|
30
|
+
|
|
31
|
+
app._storageAdapter = new FilesystemStorageAdapter({
|
|
32
|
+
basePath: "./supabase/.temp/storage",
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
This is what the `lite` CLI wires up automatically when `EXPERIMENTAL_STORAGE=1` and `storage.enabled` are set: object bytes land under `<config_dir>/.temp/storage/<bucket>/<key>`.
|
|
37
|
+
|
|
38
|
+
### S3-compatible
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { S3StorageAdapter } from "@supabase/lite/storage/adapters/S3StorageAdapter";
|
|
42
|
+
|
|
43
|
+
app._storageAdapter = new S3StorageAdapter({
|
|
44
|
+
accessKeyId: process.env.S3_ACCESS_KEY_ID!,
|
|
45
|
+
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
|
|
46
|
+
endpoint: "https://<account>.r2.cloudflarestorage.com",
|
|
47
|
+
region: "auto",
|
|
48
|
+
bucket: "my-bucket", // optional: scope all operations to one S3 bucket
|
|
49
|
+
forcePathStyle: true, // required for MinIO and some S3-compatible providers
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`endpoint` and `region` point at whichever S3-compatible provider you use (AWS S3, MinIO, Cloudflare R2). `forcePathStyle` switches between virtual-hosted-style and path-style URLs; enable it for MinIO and most self-hosted S3-compatible servers.
|
|
54
|
+
|
|
55
|
+
For the S3 API surface this adapter targets on the wire, see [Supabase Storage S3 compatibility](https://supabase.com/docs/guides/storage/s3/compatibility). Note that's about Supabase's own S3-compatible *server* endpoint, which Supabase Lite does not yet implement server-side (see [Storage limitations](/storage/limitations)); this adapter is Supabase Lite acting as an S3 *client* to store bytes remotely.
|
|
56
|
+
|
|
57
|
+
## Transformation adapters
|
|
58
|
+
|
|
59
|
+
How (and whether) images get resized/reformatted on read.
|
|
60
|
+
|
|
61
|
+
| Adapter | Status | Notes |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| Noop | Supported | Passthrough: no transforms, returns the original bytes. Default. |
|
|
64
|
+
| Sharp | Supported | Resize + format conversion via [`sharp`](https://sharp.pixelplumbing.com/), in-process. Requires `sharp` as an optional dependency in your project. |
|
|
65
|
+
| Cloudflare | Supported | Delegates to [Cloudflare Image Resizing](https://developers.cloudflare.com/images/transform-images/transform-via-workers/) via `fetch` with `cf.image` options; no image-processing library, works in Workers. |
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { SharpTransformationAdapter } from "@supabase/lite/storage/transformations/SharpTransformationAdapter";
|
|
69
|
+
|
|
70
|
+
app._transformationAdapter = new SharpTransformationAdapter();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Pick Sharp for Node/Bun deployments where you want image transforms without an external image proxy, and Cloudflare's adapter when running on Workers, where Cloudflare's edge already handles resizing and a native image library isn't available. Leave the default Noop adapter if you don't need `?width=`/`?height=` transforms at all.
|
|
74
|
+
|
|
75
|
+
For the transform options themselves (`width`, `height`, `resize`, `format`, `quality`) and how they're requested from the client, see [Supabase image transformations](https://supabase.com/docs/guides/storage/serving/image-transformations).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Storage limitations"
|
|
3
|
+
description: "What's not yet implemented in Supabase Lite Storage: TUS uploads, webhooks, bucket-list query params, and the S3-compatible server protocol."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Storage is [experimental](/storage/overview) and behind the `EXPERIMENTAL_STORAGE` flag. Everything below is a gap on top of that: even with the flag on and an adapter wired up, these features don't exist yet.
|
|
7
|
+
|
|
8
|
+
## Not yet implemented
|
|
9
|
+
|
|
10
|
+
| Feature | Notes |
|
|
11
|
+
|---|---|
|
|
12
|
+
| Bucket list query params | `GET /bucket` doesn't yet accept `?search=`, `?limit=`, `?offset=`. |
|
|
13
|
+
| S3-compatible protocol (server side) | No `PUT`/`GET`/`DELETE` under `/storage/v1/s3/*`. Supabase Lite can act as an S3 *client* via the [S3 storage adapter](/storage/adapters), but doesn't expose an S3-compatible server. |
|
|
14
|
+
| TUS resumable uploads | No `POST`/`PATCH`/`HEAD` on `/upload/resumable`. |
|
|
15
|
+
| Webhooks | No `ObjectCreated`/`ObjectRemoved` event delivery. |
|
|
16
|
+
|
|
17
|
+
## Workaround
|
|
18
|
+
|
|
19
|
+
For any of the above, run the storage-dependent parts of your app against hosted Supabase and keep the rest (Data API, Auth) on Supabase Lite. Mixed backends are a normal transitional setup, not something you need to migrate wholesale for.
|
|
20
|
+
|
|
21
|
+
For Storage access-control policies, see [Supabase Storage access control](https://supabase.com/docs/guides/storage/security/access-control); Supabase Lite supports that model across SQLite, PGlite, and PostgreSQL. For what is implemented today, see [Storage overview](/storage/overview) and [Storage adapters](/storage/adapters).
|