Introduction

Getting Started

This guide walks you through scaffolding your first WebFluid project, wiring up a minimal route, and adding a touch of frontend. By the end you will have a running app and a feel for how the pieces fit together.

Keep in mind that WebFluid has opinions and so it ships with conventions which we will explain in detail later on.

Installation

Install the webfluid package from PyPI. The CLI wf ships alongside it and is what you will use for every project task from here on.

Since this is an alpha version, you will need to pin it to install it.

terminal bash
pip install webfluid==1.0.0a1

mkdir -p myapp/fluid/templates
cd myapp
mkdir fluid/static
mkdir app_configs

This is the minimum required structure for this version to spin up your first minimal fullstack application. For now, we did not use the frameworks CLI to keep this introduction minimalistic and simple.

Python 3.14 or newer is required. WebFluid is built using the latest standards.

Your first app

Fluid is a child of FastAPI. So setting up routes works exactly the same way. The snippet below is a minimal service that serves a static HTML page and a health check.

main.py python
from webfluid import Fluid
from fastapi.responses import HTMLResponse

fluid = Fluid(__name__)


@fluid.get("/", response_class=HTMLResponse)
async def home():
    return await fluid.render(
        "index.html",
        title="Hello World!",
        name="my friend"
    )


@fluid.get("/health")
async def health():
    return {"status": "ok"}


if __name__ == "__main__":
    fluid.mix()

What you see

The snippet is looking like a mixture of Flask and FastAPI. But with one major difference: Flask and FastAPI are designed to be minimalistic. Fluid is a fullstack runtime, and so there is a lot of magic happening behind the scenes.

Nevertheless, it comes with a broad but optioned stack which allows you to decide how much of the magic you really need.

Anyway, for now we won't go into detail about what is really happening here. We just want to get you started. So let's continue setting up your app.

Adding a sprinkle of frontend

Now we have created a minimalistic app, which should render an index.html template. Like Flask, Fluid is also using the Jinja2 templating engine. It has its own jinja_env, and the major difference is the async environment as well as the rendering utility that sits inside the class.

Another slight difference is the location of the app templates. Fluid is designed to be abstracted and modular. So they are (as you may have already guessed looking at the setup command chain) located inside the fluid directory:

fluid/templates/index.html html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>

    <script>
        function healthCheck() {
            const result = document.getElementById('result')
            fetch('/health').then(res => {
                if (res.ok) result.style.color = 'green'
                else result.style.color = 'red'
                return res.json()
            }).then(data => {
                result.innerText = JSON.stringify(data)
                setTimeout(() => result.innerText = '', 2000)
            })
        }
    </script>
</head>
<body>
    <p>Hello <b>{{ name }}</b>!</p>

    <button onclick="healthCheck()">Health Check</button>
    <p id="result"></p>
</body>
</html>

Set up your application

Now everything is set in place. But before you can run your application, you will need to create an app config first. This is because WebFluid is able to serve multiple apps with different configs and setups in just one project directory.

Fluid requires only one config variable to run. And this is SECRET_KEY. So creating your app is as simple as:

terminal bash
cat <<'EOF' > app_configs/app.ini
[general]
SECRET_KEY = supersecret
EOF

Running your app

This is it. You can now run your app with the wf run command. It just takes the name of your app config (which should be equal to the name of your app) and parses your configuration as the apps' environment.

terminal bash
user@host:~/myapp: wf run app
Starting application...
[WF]    [2026-05-28 18:04:29 +0200] [INFO]      Mixing your WebFluid application.
[WF]    [2026-05-28 18:04:29 +0200] [WARNING]   Session cookies are not secure. Consider setting SESSION_COOKIE_SECURE=True.
[WF]    [2026-05-28 18:04:29 +0200] [INFO]      Running startup hooks...
[WF]    [2026-05-28 18:04:29 +0200] [INFO]      Server is listening on 127.0.0.1:8000.

Now you can access your app by opening http://localhost:8000 in your browser.

You may notice the warning inside your log / the console output. This is because Fluid sets up a SessionMiddleware when it gets initialized. It is configured as insecure per default. We will take a closer look at configuring your app in the next chapter.

For now if you would like to supress this warning, you need to run your app in debug mode using the -d flag.

Next steps

With the basics in place, we can now dive below the surface of your fluid:

  1. Read the configuration guide to learn how to configure your apps.
  2. Explore our extension system and the built-in batteries.
  3. Discover the integrated frontend tooling to release the full potential of your fluid.
  4. Build portable modules using our Additive battery.
  5. Skim the CLI reference for everything the wf command can do.