Vuesion is designed around a simple principle:
Keep responsibilities clearly separated.
The frontend, server, shared code, and database each have a distinct purpose. Within those areas, Vuesion uses predictable patterns for state management, data access, business logic, and authorization.
The goal is not to introduce architecture for its own sake. The goal is to make it obvious where code belongs and how data moves through the application.
At a high level, Vuesion consists of four main parts:
Browser
│
▼
Frontend
│
▼
Server API
│
▼
PostgreSQL
Shared types, enums, constants, and utilities
are used across the frontend and server.
Each layer has a clear responsibility and communicates through defined boundaries.
The frontend is responsible for everything users see and interact with.
This includes:
Vuesion follows a Flux-inspired data flow to keep frontend behavior predictable.
Page
│
▼
Action composable
│
├── calls the server
└── updates the store
│
▼
Reactive UI
Data flows in one direction. Components trigger actions, actions communicate with the server, and stores expose the resulting state to the UI.
Stores hold shared reactive state.
They are intended for data that must be accessed across multiple pages or components, such as:
Stores should remain focused on state. They should not become a collection of unrelated server calls or business processes.
Action composables coordinate frontend behavior.
They are responsible for tasks such as:
For example, a user action composable may fetch the current user from the API and update the corresponding store.
This keeps pages and components focused on presentation and interaction instead of request orchestration.
Frontend services are intentionally rare.
Most application behavior belongs either in action composables or on the server.
The primary service provided by Vuesion is an event bus for application-wide communication, such as displaying toast notifications or triggering global UI events.
Keeping the service layer intentionally small avoids unnecessary abstractions and helps maintain a predictable frontend architecture.
The server is organized around domains and clear application layers.
Vuesion uses ideas from domain-driven design where they improve clarity, without introducing unnecessary abstractions.
A typical request flows through the following layers:
Request
│
▼
Controller
│
▼
Access control
│
▼
Service
│
▼
Repository
│
▼
Database
Not every operation requires every layer, but each layer has a distinct responsibility.
Controllers define the server API.
They are responsible for:
Controllers should remain thin. They should not contain database queries or substantial business logic.
Access control determines whether the current user is allowed to perform an action.
It answers questions such as:
Authorization is treated as an explicit part of the request flow rather than being hidden inside UI conditions.
The frontend may hide unavailable actions for usability, but the server remains the source of truth.
Services contain application and business logic.
They coordinate operations such as:
Services are the central place for behavior that represents a meaningful application operation.
Vuesion intentionally does not introduce an additional repository layer.
Prisma already provides a powerful, type-safe data access API, making custom repository abstractions unnecessary in most applications.
Services interact directly with the generated Prisma Client, keeping the architecture lightweight and reducing boilerplate without sacrificing maintainability.
Controllers should never access the database directly. All persistence happens through services using Prisma.
Server code is grouped by domain rather than only by technical type.
Typical domains include:
This keeps related controllers, services, repositories, access rules, and types close to the concept they belong to.
As a result, developers can understand and change a feature without navigating through many unrelated parts of the codebase.
The shared directory contains code that can safely run on both the frontend and the server.
Typical examples include:
Shared code must remain independent of browser-only and server-only APIs.
This boundary prevents accidental coupling and makes it clear which code can be reused across the application.
Vuesion uses PostgreSQL with Prisma.
The Prisma schema is split by domain rather than stored in one large file.
prisma/schema/
├── auth.prisma
├── file.prisma
├── user.prisma
└── workspace.prisma
This mirrors the domain-oriented server structure and keeps the data model understandable as the application grows.
Database access should normally happen through Prisma or focused server-side operations rather than directly inside controllers.
A typical workspace update may look like this:
User submits a form
│
▼
Page calls a workspace action composable
│
▼
Action composable sends an API request
│
▼
Controller validates the request
│
▼
Access control verifies the user's permissions
│
▼
Service coordinates the update
│
▼
Repository writes to PostgreSQL
│
▼
The response updates the frontend store
│
▼
The interface reacts automatically
This flow may look more structured than placing everything in a page or API handler, but it keeps responsibilities clear and makes each part easier to test.
Many applications begin with simple shortcuts:
These shortcuts work initially but become difficult to maintain as the product grows.
Vuesion establishes clear boundaries from the beginning while keeping the individual layers small and practical.
The result is an architecture that is:
Continue with Design System to learn how Vuesion keeps design, implementation, and documentation aligned.