Vyuh
Vyuh (व्यूह, vyoo-huh) means "formation", "arrangement", or "structured configuration".
Vyuh is a handler-first Rust web framework built on Axum and SQLx.
It is designed around one idea: application structure should stay visible in
ordinary Rust code. Handler signatures describe what a route, command, task, or
signal consumes. Bundles group related application parts. Site owns the
runtime. Data<T> gives typed application data the same shape across
subsystems.
Vyuh favors a narrow, explicit API over hidden framework magic. Request wrappers
parse. Valid<E> validates. Auth is opt-in. Tasks retry only when the task says
so. Services stay separate because they are site-lifetime components, not
handler data.
Vyuh is usable, but not API-stable yet. Expect breaking changes before a stable release.
Web And Docs Assets
The vyuh/web/ directory is the shared visual source for Vyuh-owned web
surfaces. It contains public CSS, JavaScript, images, the static landing-page
source, and private Minijinja templates for the built-in console.
The mdBook source lives in docs/book/ and reuses the same CSS:
The landing page and mdBook can be built into one GitHub Pages artifact:
For the vyuh-rs/vyuh repository, GitHub Pages will serve the landing page at
https://vyuh-rs.github.io/ and the book at
https://vyuh-rs.github.io/docs/.
The console UI is server-rendered with Minijinja and uses the same bundled asset
serving path as application assets, for example /assets/css/base.css and
/assets/css/console.css.
The Shape
Vyuh tries to make the common application path cohesive:
Data<T>is typed application data.Valid<E>opts into validation.Siteis the runtime handle and lifecycle surface.- Bundles are the composition unit for features.
- Handler signatures drive extraction, auth, validation, OpenAPI, and subsystem access.
- Macros are convenience syntax. The same routes, commands, tasks, signals, emitters, services, assets, and OpenAPI wiring can be registered with the direct API.
The goal is not to hide the framework. The goal is to keep each framework concept small, explicit, and in the same place as the code that needs it.
Getting Started
use JsonSchema;
use ;
use *;
async : )
async
async
async
This bundle registers a validated JSON route, a cron emitter, a signal handler,
and an OpenAPI spec endpoint. The route parses and validates Data<Signup>,
returns Data<UserCreated> as JSON, and contributes request, response, and
validation metadata to OpenAPI from the handler signature. Without Valid,
Data<Signup> would parse only.
Site::run is the normal application entrypoint. It builds the site, runs the
requested command, and defaults to serving HTTP when no command is supplied. Use
Site::serve for server-only binaries and Site::build when embedding or
testing needs the built site object.
Bundles
A bundle is Vyuh's feature composition unit.
A feature can own its routes, templates, assets, services, tasks, commands, signals, emitters, and OpenAPI metadata together. Larger applications are built by merging and prefixing bundles instead of scattering feature wiring across unrelated global registries.
let dashboard = bundle! ;
let app = bundle! ;
Philosophy
Vyuh is built around simplicity and uniformity:
- One typed data wrapper,
Data<T>, is shared across routes, commands, tasks, signals, and emitters. - Validation is explicit through
Valid<E>, never automatic because a type derivesValidate. - Auth is completely opt-in; routes without auth extractors do no auth work.
- Errors have a common application shape, then render differently for HTTP, commands, and tasks.
- Site-level subsystems are accessed through direct handles such as
site.db(),site.tasks(),site.templates(),site.file_storage(), andsite.auth(). - Services remain distinct because they represent site-lifetime components, not handler input or output.
- Console is opt-in and read-only in its first pass, for operational inspection without exposing command or task mutation APIs.
This keeps the framework cohesive without pretending every subsystem is the same thing.
Documentation
- Site: lifecycle, configuration, subsystem handles, and testing.
- Bundles: feature composition, prefixing, OpenAPI, and validation.
- Routes: handler-first HTTP routes and route metadata.
- Request:
Data, JSON, query, path, forms, multipart, and raw bodies. - Response: response wrappers, redirects, headers, and metadata.
- Validation: explicit
Valid<E>, structured errors, and schema hints. - Errors: application errors, rendered errors, commands, and tasks.
- Auth: opt-in JWT, API keys, static roles, dynamic permissions, and Django password hashes.
- OpenAPI: generated specs from handler signatures and overrides.
- Middlewares: site-wide HTTP policy and slash behavior.
- Database: SQLx access, query helpers, sessions, and transactions.
- Tasks: durable single-unit background continuations.
- Commands: site-aware CLI commands for operations.
- Services: site-lifetime components and workers.
- Templates: Minijinja configuration, helpers, and formatting.
- Assets: embedded assets, public files, and
collect_static. - Uploads: multipart uploads, MIME screening, and file storage.
- Signals: typed in-process event handling.
- Channels: live client-facing pub/sub over SSE, WebSocket, and long polling.
- Emitters: cron, periodic, debounced, and notification sources.
- Logging: tracing setup, sinks, and runtime logging.
- Console: optional JSON APIs for operations, task records, and runtime status.
- Framework comparison:
vyuhvs Rocket, Utoipa, Actix, and FastAPI.
See docs/index.md for the full documentation index.
Backend Support
Vyuh is Postgres-first where database semantics matter most, but the common database and task surfaces support Postgres, MySQL, and SQLite.
Vyuh has no default backend feature. With no backend feature enabled, it uses
SQLite-compatible SQLx aliases, a shared in-memory SQLite default database URL,
and MemoryTaskStore for tasks. This is useful for quick starts, docs, local
experiments, and tests that do not need durable task storage.
Production applications should enable exactly one backend feature:
= { = "0.2", = ["postgres"] }
= { = "0.2", = ["mysql"] }
= { = "0.2", = ["sqlite"] }
Postgres is the preferred production backend for high-concurrency task workers and notification emitters. MySQL is supported for SQLx access and task storage. SQLite is useful for local, embedded, and single-process deployments.
Current Caveats
- Vyuh is usable, but not API-stable yet. Expect breaking changes before a stable release.
- Services are in-process and not durable.
- Tasks provide durable single-task continuations, not multi-task workflow orchestration.
MemoryTaskStoreis the no-backend default and is not durable.- SQLite task storage is not positioned as a high-concurrency production worker backend.
- Some Postgres features, such as
LISTEN/NOTIFYandRETURNING *helpers, are intentionally Postgres-only.
License
Vyuh is licensed under the MIT License.