Xeno.JS Architecture Overview
Introduction
Section titled “Introduction”Xeno.JS is built around an application-centered architecture.
The application is not defined by its HTTP server, UI framework, database, or other infrastructure.
Instead, these concerns connect to an application layer that coordinates use cases and their dependencies.
At a high level:
Presentation │ ▼Application │ ▼Domain │ ▼InfrastructureThis separation is the architectural foundation of Xeno.JS.
The Xeno.JS architecture
Section titled “The Xeno.JS architecture”A typical Xeno.JS application can be understood through four main concerns:
┌─────────────────────────────────────────────┐│ Presentation ││ HTTP / CLI / Worker / UI │└──────────────────────┬──────────────────────┘ │ ▼┌─────────────────────────────────────────────┐│ Application ││ ││ Commands / Queries / Handlers / Pipelines ││ DI / Scopes / Context / Modules │└──────────────────────┬──────────────────────┘ │ ▼┌─────────────────────────────────────────────┐│ Domain ││ ││ Entities / Aggregates / Value Objects ││ Domain Events / Rules / Contracts │└──────────────────────┬──────────────────────┘ │ ▼┌─────────────────────────────────────────────┐│ Infrastructure ││ ││ DB / Repositories / Data Sources / Cache ││ HTTP Clients / Auth / Logging / Resilience │└─────────────────────────────────────────────┘These are architectural responsibilities, not necessarily four physical folders that every application must reproduce exactly.
The important property is that the boundaries are explicit.
1. Presentation
Section titled “1. Presentation”The presentation layer is where an application receives an external interaction.
Examples include:
- HTTP requests
- CLI commands
- background workers
- other application entry points
- Vue UI interactions
Presentation translates an external interaction into an application operation.
For example:
HTTP request │ ▼Presentation │ ▼Command / Query │ ▼ApplicationThe presentation layer should not become the place where the application’s business rules are implemented.
Its responsibility is to connect the outside world to the application.
Transport independence
Section titled “Transport independence”Xeno.JS does not make HTTP the center of the architecture.
An application can use a transport such as Fastify, Express, or Hono while keeping its application logic in Xeno’s application layer.
Conceptually:
┌──────────┐│ Fastify │└────┬─────┘ │┌────▼────────────────┐│ Xeno Application │└────┬─────────────────┘ │ ▼ DomainThe transport can therefore change without requiring the application model to change with it.
2. Application
Section titled “2. Application”The application layer is the center of execution in Xeno.JS.
It coordinates what the application does.
This layer contains concepts such as:
- commands
- queries
- handlers
- pipelines
- dependency injection
- service scopes
- request context
- modules
- application composition
A simplified execution flow is:
Command / Query │ ▼ Mediator │ ▼ Pipeline │ ▼ Handler │ ▼ Application ResultThis is one of the most important aspects of the Xeno.JS architecture.
The framework does not treat CQRS as an isolated utility.
Commands, queries, handlers, dependency resolution, scopes, and pipelines participate in the application’s execution model.
3. Commands and Queries
Section titled “3. Commands and Queries”Xeno.JS represents application operations through commands and queries.
A command represents an operation that changes application state.
A query represents an operation that retrieves information.
Conceptually:
Command │ ▼Command Pipeline │ ▼Command Handler
Query │ ▼Query Pipeline │ ▼Query HandlerThe mediator is responsible for finding the appropriate handler and executing the request through the configured pipeline.
This keeps the application entry point independent from the concrete handler implementation.
For example:
HTTP Controller │ ▼CreateUserCommand │ ▼Mediator │ ▼CreateUserHandler │ ▼Domain / RepositoryThe controller does not need to know how the use case is implemented.
4. Pipelines
Section titled “4. Pipelines”Application execution can require behavior that should not be implemented repeatedly inside every handler.
Examples include:
- validation
- authorization
- logging
- performance measurement
- idempotency
- concurrency handling
- exception handling
- query behavior
Xeno.JS models these concerns through pipelines.
Request │ ▼┌───────────────────┐│ Validation │├───────────────────┤│ Authorization │├───────────────────┤│ Logging │├───────────────────┤│ Performance │├───────────────────┤│ Handler │└───────────────────┘The exact pipeline configuration is application-dependent.
The architectural principle is that cross-cutting execution can be composed around the use case instead of being duplicated across individual entry points.
5. Dependency Injection and Composition
Section titled “5. Dependency Injection and Composition”Xeno.JS uses explicit dependency injection.
Dependencies are registered in the application’s composition root rather than discovered through decorators or implicit runtime scanning.
The central composition mechanism is AppBuilder.
Conceptually:
AppBuilder │ ├── configuration ├── modules ├── services ├── pipelines ├── infrastructure └── application components │ ▼ ServiceContainerA simplified composition looks like:
const app = new AppBuilder()
.addServices((services) => { services.addScoped( 'USER_REPOSITORY', (container) => new UserRepository( container.resolve('USER_DATA_SOURCE') ) ) })
.addPipeline()
.addDb(/* configuration */)
.addLogger()
await app.build()The important property is not the fluent API itself.
It is that the dependency graph is explicitly composed.
6. Service Lifetimes and Scopes
Section titled “6. Service Lifetimes and Scopes”Xeno.JS distinguishes dependency lifetimes such as:
- singleton
- scoped
- transient
This allows dependencies to have an explicit lifecycle.
For example:
Application │ ├── Singleton │ ├── Scoped ─────── Request / Execution Scope │ └── TransientA scoped service belongs to the current application execution scope.
This becomes particularly important when an application uses request-specific dependencies such as:
- request context
- transaction state
- scoped repositories
- request-specific services
The service container also tracks dependency resolution and detects conditions such as circular dependencies and captive scoped dependencies.
7. Request Context
Section titled “7. Request Context”Xeno.JS connects request context with the service scope.
In the Node.js implementation, asynchronous request context is propagated through AsyncLocalStorage.
Conceptually:
Incoming Request │ ▼Request Context │ ├── Identity ├── Network Context └── Service Scope │ ▼ Application ExecutionThe context allows request-specific information to remain available throughout asynchronous application execution without passing it manually through every method.
The scope is also disposed when the request execution finishes.
This makes request boundaries an explicit part of the application runtime.
8. Domain
Section titled “8. Domain”The domain represents the business concepts and rules of the application.
Xeno.JS and @xeno-js/shared provide domain-oriented primitives including:
- entities
- aggregates
- value objects
- domain events
- domain errors
- domain contracts
- result types
The purpose of the domain layer is to express business concepts without making them dependent on a particular transport or infrastructure implementation.
A simplified model is:
Domain├── Entities├── Value Objects├── Aggregates├── Domain Events├── Domain Errors└── Domain ContractsThe domain is therefore different from the application layer.
The application coordinates a use case.
The domain expresses the business model used by that use case.
9. Infrastructure
Section titled “9. Infrastructure”Infrastructure contains concrete implementations and integrations required by the application.
Examples in the Xeno.JS ecosystem include:
- databases
- repositories
- data sources
- HTTP clients
- caching
- authentication
- logging
- resilience
- configuration
The conceptual relationship is:
Application │ │ depends on contracts ▼ Contracts ▲ │ implemented by │InfrastructureFor example, an application may depend on a repository contract while infrastructure provides the concrete database-backed repository.
This keeps infrastructure details out of the application and domain model.
10. Data Sources and Repositories
Section titled “10. Data Sources and Repositories”Xeno.JS distinguishes between application-facing persistence abstractions and infrastructure-level data access.
A simplified flow is:
Application │ ▼Repository Contract │ ▼Repository Implementation │ ▼Data Source │ ▼DatabaseThis distinction prevents database-specific APIs from becoming the application’s primary abstraction.
The application asks for the capability it needs.
Infrastructure determines how that capability is implemented.
11. Modules
Section titled “11. Modules”Xeno.JS uses modules to compose optional application capabilities.
The AppBuilder can queue and initialize modules during application bootstrap.
Conceptually:
AppBuilder │ ├── Context Module ├── Pipeline Module ├── Logger Module ├── Auth Module ├── Database Module ├── Cache Module ├── HTTP Module └── Custom ModulesThis allows infrastructure and application capabilities to be enabled explicitly rather than requiring every application to use the same runtime configuration.
The application composition therefore becomes part of the architecture itself.
12. The Xeno.JS Ecosystem
Section titled “12. The Xeno.JS Ecosystem”The architecture is distributed across several packages.
They have different responsibilities.
Xeno.JS
@xeno-js/shared │ Domain primitives & contracts │ ┌─────────────┴─────────────┐ │ │ ▼ ▼ @xeno-js/core @xeno-js/vue │ │ Node.js application Vue application runtime runtime │ │ └─────────────┬─────────────┘ │ ▼ @xeno-js/cli scaffolding & generators@xeno-js/shared
Section titled “@xeno-js/shared”@xeno-js/shared contains framework-neutral concepts shared across the ecosystem.
Its source structure includes domain primitives such as:
- aggregates
- entities
- value objects
- domain events
- errors
- results
It also defines application contracts for commands and queries.
The package therefore provides a common architectural language without owning the Node.js runtime or Vue runtime.
@xeno-js/core
Section titled “@xeno-js/core”@xeno-js/core is the main Node.js application architecture package.
It provides:
- application composition
- dependency injection
- service lifetimes
- service scopes
- CQRS
- mediator execution
- pipelines
- request context
- modules
- repositories
- data sources
- infrastructure integrations
The package contains the runtime mechanisms that execute the application architecture.
@xeno-js/vue
Section titled “@xeno-js/vue”@xeno-js/vue brings the Xeno application model into Vue applications.
Its structure includes its own:
- application layer
- domain contracts
- infrastructure
- context
- data sources
- application pipelines
- application builder
It also re-exports the shared architectural language from @xeno-js/shared.
This means the frontend is not treated simply as a collection of UI components.
It can participate in the same application-oriented model.
@xeno-js/cli
Section titled “@xeno-js/cli”@xeno-js/cli is the developer tooling layer.
It is responsible for:
- creating Xeno projects
- selecting project types
- generating architecture-aligned files
- generating commands
- generating queries
- scaffolding Core applications
- scaffolding Vue applications
The CLI does not execute the application architecture at runtime.
It creates the starting structure that the other packages execute.
13. How the Packages Relate
Section titled “13. How the Packages Relate”The relationship can be summarized as:
┌───────────────────┐ │ @xeno-js/shared │ │ │ │ Domain primitives │ │ Application │ │ contracts │ └─────────┬─────────┘ │ ┌─────────────┴─────────────┐ │ │ ▼ ▼ ┌────────────────────┐ ┌────────────────────┐ │ @xeno-js/core │ │ @xeno-js/vue │ │ │ │ │ │ Node.js runtime │ │ Vue runtime │ │ DI / CQRS / Scope │ │ DI / CQRS / Pipes │ │ Context / Modules │ │ Context / Sources │ └─────────┬──────────┘ └─────────┬──────────┘ │ │ └─────────────┬─────────────┘ ▼ ┌──────────────────┐ │ @xeno-js/cli │ │ │ │ Scaffold / Gen │ └──────────────────┘The important distinction is:
Shared defines common concepts. Core and Vue execute those concepts in their respective environments. CLI creates projects and components around them.
14. A Complete Application Flow
Section titled “14. A Complete Application Flow”Putting the architecture together, a backend request can be understood as:
HTTP Request │ ▼ Presentation Layer │ ▼ Command / Query │ ▼ Mediator │ ▼ Pipeline ┌──────────┼──────────┐ │ │ │ Validation Authorization Logging │ │ │ └──────────┼──────────┘ ▼ Handler │ ▼ Domain Logic │ ▼ Repository Contract │ ▼ Repository / DataSource │ ▼ DatabaseThe response then travels back through the application boundary to the presentation layer.
The important point is that the HTTP request is only the entry point.
The application architecture does not depend on HTTP being the thing that defines the use case.
15. Frontend Application Flow
Section titled “15. Frontend Application Flow”The same architectural idea can be applied in a Vue application.
A simplified flow is:
Vue UI │ ▼ Application Action │ ▼ Mediator / Pipe │ ▼ Application │ ▼ Remote Data Source │ ▼ BackendThis allows the frontend to use application-oriented concepts instead of placing all application behavior directly inside Vue components.
The exact frontend composition is provided by @xeno-js/vue.
16. The Composition Root
Section titled “16. The Composition Root”One of the most important architectural concepts in Xeno.JS is the composition root.
This is where the application decides:
- which services exist
- which implementations they use
- which lifetimes they have
- which modules are enabled
- which pipelines are configured
- which infrastructure is available
In Xeno.JS, AppBuilder provides the primary mechanism for this composition.
Composition Root │ AppBuilder │ ┌────────────────┼─────────────────┐ │ │ │ ▼ ▼ ▼ Dependencies Modules Pipelines │ │ │ └────────────────┼─────────────────┘ ▼ Application RuntimeThis is where the application’s architecture becomes executable configuration.
17. Why the Architecture Is Application-Centered
Section titled “17. Why the Architecture Is Application-Centered”The architecture can be summarized by moving from the outside inward:
Transport ↓Presentation ↓Application ↓Domain ↓InfrastructureBut the dependencies are not intended to make infrastructure the center of the system.
The application defines what it needs.
Infrastructure supplies implementations.
This gives the application a stable center while allowing external technologies to change around it.
For example:
┌── PostgreSQL │Application ────┼── Redis │ ├── External API │ └── Another implementationThe concrete technology can change without redefining the application’s business use cases.
18. The Architectural Boundary
Section titled “18. The Architectural Boundary”The most important boundary in Xeno.JS is not a particular folder.
It is the boundary between:
Application Intent │ ▼ ┌───────────────┐ │ Application │ └───────┬───────┘ │ explicit contracts │ ▼ ┌───────────────┐ │ Infrastructure │ └───────────────┘The application should express what it needs.
Infrastructure should determine how that need is fulfilled.
This is what allows Xeno.JS to remain independent from a specific transport, database, or infrastructure implementation.
19. Architecture in One Diagram
Section titled “19. Architecture in One Diagram”The complete Xeno.JS model can therefore be reduced to:
┌──────────────────────────────────────────────────────────────┐│ ENTRY POINTS ││ ││ HTTP CLI Worker Vue / Browser │└──────────────────────────────┬───────────────────────────────┘ │ ▼┌──────────────────────────────────────────────────────────────┐│ PRESENTATION ││ ││ Translate external interactions into use cases │└──────────────────────────────┬───────────────────────────────┘ │ ▼┌──────────────────────────────────────────────────────────────┐│ APPLICATION ││ ││ Commands • Queries • Handlers • Mediator • Pipelines ││ Dependency Injection • Scopes • Context • Modules │└──────────────────────────────┬───────────────────────────────┘ │ ▼┌──────────────────────────────────────────────────────────────┐│ DOMAIN ││ ││ Entities • Aggregates • Value Objects • Events • Rules │└──────────────────────────────┬───────────────────────────────┘ │ ▼┌──────────────────────────────────────────────────────────────┐│ INFRASTRUCTURE ││ ││ Database • Repositories • Data Sources • Cache • Auth ││ HTTP Clients • Logging • Resilience • External Services │└──────────────────────────────────────────────────────────────┘
SHARED ARCHITECTURAL LANGUAGE
@xeno-js/shared │ ┌──────────────┴──────────────┐ ▼ ▼ @xeno-js/core @xeno-js/vue │ │ └──────────────┬──────────────┘ ▼ @xeno-js/cliThis is the mental model to keep while reading the rest of the documentation.
Support Us
Section titled “Support Us”Xeno.JS is an MIT-licensed open source project. It can grow thanks to the support of these awesome people. If you’d like to join them, please read more at support section
