Files
supabase/apps/docs/content/guides/getting-started/quickstarts/reflex.mdx
T
Palash AwasthiandNik Richers 165582b08e docs: add Reflex framework quickstart (#45441)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Docs update — adds a new framework quickstart.

## What is the current behavior?

The Framework Quickstarts section under Getting Started covers Next.js,
Nuxt, React, Flask, and others, but doesn't include Reflex
(https://reflex.dev), an open-source Python web framework that compiles
to React. Python developers building full-stack apps with Reflex have to
piece together the Supabase setup from the general Python reference
rather than following a quickstart.

## What is the new behavior?

Adds a Reflex framework quickstart at
`apps/docs/content/guides/getting-started/quickstarts/reflex.mdx`,
mirroring the structure of the existing Flask quickstart: same DB setup
partial (`quickstart_db_setup.mdx`), same env var step using
`ProjectConfigVariables`, same six-step `StepHikeCompact` shape. A nav
entry is added directly after Flask in `NavigationMenu.constants.ts`,
gated on `!jsOnly` to match Flask's pattern.

Verified end-to-end against a fresh Supabase project: ran every command
in the docs literally, including the full SQL from
`quickstart_db_setup.mdx` (with the `grant select on public.instruments
to anon` line). The rendered Reflex app shows the Instruments heading
with all three seeded rows. No console errors, no event-loop warnings.

## Additional context

Conventions used in the quickstart:

- Uses `uv` (`uv init`, `uv add`, `uv run`) rather than pip + venv. This
follows the broader docs pattern of each quickstart using its
framework's idiomatic tooling (Next.js → npx, RedwoodJS → yarn, Laravel
→ composer, Flutter → pubspec.yaml). It also matches what Reflex's own
`reflex init` post-install message recommends. `uv add` produces a
`pyproject.toml` and `uv.lock` so users can rebuild deterministically
with `uv sync`.
- The Supabase client is constructed via `acreate_client` with a
lazy-init pattern, and the event handler is `async def`. This avoids
blocking Reflex's event loop on the HTTP request.

In touch with the Supabase team on this — happy to iterate on copy or
scope based on review.

Pre-flight: ran pnpm run format locally, which passed cleanly. Did not
run pnpm run build locally — hit a Windows/CRLF-related TOML parsing
failure in an unrelated troubleshooting frontmatter file
(apps/docs/content/troubleshooting/all-about-supabase-egress-a_Sg_e.mdx)
during page data collection. Relying on Vercel preview to validate the
build.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Added Reflex (Python) and Spring Boot to the framework quickstarts.
* Reorganized quickstart listings for clearer framework navigation and
grouping.

* **Documentation**
* Added a Reflex quickstart guide covering Supabase setup, environment
variables, asynchronous data loading, error handling, and running the
app.
  * Added Reflex-specific AI guidance for configuring Supabase projects.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Nik Richers <nik@validmind.ai>
2026-09-09 23:35:24 +00:00

131 lines
3.8 KiB
Plaintext

---
title: 'Use Supabase with Reflex'
subtitle: 'Learn how to create a Supabase project, add some sample data to your database, and query the data from a Reflex app.'
breadcrumb: 'Framework Quickstarts'
---
<AiPrompt id="reflex" />
<$Partial path="quickstart_db_setup.mdx" />
## 3. Create a Reflex app
Create a new directory for your Reflex app, initialize a project with `uv`, add Reflex as a dependency, and scaffold a blank app with `--template blank`.
```bash
mkdir my_app && cd my_app
uv init
uv add reflex
uv run reflex init --template blank
```
## 4. Set up AI tooling (optional)
<$Partial path="quickstart_ai_tooling.mdx" />
## 5. Install the Supabase client library
The fastest way to get started is to use the `supabase-py` client library, which provides a convenient interface for working with Supabase from a Reflex app.
Install `supabase-py` and `python-dotenv` to load environment variables.
```bash
uv add supabase python-dotenv
```
## 6. Declare Supabase environment variables
Create a `.env` file in your project root and populate it with your Supabase connection variables that you can get from the helper below, or [from the project **Connect** panel](/dashboard/project/_?showConnect=true&connectTab=frameworks):
<Button variant="primary" asChild>
<a href="/dashboard/project/_?showConnect=true&connectTab=frameworks">Open Connect panel</a>
</Button>
```text name=.env
SUPABASE_URL=<SUBSTITUTE_SUPABASE_URL>
SUPABASE_PUBLISHABLE_KEY=<SUBSTITUTE_SUPABASE_PUBLISHABLE_KEY>
```
<$Partial path="api_settings.mdx" variables={{ "framework": "", "tab": "" }} />
## 7. Create the Supabase client
Open `my_app/my_app.py` and add the following code to create an async Supabase client from your environment variables. Reflex's event handlers run inside an async event loop, so the client is created once with `acreate_client` and reused across requests, rather than recreated per page load.
```python name=my_app/my_app.py
import os
import reflex as rx
from supabase import acreate_client, AsyncClient
from dotenv import load_dotenv
load_dotenv()
_supabase: AsyncClient | None = None
async def get_supabase() -> AsyncClient:
global _supabase
if _supabase is None:
_supabase = await acreate_client(
os.environ.get("SUPABASE_URL"),
os.environ.get("SUPABASE_PUBLISHABLE_KEY"),
)
return _supabase
```
## 8. Query data from the app
Add a `State` class that holds the query result, an async event handler that fetches data from your `instruments` table, and a page that renders the result. `on_load` triggers the handler when the page is opened.
```python name=my_app/my_app.py
from postgrest import APIError
class State(rx.State):
instruments: list[dict] = []
error: str = ""
async def load_instruments(self):
supabase = await get_supabase()
try:
response = await supabase.table("instruments").select("*").execute()
except APIError as error:
self.error = f"Error loading instruments: {error.message}"
return
self.instruments = response.data
def index() -> rx.Component:
return rx.container(
rx.heading("Instruments"),
rx.cond(
State.error,
rx.text(State.error),
rx.foreach(
State.instruments,
lambda instrument: rx.text(instrument["name"]),
),
),
)
app = rx.App()
app.add_page(index, on_load=State.load_instruments)
```
## 9. Start the app
Run the Reflex development server, go to http://localhost:3000 in a browser, and you should see the list of instruments.
```bash
uv run reflex run
```
<$Partial path="quickstart_going_to_production.mdx" />
## Next steps
- Set up [Auth](/docs/guides/auth) for your app
- [Insert more data](/docs/guides/database/import-data) into your database
- Upload and serve static files using [Storage](/docs/guides/storage)