Skip to main content

reflex-threejs

Interactive three.js for Reflex — in pure Python.

reflex-threejs wraps React Three Fiber (the React renderer for three.js) and its helper library drei as idiomatic Reflex components. Build 3D scenes — product viewers, data visualization, generative art, simulations — without writing a line of JavaScript.

Status: alpha (v0.3.0) — foundation, core components, demo app and full SDD artifacts are in place. See the roadmap.


Why

three.js is the standard for web 3D, but it is imperative and JavaScript-only. React Three Fiber makes it declarative — yet still React/JSX. Reflex compiles Python to React, so wrapping R3F + drei once makes the entire three.js model available to Python developers as ordinary Reflex components.

import reflex as rx
from reflex_threejs import three


def index() -> rx.Component:
    return rx.box(
        three.canvas(
            three.ambient_light(intensity=0.6),
            three.directional_light(position=[5, 5, 5], intensity=1.0),
            three.mesh(
                three.box_geometry(args=[1.5, 1.5, 1.5]),
                three.mesh_standard_material(color="#6366f1", metalness=0.3),
            ),
            three.orbit_controls(auto_rotate=True),
            camera={"position": [3, 3, 3], "fov": 50},
        ),
        width="100%",
        height="600px",
    )


app = rx.App()
app.add_page(index)

Features

  • Declarative scene graph — Canvas, meshes, groups, points, lines, sprites, instancing — all from Python.
  • Full primitive surface — 22 geometries, 14 materials, 6 lights, cameras and helpers, each accepting three.js constructor args.
  • Interaction — pointer events (on_click, on_pointer_over, …) routed to Reflex event handlers.
  • State binding — drive any prop (color, transform, …) with a Reflex state Var.
  • drei helpers — OrbitControls, Environment/Stage, ContactShadows, Sky, Stars, Text, Html overlay, Float, animated materials and declarative GLTF loading.
  • Ergonomic API — flat factories or the three.* namespace mirroring rx.*.
  • SSR-safe — the WebGL Canvas is dynamically imported (ssr:false).

Installation

pip install reflex-threejs        # or: uv add reflex-threejs

From source:

git clone https://github.com/ecrespo/reflex-threejs.git
cd reflex-threejs
pip install -e .

Requirements:

  • Python ≥ 3.11
  • Reflex ≥ 0.10 (bundles React 19.3)
  • Node.js ≥ 22.22 for Reflex to build the frontend (Node 24 LTS recommended)

Reflex 0.7–0.9 users can stay on reflex-threejs 0.2.x. On an older Reflex/React 18 stack, see the compatibility guide.

Run the demo

The demo app showcases nine scenes spanning the main three.js example categories.

cd reflex_threejs_demo
pip install -r requirements.txt   # installs reflex + the local package
reflex init                       # first run only
reflex run

Then open http://localhost:3000.

Route Scene Demonstrates
/ Hello Cube Canvas, lights, mesh, OrbitControls
/geometries Geometry Gallery built-in geometries
/materials Materials material types + environment
/lights Lights ambient/directional/point/spot + shadows
/interactive Interactive click-to-recolor, hover-to-scale (state events)
/particles Particles points + buffer geometry
/staging Staging & drei Stage, ContactShadows, distort material
/text 3D Text drei Text + Float
/space Space drei Stars, emissive material

Two ways to use the API

# 1. Namespace (rx-style)
from reflex_threejs import three
three.canvas(three.mesh(three.box_geometry(), three.mesh_normal_material()))

# 2. Flat factories
from reflex_threejs import canvas, mesh, box_geometry, mesh_normal_material
canvas(mesh(box_geometry(), mesh_normal_material()))

drei helpers live under three.drei.* (common ones promoted to three.*).

Documentation

Project layout

reflex-threejs/
├── custom_components/reflex_threejs/   # the component library (Reflex convention)
│   ├── base.py        canvas.py        objects.py
│   ├── geometries.py  materials.py     lights.py
│   ├── cameras.py     drei.py          namespace.py
│   ├── *.pyi          py.typed         # generated type stubs + PEP 561 marker
│   └── __init__.py
├── reflex_threejs_demo/                # runnable demo app
├── tests/                              # contract + quality-gate tests
├── scripts/gen_pyi.py                  # regenerate the .pyi stubs
├── docs/
│   ├── sdd/                            # SDD artifacts
│   └── guides/                         # usage & compatibility
├── Makefile  pyproject.toml  README.md  LICENSE  CHANGELOG.md

This follows the classic Reflex custom-component layout (package under custom_components/, a sibling demo app). It is a plain setuptools project, so it builds with python -m build and needs no Reflex-specific packaging CLI.

How it works (in one paragraph)

Canvas is wrapped as a Reflex NoSSRComponent, so three.js initializes only in the browser. Everything inside it — <mesh>, <boxGeometry>, <meshStandardMaterial>, <ambientLight> — are React Three Fiber host elements: lowercase intrinsic JSX tags resolved by R3F's reconciler at runtime, requiring no import. We model these as Reflex components with library = None and _is_tag_in_global_scope = True, so Reflex emits the tag as a string intrinsic (jsx("mesh", …)) rather than an undefined component reference. drei helpers are real exported components, so they declare the @react-three/drei package and an explicit tag. See the architecture doc for details.

Building & publishing (Reflex custom component)

reflex-threejs is a Reflex custom component packaged as a regular Python distribution: the package lives under custom_components/ and ships .pyi type stubs and a py.typed marker.

Reflex 0.10 removed the reflex component CLI (init/build/publish/ share). This repo does not depend on it: scripts/gen_pyi.py runs Reflex's own PyiGenerator for the stubs, and the wheel/sdist come from python -m build.

make install        # pip install -e ".[dev]"
make check          # ruff + pytest
make stubs          # regenerate .pyi stubs after changing any component props
make build          # regenerate stubs, then build wheel + sdist, then twine check

CI (.github/workflows/ci.yml, all actions on Node 24) runs on every push and PR to main/develop:

  • lint-and-test — ruff, py_compile and pytest on Python 3.11–3.13;
  • package — regenerates the stubs, fails if the committed ones are stale, builds the wheel + sdist and runs twine check;
  • demo — installs the demo with Node 24 and runs reflex export.

Releasing

Releases are published by .github/workflows/publish.yml using PyPI Trusted Publishing (no API token in the repo):

  1. Bump version in pyproject.toml and add a CHANGELOG.md entry on develop.

  2. Open a PR develop → main; merge once CI is green.

  3. Tag the merge commit on main and push the tag:

    git checkout main && git pull
    git tag -a v0.3.0 -m "reflex-threejs 0.3.0"
    git push origin v0.3.0
    

The workflow checks that the tag is on main and matches the pyproject.toml version, re-runs lint/tests/stub check, builds, uploads to PyPI (environment pypi) and creates the GitHub release with the built artifacts.

One-time setup on PyPI → reflex-threejs → Publishing: add a GitHub trusted publisher with owner ecrespo, repository reflex-threejs, workflow publish.yml and environment pypi.

make publish (twine upload) remains as a manual fallback.

Contributing

Issues and PRs welcome. The design lives in docs/sdd; please keep specs and code in sync (it's in the Definition of Done). After changing any component's props, run make stubs and commit the updated .pyi.

License

MIT © 2026 Ernesto Crespo.

Acknowledgements

Built on the work of three.js, pmndrs/react-three-fiber, pmndrs/drei and Reflex.

Metadata

Release files for reflex-threejs 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for reflex-threejs 0.3.0
File Size Uploaded Provenance Actions
reflex_threejs-0.3.0.tar.gz 40.9 kB With provenance Details for reflex_threejs-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for reflex-threejs 0.3.0
File Interpreter ABI Platform Actions
reflex_threejs-0.3.0-py3-none-any.whl Python 3 none any Details for reflex_threejs-0.3.0-py3-none-any.whl

Total release size: 81.0 kB

Release files / reflex_threejs-0.3.0.tar.gz

Download URL reflex_threejs-0.3.0.tar.gz
Size 40.9 kB
Tags Source
SHA-256 checksum
How to use checksums
4ec846c567e6cb93460aff8c33ce10718bfd21ce8647212081b3d4b757fc2e8c
BLAKE2b-256 checksum
How to use checksums
69f46b2129f647b0c3fe99d9df4b87124586d04819856dcd517bf3ecc23b7935
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Release files / reflex_threejs-0.3.0-py3-none-any.whl

Download URL reflex_threejs-0.3.0-py3-none-any.whl
Size 40.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0b98bacbb556594630e2ee7818a4e1fe6b164cd57e60210a3104d5beab29c471
BLAKE2b-256 checksum
How to use checksums
902be381b96cec663807143e16397e9b5978489d0449676fc48e15e475762bac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

Security for reflex-threejs 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for reflex_threejs-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 25, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page