Summary
The current release is 0.0.5, but public install/deployment prose and the docs app still encode 0.0.1-era facts. The drift includes obsolete wheel/sdist availability, source-build requirements, the old separate Reflex-adapter status, and a Node floor that no longer satisfies the locked Vite toolchain.
Evidence
CHANGELOG.md identifies 0.0.5 as current and says reflex_xy is bundled in xy[reflex]:
|
## [Unreleased] |
|
|
|
## [0.0.5] - 2026-07-31 |
|
|
|
### Added |
|
- Reflex integration is now bundled in the `xy` distribution and installed as |
|
`xy[reflex]`. The `reflex_xy` import namespace and JSX wrapper ship in every |
|
wheel and sdist, while the extra adds the supported `reflex>=0.9.6` floor; |
|
plain `xy` still has no Reflex dependency. The separate `reflex-xy` |
|
distribution, version line, and release workflow have been removed. |
- Installation still calls 0.0.1 current, says Windows has no wheel/sdist, and pins v0.0.1 Git installs:
|
XY 0.0.1 supports Python 3.11 and newer. Install the released core package |
|
from PyPI with your preferred package manager: |
|
|
|
~~~~md tabs |
|
## uv |
|
|
|
~~~bash |
|
uv add xy |
|
~~~ |
|
|
|
## pip |
|
|
|
~~~bash |
|
python -m pip install xy |
|
~~~ |
|
~~~~ |
|
|
|
Confirm the package imports from the environment where your code will run: |
|
|
|
~~~bash |
|
python -c "import xy; print(xy.__version__)" |
|
~~~ |
|
|
|
## Supported platforms |
|
|
|
XY supports the platforms below. The PyPI column describes only the files in |
|
the current 0.0.1 upload, not whether XY supports the platform. |
|
|
|
| Platform | Compatibility | Architectures | XY support | PyPI 0.0.1 wheel | |
|
| --- | --- | --- | --- | --- | |
|
| macOS | macOS 10.12+ on Intel; macOS 11+ on Apple silicon | `x86_64`, `arm64` | Supported | Included | |
|
| Linux | glibc (`manylinux_2_17`) | `x86_64`, `aarch64`, `armv7l` | Supported | Included | |
|
| Linux | musl (`musllinux_1_2`, including Alpine) | `x86_64`, `aarch64`, `armv7l` | Supported | Included | |
|
| Windows | Native Windows | `x86_64`, `x86`, `arm64` | Supported | Not included | |
|
| WebAssembly | Pyodide 314 (Emscripten, PEP 783) | `wasm32` | Supported | Not in 0.0.1 (on PyPI since 0.0.3) | |
|
|
|
Windows is supported by XY's native core and release pipeline. The current |
|
0.0.1 PyPI upload does not include Windows wheels or a source distribution, so |
|
`uv add xy` and `python -m pip install xy` cannot install it directly on |
|
Windows yet. Until a Windows wheel is published, install the tagged source |
|
with a Rust MSVC toolchain as described below. |
|
|
|
The runtime-verified WebAssembly wheel targets the standardized PEP 783 |
|
`pyemscripten_2026_0_wasm32` platform and, as of 0.0.3, is published to PyPI |
|
alongside the native wheels. In-browser Python installs it by package name — |
|
`micropip.install("xy")`, or `%pip install xy` in a JupyterLite notebook. |
and
|
## Installing from Git or source |
|
|
|
Use the PyPI wheel when your platform is supported. A working source install |
|
must compile the native compute core, so it requires a Rust toolchain with |
|
`cargo` and `rustc`. The browser client is committed to the repository; Node |
|
and npm are not required just to install it. |
|
|
|
To reproduce the 0.0.1 release from Git with uv: |
|
|
|
~~~bash |
|
uv add "xy @ git+https://github.com/reflex-dev/xy.git@v0.0.1" |
|
~~~ |
|
|
|
Or install the same tagged source with pip: |
|
|
|
~~~bash |
|
python -m pip install "xy @ git+https://github.com/reflex-dev/xy.git@v0.0.1" |
|
~~~ |
|
|
|
A source build without Rust can finish installing, but it has no compute |
|
backend and fails with an actionable error when a chart first needs native |
|
compute. XY does not silently switch to a slower implementation. Building for |
- The same page says the browser client is committed and a raw source install needs no Node, while the build hook says it is generated/not committed and a raw clone builds it with Node/npm:
|
- The JS client (`python/xy/static/*.js`) is a **generated artifact, not |
|
committed to git** (§33): this hook builds it with `node js/build.mjs` when |
|
it's missing (running `npm ci` first if needed), and the `artifacts` config in |
|
pyproject.toml carries the git-ignored bundles into both the wheel and sdist — |
|
the JS analogue of compiling the Rust core from source. So a *published* wheel |
|
or sdist carries the client already built (end users need no Node), while |
|
building from a raw clone builds it, needing Node just as the core needs Rust. |
|
An unpacked sdist already carries the bundle, so `pip install <sdist>` stays |
|
Node-free — this hook sees the bundle present and returns without touching it. |
|
Unlike the native core, the client is **required by default**: every wheel and |
|
sdist must ship it (`verify_wheel.py` enforces it even in pure wheels), so a |
|
build that can neither find nor produce it is a hard error, never a silent |
- Deployment recipes pin 0.0.1 throughout:
|
## Build a pinned Docker image |
|
|
|
Keep the package version explicit and choose a base image that has a published |
|
wheel for its operating system and architecture: |
|
|
|
~~~dockerfile |
|
FROM python:3.11-slim |
|
|
|
ARG XY_VERSION=0.0.1 |
|
|
|
WORKDIR /app |
|
RUN python -m pip install --no-cache-dir "xy==${XY_VERSION}" |
|
|
|
COPY build_report.py /app/build_report.py |
|
|
|
CMD ["python", "build_report.py"] |
|
~~~ |
|
|
|
Build and copy the generated artifacts out of a container: |
|
|
|
~~~bash |
|
docker build --build-arg XY_VERSION=0.0.1 -t xy-report:0.0.1 . |
|
docker run --rm -v "$PWD/site:/app/site" xy-report:0.0.1 |
|
~~~ |
|
|
|
Run this image as a build job, not as a server: the script produces static |
|
artifacts and exits. If `pip` cannot find a compatible binary wheel, stop and |
|
check the [installation boundary](/docs/xy/overview/installation/) rather than |
|
silently changing the target platform. |
|
|
|
## Prepare an air-gapped wheelhouse |
|
|
|
On a connected machine that matches the target Python, operating system, and |
|
architecture, download XY and all of its Python dependencies: |
|
|
|
~~~bash |
|
mkdir -p wheelhouse |
|
python -m pip download \ |
|
--only-binary=:all: \ |
|
--dest wheelhouse \ |
|
"xy==0.0.1" |
|
~~~ |
|
|
|
Transfer the complete `wheelhouse/` directory through the approved channel. |
|
Inside the disconnected environment: |
|
|
|
~~~bash |
|
python -m pip install \ |
|
--no-index \ |
|
--find-links wheelhouse \ |
|
"xy==0.0.1" |
|
|
- The alpha-status table still calls Reflex a separate package:
|
| Surface | Current status | |
|
| --- | --- | |
|
| Declarative composition and 2D marks | Stabilizing alpha | |
|
| Standalone HTML, native PNG, and SVG | Stable alpha | |
|
| Required native Rust compute core | Stable alpha in published platform wheels | |
|
| Reflex adapter | Separate prototype/experimental package | |
|
| `xy.pyplot` compatibility | Experimental compatibility layer | |
|
| Adaptive thresholds and drill protocol | Experimental implementation details | |
- The docs app default and its test hard-code 0.0.1:
|
PUBLIC_DOCS_URL = "https://reflex.dev/docs/xy" |
|
PUBLIC_XY_VERSION = os.getenv("XY_DOCS_PUBLIC_VERSION", "0.0.1").strip() |
|
DOCS_CHANNEL = os.getenv("XY_DOCS_CHANNEL", "preview").strip().lower() |
and
|
def test_every_docs_route_has_canonical_and_social_metadata() -> None: |
|
"""Publish branded canonical and social metadata for every route.""" |
|
assert len(_DOCS_ROUTES) + len(DOCS_REDIRECTS) == len(app._unevaluated_pages) |
|
assert PUBLIC_XY_VERSION == "0.0.1" |
|
assert ( |
|
(DOCS_APP_ROOT / "assets/xy-social-card.png").read_bytes().startswith(b"\x89PNG\r\n\x1a\n") |
- Contributor docs promise Node 18+, but locked Vite requires Node
^20.19 || >=22.12 and CI uses 22:
|
Quick start: |
|
|
|
```bash |
|
git clone https://github.com/reflex-dev/xy.git |
|
cd xy |
|
make setup # dev environment + native core (needs Rust) |
|
make check # fast gate |
|
make check-full # full production gate (also needs Node 18+ and clippy) |
|
``` |
,
|
"node_modules/vite": { |
|
"version": "8.1.5", |
|
"resolved": "https://registry.npmjs.org/vite/-/vite-8.1.5.tgz", |
|
"integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==", |
|
"dev": true, |
|
"license": "MIT", |
|
"dependencies": { |
|
"lightningcss": "^1.32.0", |
|
"picomatch": "^4.0.5", |
|
"postcss": "^8.5.17", |
|
"rolldown": "~1.1.5", |
|
"tinyglobby": "^0.2.17" |
|
}, |
|
"bin": { |
|
"vite": "bin/vite.js" |
|
}, |
|
"engines": { |
|
"node": "^20.19.0 || >=22.12.0" |
|
}, |
,
|
enable-cache: false |
|
# The editable install below builds the render client from source via the |
|
# hatch hook (generated, not committed; §33) — the pyplot corpus exports |
|
# HTML, which inlines the client bundle. Pin Node so the build uses a |
|
# vite-compatible version rather than the runner's system Node. |
|
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 |
|
with: |
|
node-version: "22" |
Acceptance criteria
Summary
The current release is 0.0.5, but public install/deployment prose and the docs app still encode 0.0.1-era facts. The drift includes obsolete wheel/sdist availability, source-build requirements, the old separate Reflex-adapter status, and a Node floor that no longer satisfies the locked Vite toolchain.
Evidence
CHANGELOG.mdidentifies 0.0.5 as current and saysreflex_xyis bundled inxy[reflex]:xy/CHANGELOG.md
Lines 9 to 18 in 99eda6d
xy/docs/overview/installation.md
Lines 8 to 53 in 99eda6d
xy/docs/overview/installation.md
Lines 66 to 87 in 99eda6d
xy/hatch_build.py
Lines 14 to 25 in 99eda6d
xy/docs/guides/deployment-recipes.md
Lines 76 to 127 in 99eda6d
xy/docs/api-reference/limitations-and-alpha-status.md
Lines 12 to 19 in 99eda6d
xy/docs/app/xy_docs/constants.py
Lines 5 to 7 in 99eda6d
xy/docs/app/tests/test_docs_site.py
Lines 2233 to 2238 in 99eda6d
^20.19 || >=22.12and CI uses 22:xy/CONTRIBUTING.md
Lines 7 to 15 in 99eda6d
xy/package-lock.json
Lines 1230 to 1248 in 99eda6d
xy/.github/workflows/ci.yml
Lines 35 to 42 in 99eda6d
Acceptance criteria
xy[reflex]integration.