[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/pythonnative/pythonnative/v0.43.1/docs/meta/faq.md [Back]  [Original]

# FAQ

Conceptual questions about PythonNative. For specific error messages
and their fixes, see [Troubleshooting](troubleshooting.md).

## Why "PythonNative" and not, say, Toga or Kivy?

PythonNative renders **real** native widgets through Swift and Kotlin
component managers. A `pn.Text` becomes a `UILabel` /
`TextView`; a `pn.Button` becomes a `UIButton` / `Button`.
Platform controls provide native behavior. Applications still need appropriate
accessibility labels, roles, and testing on each deployment target.

The component model is React-style (functions plus hooks plus a
reconciler) so you get a familiar declarative API on top of those
native widgets. Python runs on its own application thread and communicates
with the native UI through a versioned bridge.

## Can I write Android-only or iOS-only code?

Yes. Two patterns:

- **Branch on `IS_ANDROID` / `IS_IOS` / `IS_WEB`** for small
  differences inside a shared component:

    ```python
    from pythonnative.utils import IS_ANDROID, IS_IOS, IS_WEB

    if IS_ANDROID:
        ...
    elif IS_IOS:
        ...
    elif IS_WEB:
        ...
    ```

    `pn preview` and `pn start` set `PN_PLATFORM=web`, so `IS_WEB` is
    `True` in the browser preview; see the
    [Browser preview guide](../guides/browser-preview.md).
    For a declarative alternative, use
    [`Platform.select`][pythonnative.platform.Platform.select] with the
    `"web"` key.

- **Per-platform native modules** for larger pieces (a custom widget,
  a device API). Implement once per platform behind a single Python
  facade. See [Native modules guide](../guides/native-modules.md).

## How do I add a new widget?

Implement a [`ViewHandler`][pythonnative.native_views.base.ViewHandler]
for each platform you support, register it on
[`get_registry()`][pythonnative.native_views.get_registry], and write
a small Python factory that returns
`Element(, props, children)`. Step-by-step instructions live in
[Native views (concept)](../concepts/native-views.md#custom-widgets).

## Does PythonNative work on the desktop or the web?

For **previewing**, yes. `pn preview` renders your app in a browser tab
inside a phone frame, with Fast Refresh on every save. It's the fastest
inner loop: see your real UI and iterate in seconds without booting a
simulator or deploying to a device. The page speaks the same bridge
protocol as the Swift and Kotlin runtimes. It shares Python components,
hooks, reconciliation, and logical navigation with mobile apps; the page
implements widgets in the DOM and layout with Yoga WebAssembly. See the
[Browser preview guide](../guides/browser-preview.md).

The browser preview is a **development tool**, not a production target:
platform chrome and fonts are approximated, most device APIs are
simulated, and there's no web or desktop packaging. Ship to devices
with `pn run android` / `pn run ios` and `pn build`.

The core (components, hooks, reconciler) is also platform-agnostic and
runs headless with a [fake backend](../guides/testing.md);
that's how the unit-test suite works.

## How do I package and distribute my app?

`pn run android` and `pn run ios` produce installable artifacts in
`build/`:

- Android: `build/android/android_template/app/build/outputs/apk/`.
- iOS: `build/ios/ios_template/build/Build/Products/Debug-iphonesimulator/ios_template.app`.

For release distribution, treat the staged template directory as a
normal Android Studio / Xcode project (sign, archive, upload via
Play Console / App Store Connect).

## Can I use any Python package?

Most of them. List packages in `[requirements].packages` in
`pythonnative.toml` and the `pn` CLI resolves them **for the phone,
not for your laptop**, then bundles them into the app:

- **Pure-Python packages** (requests, httpx, pydantic-core-free
  libraries, and so on) work everywhere.
- **Binary wheels** work when the package publishes wheels for the
  target: iOS wheels (PEP 730, `ios_13_0_arm64_iphoneos` and the
  Simulator tags) from the BeeWare index, and Android wheels from the
  Chaquopy index. numpy, Pillow, cryptography, cffi, lxml, and pandas
  all resolve out of the box today.
- **No wheel for the target** is a build-time error, reported by
  `pn deps` with the package name and the target that failed, never a
  silent import error on the device.

Run `pn deps` to see how every requirement resolves for each iOS and
Android target before you build. The
[PyPI packages guide](../guides/pypi-packages.md) covers the details
and the live compatibility matrix.

Don't put `pythonnative` itself in `[requirements].packages`; the CLI
bundles the installed copy directly.

## Where do `flex`, `padding`, and `position: "absolute"` actually run?

In the Yoga C++ engine compiled into each mobile runtime. Python sends
styles through the bridge; native widgets supply intrinsic measurements,
and the renderer returns changed frames to Python. The browser uses Yoga
WebAssembly, while headless tests use the Python host binding in
`pythonnative.layout`. The layout rules are shared, but platform fonts
and controls can have different intrinsic sizes. See
[Layout engine](../concepts/layout.md).

## How is state shared across screens?

Two main options:

- [`use_context`][pythonnative.use_context] /
  [`Context.Provider`][pythonnative.hooks.Context.Provider] for tree-scoped values
  (themes, current user). The provider sits at the top of the
  navigator and descendants subscribe.
- A plain Python module-level object (a "store") for app-wide,
  long-lived state. Subscribe to changes via your own event bus and
  call `set_state` on a hook to trigger re-renders.

PythonNative doesn't ship a Redux-style store; the
[`use_reducer`][pythonnative.use_reducer] hook covers most cases
without one.

## How do I navigate between screens?

Use [`NavigationContainer`][pythonnative.NavigationContainer] plus one
of [`create_stack_navigator`][pythonnative.create_stack_navigator],
[`create_tab_navigator`][pythonnative.create_tab_navigator], or
[`create_drawer_navigator`][pythonnative.create_drawer_navigator].
From a screen, call [`use_navigation`][pythonnative.use_navigation]
to get an imperative handle (`navigate`, `go_back`, etc.). See the
[Navigation guide](../guides/navigation.md).

## Why hooks instead of class components?

Hooks are smaller (no inheritance), composable (a custom hook is just
a Python function that calls other hooks), and produce simpler diffs.
The React community's experience over the last few years made the
choice straightforward.

## Why function components and not just plain functions?

The `@pn.component` decorator establishes a hook context for the
function call. Without it, hooks have no slot to attach state to and
will raise. The decorator also gives the reconciler a stable
identity for the function so it can keep state across re-renders.

## How do I do animations?

Two strategies, depending on the cadence:

- **State-driven** (e.g., a fade triggered by a button press): keep
  the value in [`use_state`][pythonnative.use_state] and let the
  reconciler push updates. Fine up to a few updates per second.
- **Frame-driven** (e.g., a spring animation): bind an
  [`AnimatedValue`][pythonnative.AnimatedValue] into an
  `Animated.View` style and drive it with `Animated.spring` or
  `Animated.timing`. Native animation graphs update supported bindings
  without running Python on every frame. See the
  [Animations guide](../guides/animations.md) for examples and fallback cases.

## Is there async/await support?

Yes, and it's the core of the framework. PythonNative runs a single
standard `asyncio` loop on a dedicated application thread. Native UI threads
own widgets, scrolling, and animation frames. Components themselves can be `async def` (pair
them with [`Suspense`][pythonnative.Suspense] for loading states),
`use_effect` accepts coroutine callbacks and cancels them on unmount,
[`use_resource`][pythonnative.use_resource] fetches during render, and
native modules like `Camera` and `Location` are awaitable. From a
synchronous event handler, kick off work with
[`pn.run_async`][pythonnative.run_async]. See the
[Async + data guide](../guides/async.md).

## How is this different from Toga, BeeWare, Kivy, Briefcase?

| Tool | Model | Widgets |
|---|---|---|
| **PythonNative** | Declarative components plus reconciler | Real native (`UILabel`, `TextView`) via Swift / Kotlin component managers |
| Toga | Imperative widgets | Real native via per-platform backend |
| Kivy | Imperative widgets | Custom OpenGL renderer |
| Briefcase | Packaging only (no widgets) | n/a |

PythonNative also has a built-in `pn` CLI for the
build / install / hot-reload loop, so the equivalent of "Briefcase"
is included.

## Where do I file bugs and feature requests?

[GitHub issues](https://github.com/pythonnative/pythonnative/issues).
Smaller fixes and docs improvements are welcome as pull requests
without a prior issue. See [Contributing](contributing.md).

## Next steps

- Walk through your first app: [Getting started](../getting-started.md).
- Read the runtime model: [Mental model](../concepts/mental-model.md).
- Browse the API: [Package overview](../api/pythonnative.md).

Web Proxy Viewer  |  New URL  |  Original Page