Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 21 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,42 +56,47 @@ mkdir my_app_name
cd my_app_name
```

### 2. Set up a virtual environment
### 2. Install uv

Create and activate virtual environment
Reflex recommends [uv](https://docs.astral.sh/uv/) for managing your project environment and dependencies.
See the [uv installation docs](https://docs.astral.sh/uv/getting-started/installation/) for your platform.

```bash
# On Windows:
python -m venv .venv
.venv\Scripts\activate
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# On macOS/Linux:
python3 -m venv .venv
source .venv/bin/activate
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

### 3. Install Reflex
### 3. Initialize the Python project

Reflex is available as a pip package (Requires Python 3.10+):
```bash
uv init
```

### 4. Add Reflex

Reflex requires Python 3.10+:

```bash
pip install reflex
uv add reflex
```

### 4. Initialize the project
### 5. Initialize the project

This command initializes a template app in your new directory:

```bash
reflex init
uv run reflex init
```

### 5. Run the app
### 6. Run the app

You can run this app in development mode:

```bash
reflex run
uv run reflex run
```

You should see your app running at http://localhost:3000.
Expand All @@ -100,7 +105,7 @@ Now you can modify the source code in `my_app_name/my_app_name.py`. Reflex has f

### Troubleshooting

If you installed Reflex without a virtual environment and the `reflex` command is not found, you can run commands using: `python3 -m reflex init` and `python3 -m reflex run`
If the `reflex` command is not on your PATH, run it through uv instead: `uv run reflex init` and `uv run reflex run`

## 🫧 Example App

Expand Down
26 changes: 26 additions & 0 deletions packages/reflex-base/src/reflex_base/compiler/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,32 @@ def rxconfig_template(app_name: str):
)"""


def pyproject_toml_template(
app_name: str,
reflex_version: str,
*,
project_version: str = constants.PyprojectToml.DEFAULT_VERSION,
requires_python: str = constants.PyprojectToml.REQUIRES_PYTHON,
):
"""Template for a Reflex app pyproject.toml.

Args:
app_name: The name of the application.
reflex_version: The Reflex version to pin.
project_version: The version for the initialized app.
requires_python: The supported Python range for the initialized app.

Returns:
Rendered pyproject.toml content as string.
"""
return f"""[project]
name = "{app_name}"
version = "{project_version}"
requires-python = "{requires_python}"
dependencies = ["reflex=={reflex_version}"]
"""


def document_root_template(*, imports: list[_ImportDict], document: dict[str, Any]):
"""Template for the document root.

Expand Down
4 changes: 4 additions & 0 deletions packages/reflex-base/src/reflex_base/constants/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ class PyprojectToml(SimpleNamespace):

# The pyproject.toml file.
FILE = "pyproject.toml"
# The default version used for newly initialized apps.
DEFAULT_VERSION = "0.1.0"
# The default supported Python range for newly initialized apps.
REQUIRES_PYTHON = ">=3.10"


class RequirementsTxt(SimpleNamespace):
Expand Down
2 changes: 1 addition & 1 deletion reflex/docs/advanced_onboarding/code_structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ example-big-app/
│ ├─ state.py
│ ├─ template.py
├─ uploaded_files/
├─ requirements.txt
├─ pyproject.toml
├─ rxconfig.py
```

Expand Down
8 changes: 4 additions & 4 deletions reflex/docs/advanced_onboarding/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Reflex apps can be configured using a configuration file, environment variables,

## Configuration File

Running `reflex init` will create an `rxconfig.py` file in your root directory.
Running `uv run reflex init` will create an `rxconfig.py` file in your root directory.
You can pass keyword arguments to the `Config` class to configure your app.

For example:
Expand All @@ -31,15 +31,15 @@ You can override the configuration file by setting environment variables.
For example, to override the `frontend_port` setting, you can set the `FRONTEND_PORT` environment variable.

```bash
FRONTEND_PORT=3001 reflex run
FRONTEND_PORT=3001 uv run reflex run
```

## Command Line Arguments

Finally, you can override the configuration file and environment variables by passing command line arguments to `reflex run`.
Finally, you can override the configuration file and environment variables by passing command line arguments to `uv run reflex run`.

```bash
reflex run --frontend-port 3001
uv run reflex run --frontend-port 3001
```

See the [CLI reference](/docs/api-reference/cli) for all the arguments available.
Expand Down
4 changes: 2 additions & 2 deletions reflex/docs/advanced_onboarding/how-reflex-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ rx.box(height="1em")

We wanted Reflex apps to look and feel like a traditional web app to the end user, while still being easy to build and maintain for the developer. To do this, we built on top of mature and popular web technologies.

When you `reflex run` your app, Reflex compiles the frontend down to a single-page [Next.js](https://nextjs.org) app and serves it on a port (by default `3000`) that you can access in your browser.
When you run `uv run reflex run`, Reflex compiles the frontend down to a single-page [Next.js](https://nextjs.org) app and serves it on a port (by default `3000`) that you can access in your browser.

The frontend's job is to reflect the app's state, and send events to the backend when the user interacts with the UI. No actual logic is run on the frontend.

Expand Down Expand Up @@ -128,7 +128,7 @@ Beyond this, Reflex components can be styled using the full power of CSS. We lev

Now let's look at how we added interactivity to our apps.

In Reflex only the frontend compiles to Javascript and runs on the user's browser, while all the state and logic stays in Python and is run on the server. When you `reflex run`, we start a FastAPI server (by default on port `8000`) that the frontend connects to through a websocket.
In Reflex only the frontend compiles to Javascript and runs on the user's browser, while all the state and logic stays in Python and is run on the server. When you run `uv run reflex run`, we start a FastAPI server (by default on port `8000`) that the frontend connects to through a websocket.

All the state and logic are defined within a `State` class.

Expand Down
4 changes: 2 additions & 2 deletions reflex/docs/getting_started/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ This page gives an introduction to the most common concepts that you will use to
- Create pages and navigate between them
```

[Install](/docs/getting_started/installation) `reflex` using pip.
[Install](/docs/getting_started/installation) `reflex` with uv before continuing.

```bash
pip install reflex
uv add reflex
```

Import the `reflex` library to get started.
Expand Down
4 changes: 2 additions & 2 deletions reflex/docs/getting_started/dashboard_tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,9 @@ Don't worry if you don't understand the code above, in this tutorial we are goin

## Setup for the tutorial

Check out the [installation docs](/docs/getting_started/installation) to get Reflex set up on your machine. Follow these to create a folder called `dashboard_tutorial`, which you will `cd` into and `pip install reflex`.
Check out the [installation docs](/docs/getting_started/installation) to get Reflex set up on your machine. Follow these to create a folder called `dashboard_tutorial`, which you will `cd` into, then run `uv init` and `uv add reflex`.

We will choose template `0` when we run `reflex init` to get the blank template. Finally run `reflex run` to start the app and confirm everything is set up correctly.
We will choose template `0` when we run `uv run reflex init` to get the blank template. Finally run `uv run reflex run` to start the app and confirm everything is set up correctly.

## Overview

Expand Down
25 changes: 21 additions & 4 deletions reflex/docs/getting_started/project-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,36 @@ Let's create a new app called `{app_name}`
```bash
mkdir {app_name}
cd {app_name}
reflex init
uv init
uv add reflex
uv run reflex init
```

This will create a directory structure like this:

```bash
{app_name}
├── .venv
├── .web
├── assets
├── {app_name}
│ ├── __init__.py
│ └── {app_name}.py
└── rxconfig.py
├── .gitignore
├── .python-version
├── pyproject.toml
├── rxconfig.py
└── uv.lock
```

`uv init` may also create helper files such as `README.md`, `main.py`, and Git metadata. The tree above focuses on the main files you will interact with while building a Reflex app.

Let's go over each of these directories and files.

## .venv

`uv add reflex` creates a local virtual environment in `.venv` by default. This keeps your app dependencies isolated from the rest of your system Python.

## .web

This is where the compiled Javascript files will be stored. You will never need to touch this directory, but it can be useful for debugging.
Expand All @@ -45,14 +58,18 @@ For example, if you save an image to `assets/image.png` you can display it from
rx.image(src="https://web.reflex-assets.dev/other/image.png")
```

j

## Main Project

Initializing your project creates a directory with the same name as your app. This is where you will write your app's logic.

Reflex generates a default app within the `{app_name}/{app_name}.py` file. You can modify this file to customize your app.

## Python Project Files

`pyproject.toml` defines your Python project metadata and dependencies. Reflex pins its own version here when you initialize a new app.

`uv.lock` stores the fully resolved dependency set for reproducible installs. Commit it to version control so everyone working on the app gets the same Python package versions.

## Configuration

The `rxconfig.py` file can be used to configure your app. By default it looks something like this:
Expand Down
29 changes: 20 additions & 9 deletions reflex/reflex.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,30 @@ def _init(
# Initialize the .gitignore.
frontend_skeleton.initialize_gitignore()

# Initialize the requirements.txt.
needs_user_manual_update = frontend_skeleton.initialize_requirements_txt()
# Initialize the Python dependency manifest.
manifest = frontend_skeleton.initialize_python_manifest(app_name=app_name)

template_msg = f" using the {template} template" if template else ""
# Finish initializing the app.
console.success(
f"Initialized {app_name}{template_msg}."
+ (
f" Make sure to add {constants.RequirementsTxt.DEFAULTS_STUB + constants.Reflex.VERSION} to your requirements.txt or pyproject.toml file."
if needs_user_manual_update
reflex_dependency_pin = (
f"{constants.Reflex.MODULE_NAME}=={constants.Reflex.VERSION}"
)
if manifest.kind == "pyproject":
next_steps = " Run `uv sync` to install dependencies and `uv run reflex run` to start the app."
manual_update = (
f" Make sure to add `{reflex_dependency_pin}` to your pyproject.toml dependencies before running `uv sync`."
if manifest.needs_manual_reflex_dependency
else ""
)
)
else:
next_steps = " Install dependencies from `requirements.txt` with `uv pip install -r requirements.txt` (or your preferred installer) before running the app."
manual_update = (
f" Make sure to add `{reflex_dependency_pin}` to your requirements.txt file."
if manifest.needs_manual_reflex_dependency
else ""
)

# Finish initializing the app.
console.success(f"Initialized {app_name}{template_msg}.{manual_update}{next_steps}")


@cli.command()
Expand Down
Loading