<!-- Pyxle · Markdown for AI agents -->
> This is the Markdown rendition of https://pyxle.dev/docs/getting-started/quick-start, served for AI agents and assistants.
> Append `.md` to any pyxle.dev URL to fetch its Markdown; the links below already do.
> Index of every page: https://pyxle.dev/llms.txt · Whole docs in one file: https://pyxle.dev/llms-full.txt
> Search the docs: https://pyxle.dev/api/docs-search?q=YOUR+QUERY (returns matching pages as Markdown links)

# Quick Start

Create a working Pyxle app in under 5 minutes.

> **Before you start:** Pyxle needs **Python 3.10+** and **Node.js 20.19+** (for Vite 7 and React 19). Run `python3 --version` and `node --version` to check. On the wrong version, `pip install` or `pyxle dev` fails with a version error — see [Installation → Troubleshooting](https://pyxle.dev/docs/getting-started/installation.md#troubleshooting).

## 1. Scaffold a new project

```bash
pyxle init my-app
```

`pyxle init` is **interactive** — it asks a few questions and generates a project tailored to your answers:

```
◆ Use Tailwind CSS?                          › No / Yes   (↑/↓ + Enter)
◆ Add shadcn/ui components?                  › No / Yes   (only when Tailwind is on)
◆ Customize the default import alias (@/*)?  › No / Yes
```

Each question is an arrow-key selection with the default highlighted — press
Enter to accept it.

- **Tailwind CSS** — opt in to Tailwind v4, wired straight into Vite (no `postcss.config`, no separate watcher). Decline it and you get a clean baseline where plain CSS **and** CSS Modules work out of the box.
- **shadcn/ui** — sets up [shadcn/ui](https://ui.shadcn.com) (implies Tailwind), so `npx shadcn@latest add button` just works.
- **Import alias** — the shorthand for absolute imports of your own modules: `import { Button } from '@/components/ui/button'` instead of a brittle `../../` path. `@/*` is the convention (and what shadcn expects); almost everyone keeps it, so the value input only appears if you choose to customize.

This creates a `my-app/` directory with a complete starter project.

### Non-interactive (CI / scripts)

When stdin isn't a terminal, `pyxle init` never blocks on a prompt — it uses flags and defaults. Drive it explicitly:

```bash
pyxle init my-app --yes                      # accept all defaults (no Tailwind)
pyxle init my-app --tailwind --no-shadcn     # Tailwind, no shadcn
pyxle init my-app --shadcn                   # shadcn (implies Tailwind)
pyxle init my-app --import-alias '~/*'       # custom alias
```

### Scaffold into the current directory

Already made the directory (or ran `git init`)? Scaffold in place with `.` — the project name is derived from the directory name:

```bash
mkdir my-app && cd my-app
pyxle init .            # requires an empty directory (or pass --force)
```

## 2. Install dependencies

```bash
cd my-app
pyxle install
```

This runs both `pip install -r requirements.txt` and `npm install`. You can also run them separately:

```bash
pip install -r requirements.txt
npm install
```

`requirements.txt` lists your app's runtime dependencies (Starlette, Uvicorn, HTTPX). Pyxle itself comes from the `pip install pyxle-framework` in step 1.

## 3. Start the dev server

```bash
pyxle dev
```

The console prints a short summary — the local URL, the Vite URL, the route count, and how long startup took — then stays quiet unless something needs your attention:

```
✅ Pyxle dev server ready in 512 ms
ℹ️    Local:   http://127.0.0.1:8000
ℹ️    Vite:    http://127.0.0.1:5173
ℹ️    Routes:  1 page(s), 1 API route(s)
ℹ️    Studio:  http://127.0.0.1:8000/__pyxle/studio
```

The last line is [Pyxle Studio](https://pyxle.dev/docs/guides/studio.md), the dev-only dashboard for your routes, requests, and diagnostics. It appears whenever Studio is enabled (the default in `pyxle dev`).

Open [http://localhost:8000](http://localhost:8000) in your browser. You should see the Pyxle starter page — a centered card showing the framework version, server time, and the file to edit first, `pages/index.pyxl`.

The card also has a **Clicked 0 times** button, and it is there to be pressed. The version and the time above it were produced by Python on the server; the button is React running in your browser, from the same file. If the count goes up when you click, your page hydrated — the server HTML was handed to React and React took over. That is worth checking once on a new machine, because a page that renders perfectly and does nothing is exactly what a hydration failure looks like, and nothing else on a starter page would tell you.

Each edit you save prints one concise `Rebuilt … in X ms` line. Your server-side `logging` output — including the usual `log = logging.getLogger(__name__)` at the top of a page — streams to the **browser** devtools console (prefixed `[pyxle:server pages/index.pyxl]`) as well as the terminal, so you can follow loaders and actions without switching windows. Need the full picture — raw Vite logs and debug internals? Run `pyxle dev --verbose`. See the [CLI reference](https://pyxle.dev/docs/reference/cli.md#pyxle-dev) for details.

CSS just works: Vite compiles every stylesheet you import — plain CSS, CSS Modules, and (if you enabled it) Tailwind v4 via the `@tailwindcss/vite` plugin — with hot reload. There's nothing separate to start. See the [Styling guide](https://pyxle.dev/docs/guides/styling.md).

## What just happened?

When you ran `pyxle dev`, the framework:

1. **Compiled** `pages/index.pyxl` -- split the Python server code from the React JSX
2. **Started Vite** -- the JavaScript bundler that serves your React components with hot reload
3. **Started Starlette** -- the Python ASGI server that handles routing, SSR, and API requests
4. **Ran the `@server` loader** -- fetched data on the server and passed it as props to React
5. **Rendered HTML on the server** -- sent fully-rendered HTML to the browser (SSR)
6. **Hydrated on the client** -- React took over the server-rendered HTML for interactivity

## 4. Make a change

Open `pages/index.pyxl` in your editor. Change the `message` returned by `load_home`:

```python
@server
async def load_home(request):
    now = datetime.now(tz=timezone.utc)
    return {
        "version": __version__,
        "time": now.strftime("%H:%M:%S UTC"),
        "message": "Hello from my Pyxle app!",
    }
```

Save the file. The browser reloads automatically with your updated message.

## 5. Check your routes

```bash
pyxle routes
```

This prints the route table derived from your `pages/` directory:

```
ℹ️  Routes for my-app/

ℹ️    Pages:
▶️  / — index.pyxl  [loader=load_home]

ℹ️    API Routes:
▶️  /api/pulse — api/pulse.py

✅ 2 route(s) found
```

Paths are shown relative to `pages/`.

## 6. Validate your project

```bash
pyxle check
```

This validates your `.pyxl` files — Python syntax and semantics (including undefined names), JSX **syntax**, and your config file — and reports any problems it finds. Note the asymmetry: an undefined name in the Python half is reported, an undefined identifier in the JSX half is not, because the JSX pass checks that the markup parses rather than resolving what its identifiers refer to. Everything Python-side ships with `pip install pyxle-framework`, and the JSX pass runs on the Node.js install you already have from step 1 — so on a fresh project you should see:

```
ℹ️  Checked 2 .pyxl file(s) in my-app/
✅ All checks passed
```

## Next steps

- Understand what each file does: [Project Structure](https://pyxle.dev/docs/getting-started/project-structure.md)
- Learn the `.pyxl` file format: [`.pyxl` Files](https://pyxle.dev/docs/core-concepts/pyxl-files.md)
- Add a new page with data loading: [Data Loading](https://pyxle.dev/docs/core-concepts/data-loading.md)

## Continue reading

- Previous: [Installation](https://pyxle.dev/docs/getting-started/installation.md)
- Next: [Project Structure](https://pyxle.dev/docs/getting-started/project-structure.md)

---
> Human (HTML) version of this page: https://pyxle.dev/docs/getting-started/quick-start
> Keep exploring: https://pyxle.dev/llms.txt (index) · https://pyxle.dev/llms-full.txt (everything) · https://pyxle.dev/api/docs-search?q= (search)
