Vlahx Core — Configuration and Backend Extensions
In Chapter 1, we followed Vlahx from a collection of Python files to a running FastAPI application. We looked at the engine starting, the application being assembled, and the runtime becoming more important than the source tree itself.
Now we can go one level deeper.
A running application is useful, but a modular platform needs something more: it needs to be configurable and extensible.
Vlahx approaches these two requirements as parts of the same architecture.
Configuration defines how the runtime should behave. Extensions define what the runtime can do.
1. From a Running Application to a Configurable Runtime
The previous chapter ended with a running Vlahx application. But the application does not have a single fixed configuration embedded in its Python source.
Instead, Vlahx resolves configuration from several sources. Depending on the setting, values may come from environment variables, database settings, defaults, or extension-specific configuration.
The important idea is not where every individual value is stored. The important idea is that the application obtains a runtime value from a configuration layer instead of forcing every component to know where that value originally came from.
Environment
β
ββββββββββββββββ
β β
↓ ↓
Defaults Database
β β
βββββββββ¬βββββββ
↓
config.py
↓
Runtime value
This is the role of app/core/config.py.
The configuration layer acts as a boundary between the rest of the application and the different places where configuration may be stored.
That boundary becomes particularly useful when extensions enter the picture.
2. Application Settings and Extension Settings
Vlahx distinguishes between settings that belong to the application as a whole and settings that belong to a particular extension.
The distinction is important because an extension should not need to turn its own configuration into global application state.
SETTINGS
β
βββββββββββ΄ββββββββββ
β β
App Settings Extension Settings
β β
global runtime per-extension
β β
βββββββββββ¬ββββββββββ
↓
Runtime Config
Application settings are represented by the core configuration layer. Extension settings are associated with a specific extension and can be stored and retrieved independently.
This gives an extension its own configuration space while still allowing the core to resolve values needed by the running application.
There is another useful consequence: the configuration system can preserve compatibility while the architecture evolves. Older configuration paths can coexist with newer extension-based settings, allowing the platform to move forward without forcing every existing installation to change at once.
3. Extensions: The Backend Is Not Closed
Configuration answers the question:
How should this application behave?
Extensions answer another question:
What capabilities can this application have?
In Vlahx, a plugin is a concrete implementation of an extension. The more general architectural concept is the extension: an independent component that can add behavior to the backend without requiring changes to the core itself.
This distinction matters because the core does not need to know in advance which extensions will exist.
VLAHX CORE
β
Extension System
β
βββββββββββΌββββββββββ
↓ ↓ ↓
Blog OAuth AI Author
β β β
βββββββββββΌββββββββββ
↓
Backend Runtime
The core defines the mechanisms through which extensions can participate. Individual extensions provide the implementation.
This is one of the central ideas behind the Vlahx architecture:
The core defines contracts. Extensions provide capabilities.
4. From an Extension Package to Runtime Behavior
An extension starts as code on disk. That alone does not make it part of the running application.
Vlahx has a runtime loading process that connects the physical extension package with the application currently running in memory.
Extension on disk
↓
Discovery
↓
Metadata
↓
Database state
↓
Load
↓
register()
↓
βββββββΌβββββββ¬ββββββββ
↓ ↓ ↓ ↓
Routes Events Hooks Settings
βββββββ΄βββββββ΄ββββββββ
↓
Backend Runtime
The plugin manager discovers extension packages from the plugins directory and reads their metadata. The database keeps runtime state such as whether an extension is enabled and stores extension-specific settings.
When an enabled extension is loaded, Vlahx imports its Python module and looks for its registration function.
The important transition is:
code on disk
↓
import
↓
register(app)
↓
active runtime component
The register() function is therefore much more than a conventional initialization function. It is the point where an extension connects itself to the Vlahx runtime.
Inside registration, an extension may register routes, event handlers, template hooks, navigation items, content providers, services, or other capabilities exposed by the core.
The core does not need to contain a special branch saying:
if plugin == "blog":
...
elif plugin == "newsletter":
...
elif plugin == "ai_author":
...
Instead, the extension registers itself through the contracts already provided by the core.
5. Hooks and Events: Two Different Extension Mechanisms
Once extensions can register themselves, Vlahx needs defined places where that registration can have an effect.
This is where hooks and events become important.
Hooks
A hook is an explicit extension point provided by the core.
Extension ββββββ→ Core extension point
↓
result
For example, Vlahx can maintain a registry of functions that contribute sidebar widgets, navigation elements, content trees, article footers, or other pieces of application behavior.
An extension registers a function with the appropriate hook. Later, when the core reaches that extension point, it executes the registered functions.
Hooks can also define ordering. Multiple extensions can contribute to the same point without needing to know about each other.
This is a powerful property because the core does not have to become increasingly complicated as more extensions are added.
Events
Events solve a different problem.
An event represents something that happened. Code can publish an event, and independent handlers can subscribe to it.
Core / Extension ββ→ Event
↓
βββββββΌββββββ
↓ ↓ ↓
handler handler handler
The publisher does not need to know which components are listening.
This creates a loose connection between components. One extension can publish an event while several other components react to it without the publisher having to import or directly control them.
Hooks and events therefore complement each other:
- Hooks provide defined places where extensions can contribute behavior.
- Events provide a way for components to react to things that happen during runtime.
Both mechanisms reduce direct coupling between the core and its extensions.
6. The Database Is Part of the Runtime Model
At this point, the database is no longer just application storage.
For the extension system, it also represents part of the runtime configuration.
An extension can have an identity, metadata, enabled state, and its own settings.
Filesystem
β
β extension code
↓
Plugin Metadata
β
↓
Database
β
βββ identity
βββ enabled state
βββ extension settings
β
↓
Plugin Manager
β
↓
Runtime
This means that the physical presence of a directory under app/plugins is not the whole story.
There is a difference between:
- an extension that exists on disk,
- an extension known to the application,
- an extension enabled in the database, and
- an extension actually registered in the current runtime.
That distinction is fundamental to a modular platform.
7. Configuration Changes Can Rebuild the Runtime
There is one small core component that becomes surprisingly important here: process_restart.py.
When administrative changes require a new application lifecycle, Vlahx can trigger a controlled process restart. In the development environment, touching main.py can cooperate with Uvicorn's reload mechanism. In a containerized deployment, terminating the main process can allow the container runtime to restart it according to its configured restart policy.
The important architectural idea is the lifecycle, not the implementation detail of the restart itself.
Admin change
↓
Database state changes
↓
Process restart
↓
Application starts
↓
Configuration resolved
↓
Extensions discovered
↓
Enabled extensions loaded
↓
register()
↓
NEW RUNTIME
In other words, changing an extension's configuration or activation state can become part of the process that constructs the next runtime.
This is one reason why Vlahx treats configuration, extension management, and application lifecycle as connected concerns rather than completely separate systems.
8. The Core Does Not Need to Know the Future
A modular platform becomes difficult to maintain when every new feature requires another change inside the core.
Vlahx takes the opposite approach.
The core provides mechanisms:
- configuration resolution,
- extension discovery and loading,
- registration,
- hooks,
- events,
- settings,
- application lifecycle.
Extensions then use those mechanisms to add capabilities.
The result is a runtime that can evolve without the core having to predict every future feature.
VLAHX CORE
β
ββββββββββββΌβββββββββββ
β β β
Config Hooks Events
β β β
ββββββββββββΌβββββββββββ
β
Extension System
β
ββββββββββββΌβββββββββββ
↓ ↓ ↓
Extension Extension Extension
β β β
ββββββββββββΌβββββββββββ
↓
Backend Runtime
9. Backend First, Frontend Second
At this point, something important should be clear.
Vlahx does not begin its modular architecture with the visual interface.
The backend runtime comes first.
Configuration establishes the state in which the application should operate. Extensions add capabilities to that runtime. Hooks and events provide controlled communication between the core and those extensions.
Only after this runtime exists does the frontend layer become interesting.
CONFIGURATION
+
EXTENSIONS
↓
BACKEND RUNTIME
↓
TEMPLATE LAYER
↓
FRONTEND
That final transition leads directly into the next part of the architecture.
In the next chapter, we will move from the backend runtime into the frontend generation system: the Jinja environment, template loaders, template context, hooks, themes, and the mechanisms through which the runtime becomes an actual web page.
Conclusion
Vlahx Core is not simply a collection of utility modules.
It provides the mechanisms through which the application defines its configuration, discovers its extensions, loads their runtime behavior, and allows independent components to communicate without becoming tightly coupled to the core.
The result is a different way of thinking about the application.
The source tree contains the pieces. The database contains part of the state. The configuration layer resolves how those pieces should behave. The extension system connects independent capabilities to the core.
And when the application starts, those pieces become one runtime.
Source + Configuration + Extensions
↓
VLAHX RUNTIME
That is the foundation on which the frontend layer is built.
π¬ Comments (0)
π¬ Join the Conversation
Log in quickly with Telegram to leave a comment.