Generated Layout
The backend template generates a structured Vix application with a small process entry point and a clear backend shell. The project is still one executable target, but the generated files separate startup, routes, middleware, response helpers, runtime resources, tests, and production workflow metadata.
A generated backend named api follows this general shape:
api/
include/
api/
app/
AppBootstrap.hpp
presentation/
controllers/
HomeController.hpp
HealthController.hpp
middleware/
MiddlewareRegistry.hpp
routes/
RouteRegistry.hpp
support/
HttpResponses.hpp
src/
main.cpp
api/
app/
AppBootstrap.cpp
presentation/
controllers/
HomeController.cpp
HealthController.cpp
middleware/
MiddlewareRegistry.cpp
routes/
RouteRegistry.cpp
support/
HttpResponses.cpp
public/
views/
storage/
tests/
test_basic.cpp
vix.app
.env.example
README.md
vix.app
vix.jsonSome generated versions may also include additional configuration files such as config/production.json. The core backend layout stays the same: the root vix.app describes the backend executable, vix.json describes project workflow and production metadata, and the source tree keeps backend responsibilities separated.
src/main.cpp
The backend entry point is deliberately small.
src/main.cppIt includes the generated bootstrap header, creates an AppBootstrap instance, and delegates startup to it.
#include <api/app/AppBootstrap.hpp>
int main()
{
api::app::AppBootstrap bootstrap;
return bootstrap.run();
}This file should stay boring. It starts the process and hands control to the backend bootstrap. Routes, middleware, configuration, static files, module registration, and server startup belong elsewhere.
include/<project>/app/AppBootstrap.hpp
The public bootstrap declaration lives under the project include tree.
include/api/app/AppBootstrap.hppAppBootstrap owns the startup sequence of the backend application. The class is intentionally non-copyable and exposes one main operation:
int run();The header gives main.cpp a stable public entry point without exposing the whole startup implementation.
src/<project>/app/AppBootstrap.cpp
The bootstrap implementation is the center of the generated backend startup flow.
src/api/app/AppBootstrap.cppIt loads runtime configuration from .env, creates the vix::App, configures public files and views, registers middleware, registers base application routes, connects generated application modules, and finally starts the server.
The generated flow is:
AppBootstrap::run()
-> vix::config::Config cfg{".env"}
-> vix::App app
-> configure static files and views
-> MiddlewareRegistry::register_all(app)
-> RouteRegistry::register_all(app)
-> vix::app_generated::register_app_modules(app)
-> app.run(cfg)This is the main reason the backend template stays readable as it grows. The bootstrap owns startup, but it delegates the details of middleware, routes, and modules to focused files.
presentation/controllers
The backend template generates two base controllers.
include/api/presentation/controllers/
HomeController.hpp
HealthController.hpp
src/api/presentation/controllers/
HomeController.cpp
HealthController.cppHomeController registers the default API route.
GET /apiHealthController registers health check routes.
GET /health
GET /api/healthThese routes are small, but they prove that the backend is reachable and correctly wired. They also give the project a clear pattern for adding future application-level controllers.
Feature-specific controllers should normally move into application modules when the backend grows.
presentation/routes
The route registry groups application-level route registration.
include/api/presentation/routes/RouteRegistry.hpp
src/api/presentation/routes/RouteRegistry.cppThe generated implementation calls the base controllers.
void RouteRegistry::register_all(vix::App &app)
{
controllers::HomeController::register_routes(app);
controllers::HealthController::register_routes(app);
}This keeps AppBootstrap from including every controller directly. The bootstrap calls the route registry once, and the registry owns the list of base application routes.
presentation/middleware
The middleware registry groups global HTTP middleware.
include/api/presentation/middleware/MiddlewareRegistry.hpp
src/api/presentation/middleware/MiddlewareRegistry.cppThe generated backend starts with middleware for security headers, request logging, and a simple API marker header. It also leaves commented examples for common middleware such as CORS and rate limiting.
Middleware is placed in a registry because it affects the request pipeline as a whole. Keeping it in one file makes the order visible and avoids scattering global HTTP behavior through unrelated controllers.
support/HttpResponses
The backend template includes JSON response helpers.
include/api/support/HttpResponses.hpp
src/api/support/HttpResponses.cppThese helpers keep common response shapes out of controllers.
api::support::json_error(res, 404, "not_found", "Resource not found");
api::support::json_ok(res, data);
api::support::json_message(res, "Backend is running");This file is not meant to contain all application logic. It is a small shared support layer for response formatting. As features grow, feature-specific response logic can live inside modules.
public/
The public/ directory is for static files.
public/The backend bootstrap can mount this directory so files can be served by the application at runtime.
The directory is also declared as a runtime resource in vix.app.
resources = [
"public=public",
]This allows the built backend to find the directory beside the executable.
views/
The views/ directory is available for templates.
views/The backend template is API-oriented, but it still provides a place for views because some backend services need simple HTML pages, error views, diagnostics, admin pages, or generated documentation.
For a project whose main purpose is server-rendered HTML, the web template is usually a better fit.
storage/
The storage/ directory gives the backend a local runtime area.
storage/It can be used for generated files, local SQLite databases, uploads, temporary files, or other application-owned runtime data. The generated .env.example uses this shape for SQLite by default:
DATABASE_SQLITE_PATH=storage/api.dbThe directory is also copied as a resource so the runtime layout remains predictable after the build.
resources = [
"storage=storage",
]tests/
The backend template includes a test directory.
tests/
test_basic.cpp
vix.appThe generated test source defines its own main() and uses the Vix test runner. It does not include the application main.cpp, because tests are separate executables.
The test manifest describes the generated test target.
name = "api_tests"
type = "executable"
standard = "c++20"
output_dir = "bin"
sources = [
"test_basic.cpp",
]
include_dirs = [
"../include",
"../src",
]
packages = [
"vix",
]
links = [
"vix::vix",
]Run the test workflow with:
vix testsFor a stronger local validation:
vix check --tests --run.env.example
The generated backend includes an example environment file.
.env.exampleCopy it before running the backend locally.
cp .env.example .envThe file documents the expected runtime values: application name, environment, server host and port, TLS options, logging settings, public file settings, storage path, database settings, ORM values, WebSocket settings, and production diagnostics.
APP_NAME=api
APP_ENV=development
SERVER_HOST=0.0.0.0
SERVER_PORT=8080
PUBLIC_PATH=public
VIEWS_PATH=views
DATABASE_ENGINE=sqlite
DATABASE_SQLITE_PATH=storage/api.dbThe example file should be committed. The real .env file should hold local values and secrets.
vix.app
The root vix.app file describes the backend executable.
vix.appIt lists the generated source files, include roots, definitions, packages, linked targets, runtime resources, and output directory.
name = "api"
type = "executable"
standard = "c++20"
output_dir = "bin"
sources = [
"src/main.cpp",
"src/api/app/AppBootstrap.cpp",
"src/api/support/HttpResponses.cpp",
"src/api/presentation/routes/RouteRegistry.cpp",
"src/api/presentation/middleware/MiddlewareRegistry.cpp",
"src/api/presentation/controllers/HomeController.cpp",
"src/api/presentation/controllers/HealthController.cpp",
]
include_dirs = [
"include",
"src",
]
defines = [
"VIX_BACKEND_APP=1",
"VIX_APP_NAME=api",
]
packages = [
"vix",
]
links = [
"vix::vix",
]
resources = [
".env=.env",
"public=public",
"views=views",
"storage=storage",
]When Vix builds the project, it converts this manifest into an internal CMake project under:
.vix/generated/app/The generated files are not the source of truth. Edit vix.app when the backend target changes.
vix.json
The root vix.json file describes project metadata, tasks, and production-oriented workflow settings.
vix.jsonIt can include tasks such as:
{
"tasks": {
"dev": "vix dev",
"build": "vix build",
"check": "vix check --tests --run",
"test": "vix tests",
"env": "vix env check",
"health": "vix health",
"logs": "vix logs",
"service": "vix service status",
"proxy": "vix proxy nginx check",
"doctor": "vix doctor production",
"deploy": "vix deploy"
}
}It can also hold production metadata for service configuration, ports, reverse proxy settings, health checks, deploy behavior, logs, environment requirements, and database defaults.
The split is important:
vix.app -> C++ target manifest
vix.json -> project workflow and production metadata
.env -> local runtime values and secretsREADME.md
The generated README gives the project a local starting guide.
README.mdIt should explain the quick start, layout, important routes, configuration, build commands, and production workflow. The README belongs to the generated project itself, while these documentation pages explain the template in more detail.
Optional production config
Some backend template versions include a production configuration file.
config/production.jsonWhen present, it records production defaults such as the app name, server settings, logging format, public files, templates, storage, database path, health routes, and WebSocket defaults.
Use this file for structured runtime defaults when the project needs it. Keep secrets and machine-specific values in .env.
How the pieces work together
The backend template is organized around a stable startup path.
src/main.cpp
-> AppBootstrap
-> Config
-> vix::App
-> public/
-> views/
-> MiddlewareRegistry
-> RouteRegistry
-> generated app modules
-> app.run(...)The project files have separate responsibilities.
main.cpp process entry point
AppBootstrap startup owner
MiddlewareRegistry global HTTP middleware
RouteRegistry base application routes
HomeController default API route
HealthController health routes
HttpResponses shared JSON response helpers
public/ static files
views/ templates
storage/ runtime data
tests/ generated test target
vix.app backend executable manifest
vix.json project workflow and production metadata
.env.example documented runtime variablesThis is the main value of the backend template. It gives the project a structure that can grow without making the entry point or bootstrap absorb every feature.
Next step
Continue with the App Bootstrap page to understand the generated startup flow in detail.