Architecture

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.

High-level architecture

At a high level, Vuesion consists of four main parts:

Text
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.

Frontend architecture

The frontend is responsible for everything users see and interact with.

This includes:

  • Pages
  • Layouts
  • Components
  • Forms
  • Navigation
  • Client-side state
  • Communication with the server

Vuesion follows a Flux-inspired data flow to keep frontend behavior predictable.

Text
       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

Stores hold shared reactive state.

They are intended for data that must be accessed across multiple pages or components, such as:

  • The current user
  • Workspaces
  • Application settings
  • Error states

Stores should remain focused on state. They should not become a collection of unrelated server calls or business processes.

Action composables

Action composables coordinate frontend behavior.

They are responsible for tasks such as:

  • Loading data from the server
  • Submitting changes
  • Updating stores
  • Handling loading states
  • Coordinating several related operations

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.

Services

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.

Server 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:

Text
Request
   │
   ▼
Controller
   │
   ▼
Access control
   │
   ▼
Service
   │
   ▼
Repository
   │
   ▼
Database

Not every operation requires every layer, but each layer has a distinct responsibility.

Controllers

Controllers define the server API.

They are responsible for:

  • Receiving requests
  • Parsing input
  • Triggering validation
  • Calling the appropriate service
  • Returning a response

Controllers should remain thin. They should not contain database queries or substantial business logic.

Access control

Access control determines whether the current user is allowed to perform an action.

It answers questions such as:

  • Is the user authenticated?
  • Does the user belong to the workspace?
  • Does the user have the required role?
  • May the user access or modify this resource?

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

Services contain application and business logic.

They coordinate operations such as:

  • Creating a user
  • Updating a workspace
  • Linking an authentication account
  • Sending a verification email
  • Performing several database changes in a transaction

Services are the central place for behavior that represents a meaningful application operation.

Repositories

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.

Domain-oriented organization

Server code is grouped by domain rather than only by technical type.

Typical domains include:

  • Authentication
  • Users
  • Files
  • Workspaces

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.

Shared code

The shared directory contains code that can safely run on both the frontend and the server.

Typical examples include:

  • TypeScript types
  • Enums
  • Constants
  • Validation-independent utilities
  • Generated Prisma types

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.

Database

Vuesion uses PostgreSQL with Prisma.

The Prisma schema is split by domain rather than stored in one large file.

Text
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 complete request flow

A typical workspace update may look like this:

Text
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.

Why this architecture?

Many applications begin with simple shortcuts:

  • API calls directly inside components
  • Database queries inside controllers
  • Authorization checks scattered across the codebase
  • Business logic mixed with persistence
  • Stores that own every responsibility

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:

  • Predictable
  • Testable
  • Replaceable
  • Easy to navigate
  • Suitable for long-term product development

Next steps

Continue with Design System to learn how Vuesion keeps design, implementation, and documentation aligned.