Metadata-Version: 2.4
Name: koyoapp
Version: 0.4.2
Summary: Koyo is a Python web framework that brings the Next.js app directory experience to pure Python.
Author: Koyo Developers
License-Expression: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: starlette>=0.37.0
Requires-Dist: uvicorn>=0.30.0
Requires-Dist: watchfiles>=0.21.0
Requires-Dist: typer>=0.12.0
Requires-Dist: tomlkit>=0.12.0
Provides-Extra: test
Requires-Dist: pytest>=8.0; extra == "test"
Requires-Dist: httpx>=0.27; extra == "test"
Provides-Extra: dev
Requires-Dist: build>=1.0.0; extra == "dev"
Requires-Dist: twine>=5.0.0; extra == "dev"
Dynamic: license-file

# Koyo

Koyo is a Python web framework that mirrors the developer experience of
Next.js (the app directory convention, file based routing, layouts,
reusable components) but is written entirely in Python and runs as a normal
Python web server. Since it is a normal Python process under the hood, any
package installed with pip is available immediately, with no build step or
compiler touching the Python code.

This is v1, frontend and routing only. No backend API layer, no database,
no auth.

Koyo is free and open source under the MIT license. Fork it, use it anywhere,
for anything, and ship what you build with it. Contributions are welcome;
open an issue or pull request on the repository.

## Install

Koyo requires Python 3.11 or newer.

```
pip install koyoapp
```

## Quickstart

```
koyoapp create my-app
cd my-app
koyoapp dev
```

Open http://127.0.0.1:2309. The home page renders out of the box with an
animated hero, a call to action linking to the Koyo documentation, and a
live session counter driven by htmx. Edit any file under `app/`, `public/`,
or `styles/` and the page updates in place without a full reload.

## Deploying

Every scaffold ships deploy-ready files: a `Procfile` that starts
`python -m uvicorn koyoapp.serve:app` on `$PORT`, a `requirements.txt`
pinning the koyoapp release, and a `.railwayignore` that keeps the local
venv and build output out of deploys. Railway, Render, and any Procfile
based host can run a Koyo app with no extra setup; for static-only sites,
`koyoapp build` prerenders into `.koyo/build/site` for any static host.
See https://justphemi.github.io/koyo-docs for a full guide.

## CLI

- `koyoapp create .` scaffolds a Koyo project into the current directory.
- `koyoapp create my-app` creates `my-app` and scaffolds inside it.
- `koyoapp dev` starts the dev server on port 2309 by default, override
  with `--port`. If the port is already in use, the next free port is
  used automatically.
- `koyoapp build` prerenders every static route into `.koyo/build/site`.

## Project structure

```
my-app/
  app/
    layout.py
    page.py
  components/
    counter.py
    landing.py
    site.py
  public/
  styles/
  koyo.config.py
  pyproject.toml
```

Routing rules follow the Next.js app directory convention. Folders wrapped
in square brackets become dynamic path parameters. A page file must export
a function named `page`, and a layout file must export a function named
`layout(children)`. Layouts nest outward to inward, exactly like Next.js.

## Component system

`koyoapp.html` exposes function based HTML elements. Text content is HTML
escaped by default; use `Markup` (or `raw()`) for raw unescaped output.
Children can be passed positionally as arguments or appended with square
brackets; both styles can be mixed, and a list (or any iterable) passed as
a single child is flattened in place. Attributes map underscores to
hyphens (`hx_`, `data_`, `aria_`), and `class_` / `cls` both mean `class`.

```python
from koyoapp.html import div, h1, p, span

def Card(title: str, body: str):
    return div(class_="p-4 rounded-lg shadow bg-white")[
        h1(class_="text-xl font-bold")[title],
        p(class_="text-gray-600")[body],
    ]

def Row(label: str, value: str):
    return div(span(label, cls="font-medium"), span(value), class_="flex gap-2")
```

## Styles

`koyoapp dev` runs the Tailwind CLI in watch mode against the project and
compiles `styles/globals.css` to `styles/koyo.css`, which the root layout
links automatically. Any other `.css` file under `styles/` is served
untouched from `/styles/` and can be linked directly with a normal `link`
tag. The scaffold ships a light/dark theme switch: `public/theme.js`
applies the saved or system-preferred theme before first paint, the hero
button toggles it and stores the choice in `localStorage`, and dark mode
is class based (`darkMode: "class"`) so any element can use `dark:`
variants.

## Packages

There is no custom package manager. Activate the project virtualenv and use
plain pip:

```
.venv/bin/pip install <package>
```

The package is importable in any `page.py`, `layout.py`, or component file
immediately, since Koyo runs as a normal Python process.
