[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/pythonnative/pythonnative/v0.43.1/docs/examples/hello-world.md [Back]  [Original]

# Hello world

The smallest possible PythonNative app. You'll learn how to:

- Define a component with `@pn.component`.
- Manage state with `use_state`.
- Compose elements with `pn.Column`.
- Run it with `pn preview` and `pn run`.

## The code

Save this as `app/main.py`:

```python
import pythonnative as pn


@pn.component
def App():
    count, set_count = pn.use_state(0)
    return pn.Column(
        pn.Text(f"Count: {count}", style={"font_size": 24, "bold": True}),
        pn.Button("Tap me", on_press=lambda: set_count(count + 1)),
        style={"spacing": 12, "padding": 16, "align_items": "stretch"},
    )
```

## What's happening

- `@pn.component` registers `App` as a function component. Hooks
  (like `use_state`) work because the decorator establishes a hook
  context for each call.
- `pn.use_state(0)` returns `(value, setter)`. The setter triggers a
  re-render scheduled on the Python application thread.
- `pn.Column(*children, style=...)` returns a vertical container
  element. Both the children and the style are read on every render;
  the reconciler diffs them against the previous render and updates
  the underlying `UIView` / `FrameLayout` in place.
- `pn.Text` and `pn.Button` map to native widgets via their
  Swift and Kotlin component managers.
- After every commit a [layout pass](../concepts/layout.md) computes
  frame for each widget using Yoga and the platform's intrinsic
  measurements. `spacing`, `padding`, and `align_items` follow shared
  layout rules; fonts and control sizes can differ by platform.

## Run it

### Preview in the browser

For the fastest feedback loop, start the dev server and open the
browser preview before reaching for an emulator or simulator. The
preview imports your real app code, so if your project declares
packages in `[requirements].packages`, `pip install` them first (this
example needs `emoji`). From the project root:

```bash
pn preview
```

A browser tab opens with `app/main.py`'s `App` in a phone frame. Edit a
component, save, and the preview refreshes in place. See the
[Browser preview guide](../guides/browser-preview.md) for the toolbar
and more options.

### Run on a device or simulator

Leave `pn preview` running and, from the project root in another
terminal:

```bash
pn run android   # or: pn run ios
```

`pn run` will:

1. Stage your `app/` and the bundled `pythonnative` package into the
   appropriate native template under `build/`.
2. Build it (`gradle installDebug` on Android, `xcodebuild` on iOS),
   unless an identical native build already exists.
3. Install and launch it on a connected device or simulator, pointed
   at the running dev server.
4. Stream logs back to the terminal.

The app is now a dev client: saves under `app/` Fast Refresh it, and
its output shows up in the `pn preview` terminal. See the
[Development workflow](../guides/dev-workflow.md) for the details.

## Next steps

- Build a slightly richer counter: [Counter](counter.md).
- Add a second screen and navigation: [Navigation](navigation.md).
- Learn the runtime model: [Mental model](../concepts/mental-model.md).

Web Proxy Viewer  |  New URL  |  Original Page