Skip to content

Refresh versioned install/release docs and derive docs metadata from one source #446

Description

@Alek99

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]:

    xy/CHANGELOG.md

    Lines 9 to 18 in 99eda6d

    ## [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:

    xy/hatch_build.py

    Lines 14 to 25 in 99eda6d

    - 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:

    xy/CONTRIBUTING.md

    Lines 7 to 15 in 99eda6d

    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)
    ```
    ,

    xy/package-lock.json

    Lines 1230 to 1248 in 99eda6d

    "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

  • Current install/platform/source-build facts are version-neutral where possible and accurate for the latest release where version-specific.
  • Raw-clone vs published-sdist Node requirements are documented correctly.
  • Reflex is consistently documented as the bundled xy[reflex] integration.
  • Public docs version metadata comes from one release-owned source (or is injected by the release), with a test that cannot bless an old literal.
  • Contributor Node guidance matches the actual package-manager/toolchain floor and CI.
  • Add a drift check for stale release literals/current-platform claims.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions