Release Overview

WebFluid Documentation

This is the second public alpha of WebFluid. Alpha 2 keeps the foundations of the first release and grows a lot on top of them: a full security battery, a runtime theming layer, a reworked event and i18n system and the wf ocean client for sharing packages. The runtime and its typing stubs now ship as two separate packages. APIs are still settling before the stable release, so keep pinning your version while the alpha runs.

1.0.0a2 Alpha July 06, 2026
View repository

New Features

+

Security battery

A complete auth stack: users, roles and permissions, two-factor auth via TOTP and WebAuthn, argon2 password hashing, double-submit CSRF protection and OAuth clients. It ships ready made FastAPI dependencies like require_user, require_admin and require_permissions.

+

Ocean package client

The new wf ocean command group logs you in, searches the Ocean hub and installs or publishes Additives and extensions. Required Additives are pulled in automatically when you install a package.

+

Runtime theming

With WF_THEMES enabled, Fluid manages a stylesheet theme per session. Register additional themes through fluid.add_theme() and switch them with fluid.set_theme().

+

Reworked event system

Signals, events and request/response queries now share a single /ws/events socket. The bundled frontend EventManager can request a query result, not just subscribe to broadcasts.

+

Domain based i18n

Translations are organised into domains with JSON message sources, locale and timezone selectors, a force() context manager and a /ws/i18n socket for translating in the browser.

+

File backed config values

Any *_FILE key in an app config is resolved from the file it points to, which keeps Docker style secrets out of your environment. A [dev] section is applied only when you run in debug mode.

+

Split runtime and typing stubs

The webfluid package now ships the pure runtime. Type information lives in a separate webfluid-stubs package that you pull in with webfluid[typing].

+

Async-first runtime with sync counterparts

Every battery still exposes an async API and a matching synchronous one. The SQLAlchemy extension, for example, gives you both executor() and async_executor() over the same bind set.

Fix Fixes

Interactive runtime on Windows

wf run [app] --interactive now drives its child process through a dedicated process group and works on NT based systems.

Version representation

Pre-release stages and builds (like 1.0.0a2) are parsed and compared correctly now, so Additive manifest version checks no longer fail on startup.

Optional static folder

Fluid only mounts its app static directory when it actually exists. A project without a fluid/static folder no longer breaks on initialization.

Passthrough CLI output

The wf node and wf tailwind passthrough commands now print the output of the underlying tools instead of succeeding silently.

Frontend query results

The bundled frontend EventManager can request a query result through the new query/request system, closing the gap from the first alpha.

Bug Known issues

!

Tailwind without themes

When WF_THEMES is disabled and a surface only ships a tailwind_no_themes.css, the frontend loader still probes for tailwind_raw.css and drops the stylesheet link. Keep a tailwind_raw.css around, or leave themes enabled, until this is fixed.

!

Migrations collect every Additive

The generated Alembic env.py imports the models of every Additive under additives/, without skipping the ones disabled for the app being migrated. So autogenerated revisions contain foreign Additives' tables. Review your revisions before applying them.

!

Secrets in migrations

Unlike wf run, the migration environment does not resolve *_FILE config values. File backed secrets are passed through verbatim, so a migration may not see the real value behind them.

!

Migrate template selection

wf migrate init chooses the single- or multi-database template from SQLALCHEMY_BINDS in your config. Binds attached at runtime through Model.set_bind are not detected and need a manual template.

!

Event backpressure

Broadcasts use a bounded per-listener buffer sized by EVENTS_EVENT_QUEUE_SIZE. A consumer that falls behind silently loses the oldest events.

!

Server-side theme switching

fluid.set_theme() validates the name like add_theme() does and rejects a name that is already registered, so it cannot currently select one of your registered themes. The client-side light/dark helper (window.wf.switchTheme()) is unaffected.

Break Breaking Changes

Additives moved into the core

The old webfluid.additives package is gone. The Additive base is now imported straight from webfluid (from webfluid import Additive) and its helpers live in webfluid.utils.additives.

Reworked i18n storage

The translation layer was rebuilt around domains and JSON message sources. Translation setups from the first alpha have to be recreated against the new structure. See the Babel chapter for the current shape.

Separate typing package

Type stubs are no longer bundled with the runtime. Install webfluid[typing] (or webfluid-stubs directly) to get editor and type-checker support.

New EXT_SECURITY switch

The security battery is a new extension gated by EXT_SECURITY. Enabling it requires a SECURITY_SECRET in production, so add both to your app config when you adopt it.