Facade vs Independent Packages
This guide explains the difference between using the unified Rix facade and using an independent Rix package directly.
Rix supports both styles.
Use the facade when you want the normal public Rix API:
#include <rix.hpp>and:
rix.auth
rix.csv
rix.debug
rix.pdfUse an independent package when you intentionally want only one package:
#include <rix/pdf.hpp>and:
auto pdf = rixlib::pdf::module();The short version
Use rix/rix for application code and documentation examples.
Use rix/name directly when a project only needs one package and does not need the full facade.
Unified facade -> rix/rix -> <rix.hpp> -> rix.*
Independent package -> rix/pdf -> <rix/pdf.hpp> -> rixlib::pdf::module()Unified facade
The unified facade is the package:
rix/rixInstall it with:
vix add rix/rix
vix installUse it with:
#include <rix.hpp>Then access packages through the global rix object:
rix.auth
rix.csv
rix.debug
rix.pdfIndependent package
An independent package is a focused package such as:
rix/auth
rix/csv
rix/debug
rix/pdfInstall one package directly:
vix add rix/pdf
vix installUse its header directly:
#include <rix/pdf.hpp>Then create the package module:
auto pdf = rixlib::pdf::module();Facade example
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
auto &page = doc.add_page();
page.text(
page.x_left(),
page.y_top(),
"Hello from rix.pdf through the facade");
auto saved = rix.pdf.save(doc, "facade.pdf");
return saved.ok() ? 0 : 1;
}This style is short and readable.
It is the preferred style for most Rix documentation.
Independent package example
#include <rix/pdf.hpp>
int main()
{
auto pdf = rixlib::pdf::module();
auto doc = pdf.document();
auto &page = doc.add_page();
page.text(
page.x_left(),
page.y_top(),
"Hello from rix/pdf directly");
auto saved = pdf.save(doc, "independent.pdf");
return saved.ok() ? 0 : 1;
}This style is useful when the project only needs rix/pdf.
Main difference
The difference is not the PDF feature itself.
The difference is the entry point.
Facade:
#include <rix.hpp>
rix.pdf.document()Independent:
#include <rix/pdf.hpp>
auto pdf = rixlib::pdf::module();
pdf.document()Both styles use the same package underneath.
When to use the facade
Use the facade when:
you are writing application code
you want one include
you use more than one Rix package
you want rix.auth, rix.csv, rix.debug, rix.pdf
you are writing documentation examples
you want the public Rix styleExample:
#include <rix.hpp>
int main()
{
rix.debug.print("Hello from Rix");
const auto table = rix.csv.parse(
"name,language\n"
"Ada,C++\n");
auto doc = rix.pdf.document();
rix.debug.print("rows:", table.size());
return 0;
}When to use an independent package
Use an independent package when:
you only need one package
you want a smaller dependency scope
you are building a focused library
you do not need the global rix facade
you want direct package ownership in the fileExample:
#include <rix/pdf.hpp>
int main()
{
auto pdf = rixlib::pdf::module();
auto doc = pdf.document();
return pdf.save(doc, "output.pdf").ok() ? 0 : 1;
}Project dependency for facade usage
For facade usage, add:
vix add rix/rix
vix installIn vix.app:
deps = [
"rix/rix",
]Then include:
#include <rix.hpp>Project dependency for independent usage
For independent usage, add only the package you need.
Example for PDF:
vix add rix/pdf
vix installIn vix.app:
deps = [
"rix/pdf",
]Then include:
#include <rix/pdf.hpp>Do not put Rix packages in packages
Rix packages belong in deps.
Wrong:
packages = [
"rix/rix",
]Correct:
deps = [
"rix/rix",
]For independent usage:
deps = [
"rix/pdf",
]deps is for Vix Registry packages.
packages is for CMake package discovery.
Facade naming
The facade follows this model:
Registry package -> rix/rix
Header -> <rix.hpp>
Access -> rix.*Examples:
rix.auth.memory()
rix.csv.parse(...)
rix.debug.print(...)
rix.pdf.document()This is the normal public Rix style.
Independent naming
Independent packages follow this model:
Registry package -> rix/name
Header -> <rix/name.hpp>
Namespace -> rixlib::name
Module helper -> rixlib::name::module()Example for PDF:
Registry package -> rix/pdf
Header -> <rix/pdf.hpp>
Namespace -> rixlib::pdf
Module helper -> rixlib::pdf::module()Side-by-side comparison
| Need | Use | Install | Include | Access |
|---|---|---|---|---|
| Normal app usage | Facade | rix/rix | <rix.hpp> | rix.* |
| Multiple packages | Facade | rix/rix | <rix.hpp> | rix.auth, rix.pdf |
| Docs and examples | Facade | rix/rix | <rix.hpp> | rix.* |
| One focused package | Independent | rix/name | <rix/name.hpp> | rixlib::name::module() |
| Smaller dependency scope | Independent | rix/name | <rix/name.hpp> | package module |
Facade with auth
#include <rix.hpp>
int main()
{
auto auth = rix.auth.memory();
auto registered = auth.register_user({
"ada@example.com",
"correct-password"});
return registered.ok() ? 0 : 1;
}Install:
vix add rix/rix
vix installIn vix.app:
deps = [
"rix/rix",
]Facade with CSV
#include <rix.hpp>
int main()
{
const auto table = rix.csv.parse(
"name,language\n"
"Ada,C++\n");
rix.debug.print("rows:", table.size());
return 0;
}This uses both rix.csv and rix.debug, so the facade is a good fit.
Facade with PDF
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
auto &page = doc.add_page();
page.text(
page.x_left(),
page.y_top(),
"Hello from rix.pdf");
auto saved = rix.pdf.save(doc, "hello.pdf");
return saved.ok() ? 0 : 1;
}This is the preferred style for PDF examples in the Rix docs.
Independent PDF
#include <rix/pdf.hpp>
int main()
{
auto pdf = rixlib::pdf::module();
auto doc = pdf.document();
auto &page = doc.add_page();
page.text(
page.x_left(),
page.y_top(),
"Hello from independent rix/pdf");
auto saved = pdf.save(doc, "hello.pdf");
return saved.ok() ? 0 : 1;
}Install:
vix add rix/pdf
vix installIn vix.app:
deps = [
"rix/pdf",
]Independent debug
#include <rix/debug.hpp>
int main()
{
auto debug = rixlib::debug::module();
debug.print("Hello from rix/debug");
return 0;
}Use this style only when the independent package exposes a module helper.
For most examples, prefer:
#include <rix.hpp>and:
rix.debug.print(...)Lightweight facade
The facade can be reduced with feature macros.
Example:
#define RIX_ENABLE_PDF
#define RIX_ENABLE_DEBUG
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
rix.debug.print("PDF ready");
return 0;
}When at least one RIX_ENABLE_* macro is defined, only selected modules are mounted.
This gives a middle path between full facade and fully independent package usage.
Default facade behavior
If no feature macro is defined, all currently mounted modules are enabled.
This means:
#include <rix.hpp>gives access to:
rix.auth
rix.csv
rix.debug
rix.pdfThis keeps simple examples short and backward-compatible.
Feature macro examples
Only PDF:
#define RIX_ENABLE_PDF
#include <rix.hpp>PDF and debug:
#define RIX_ENABLE_PDF
#define RIX_ENABLE_DEBUG
#include <rix.hpp>Auth only:
#define RIX_ENABLE_AUTH
#include <rix.hpp>CSV and debug:
#define RIX_ENABLE_CSV
#define RIX_ENABLE_DEBUG
#include <rix.hpp>Available macros include:
RIX_ENABLE_AUTH
RIX_ENABLE_CSV
RIX_ENABLE_DEBUG
RIX_ENABLE_PDFWhich style should docs use?
Rix docs should start with the public facade.
Use:
#include <rix.hpp>and:
rix.pdf.document()
rix.auth.memory()
rix.csv.parse(...)
rix.debug.print(...)Then show independent package usage later as an alternative.
This keeps the docs consistent and teaches one public style first.
Which style should applications use?
Most applications should use:
vix add rix/rix
vix installThen:
#include <rix.hpp>This gives the cleanest application code.
Use independent packages only when the app has a clear reason to avoid the unified facade.
Which style should libraries use?
A focused library can use an independent package when it only needs one Rix package.
Example:
vix add rix/pdf
vix installThen:
#include <rix/pdf.hpp>This avoids depending on the full facade when the library only needs PDF types or PDF generation.
Single-file usage with facade
Create a file:
mkdir -p ~/rix-facade-example
cd ~/rix-facade-example
touch main.cppAdd:
#include <rix.hpp>
int main()
{
rix.debug.print("Hello from Rix");
return 0;
}Run:
vix run main.cppIf Rix is not available globally:
vix install -g rix/rix
vix run main.cppSingle-file usage with independent package
Create a file:
mkdir -p ~/rix-independent-example
cd ~/rix-independent-example
touch main.cppAdd:
#include <rix/pdf.hpp>
int main()
{
auto pdf = rixlib::pdf::module();
auto doc = pdf.document();
auto saved = pdf.save(doc, "independent.pdf");
return saved.ok() ? 0 : 1;
}Run:
vix run main.cppIf the package is not available globally:
vix install -g rix/pdf
vix run main.cppProject usage with facade
vix new facade-app --app
cd facade-app
vix add rix/rix
vix installIn vix.app:
deps = [
"rix/rix",
]In src/main.cpp:
#include <rix.hpp>
int main()
{
rix.debug.print("Hello from facade app");
return 0;
}Build and run:
vix build
vix runProject usage with independent package
vix new independent-pdf-app --app
cd independent-pdf-app
vix add rix/pdf
vix installIn vix.app:
deps = [
"rix/pdf",
]In src/main.cpp:
#include <rix/pdf.hpp>
int main()
{
auto pdf = rixlib::pdf::module();
auto doc = pdf.document();
auto saved = pdf.save(doc, "independent.pdf");
return saved.ok() ? 0 : 1;
}Build and run:
vix build
vix runMigration from independent package to facade
Before:
#include <rix/pdf.hpp>
int main()
{
auto pdf = rixlib::pdf::module();
auto doc = pdf.document();
auto saved = pdf.save(doc, "hello.pdf");
return saved.ok() ? 0 : 1;
}After:
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
auto saved = rix.pdf.save(doc, "hello.pdf");
return saved.ok() ? 0 : 1;
}Update vix.app:
deps = [
"rix/rix",
]instead of:
deps = [
"rix/pdf",
]Migration from facade to independent package
Before:
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
auto saved = rix.pdf.save(doc, "hello.pdf");
return saved.ok() ? 0 : 1;
}After:
#include <rix/pdf.hpp>
int main()
{
auto pdf = rixlib::pdf::module();
auto doc = pdf.document();
auto saved = pdf.save(doc, "hello.pdf");
return saved.ok() ? 0 : 1;
}Update vix.app:
deps = [
"rix/pdf",
]instead of:
deps = [
"rix/rix",
]Avoid mixing styles without a reason
This is usually unnecessary:
#include <rix.hpp>
#include <rix/pdf.hpp>If you use the facade, prefer:
#include <rix.hpp>and:
rix.pdfIf you use the independent package, prefer:
#include <rix/pdf.hpp>and:
auto pdf = rixlib::pdf::module();Keep one style per file unless there is a clear reason.
Common mistakes
Using the independent include but writing facade code
Wrong:
#include <rix/pdf.hpp>
int main()
{
auto doc = rix.pdf.document();
return 0;
}Correct independent usage:
#include <rix/pdf.hpp>
int main()
{
auto pdf = rixlib::pdf::module();
auto doc = pdf.document();
return 0;
}Or use the facade:
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
return 0;
}Installing rix/pdf but including <rix.hpp>
If the project uses:
#include <rix.hpp>then install the facade package:
vix add rix/rix
vix installand keep:
deps = [
"rix/rix",
]Installing rix/rix but expecting only one package
rix/rix is the unified facade.
If you want only PDF, use:
vix add rix/pdf
vix installor use the lightweight facade macros with rix/rix.
Putting Rix packages in packages
Wrong:
packages = [
"rix/pdf",
]Correct:
deps = [
"rix/pdf",
]Using rix.debug.log as production logging
rix.debug is useful for examples and development output.
For real Vix applications, prefer the Vix logging system.
What you should remember
Facade style:
vix add rix/rix
vix install#include <rix.hpp>
rix.pdf.document()Independent style:
vix add rix/pdf
vix install#include <rix/pdf.hpp>
auto pdf = rixlib::pdf::module();Use deps in vix.app:
deps = [
"rix/rix",
]or:
deps = [
"rix/pdf",
]For most Rix docs and application examples, prefer:
#include <rix.hpp>and:
rix.*Next step
Continue with feature macros.
Next: Feature macros