get started

Create your first app

Install pyxpo, create a project and run it with hot reload in a few minutes.

Requirements

  • Python 3.9 or newer on your computer.
  • For iOS: a Mac with Xcode and the iOS simulator.
  • For Android: Android Studio, or the Android SDK with an emulator, and a JDK.

You do not need a phone toolchain to start. pyxpo run web and pyxpo run desktop --preview run on your computer and are the fastest way to try pyxpo.

Install

terminal
python3 -m venv .venv
source .venv/bin/activate
pip install pyxpo

Then check your machine. The doctor command reports what is missing and how to fix it.

terminal
pyxpo doctor

Using VS Code? Install the pyxpo extension for style and prop completion, auto-import, color swatches and run commands.

Create a project

terminal
pyxpo create demo
cd demo

The new project looks like this:

demo/
demo/
├── app/
│   ├── _layout.py       # root layout (a Stack)
│   ├── index.py         # the "/" screen
│   ├── details/[id].py  # a dynamic route
│   └── +not-found.py    # shown for unknown routes
├── assets/
└── pyproject.toml     # [tool.pyxpo] app config

Run with hot reload

terminal
pyxpo run desktop   # native Mac or Windows app
pyxpo run web       # the browser, with a phone / tablet preview
pyxpo run ios       # iOS simulator
pyxpo run android   # Android emulator or USB device

Hot reload is on by default. Save a file and the screen updates while keeping its state. The dev server uses port 8765; change it with --port, or turn reload off with --no-reload.

The first iOS or Android build downloads the prebuilt CPython 3.13.7 runtime into ~/.cache/pyxpo. Later builds reuse it.

Edit your first screen

app/index.py
from pyxpo import Button, Text, View, useState
from pyxpo.router import Link

def Index():
    n, setN = useState(0)
    return View(
        Text("Count: ", n),
        Button(title="Add", onPress=lambda: setN(n + 1)),
        Link("Details", href="/details/%d" % n),
    )

default = Index

The link above opens app/details/[id].py, which reads the id from the URL:

app/details/[id].py
from pyxpo import Text, View
from pyxpo.router import useLocalSearchParams

def Details():
    params = useLocalSearchParams()
    return View(Text("Details for ", params["id"]))

default = Details

Build the app

terminal
pyxpo build android --release   # prints the path of the APK
pyxpo build ios
pyxpo build desktop             # Mac .app or Windows .exe
pyxpo build web                 # static site in build/web/

Without a keystore, the release APK is signed with the debug key, so you can install it on your own phone right away. Add your own signing config before you publish to a store.