App Suite UI (latest)
All versions
Imprint
All versions
Imprint
  • Feature Catalog
    • General
      • Getting around
      • Search and notifications
      • Settings and appearance
      • Signing in
      • Account and security
      • Onboarding and devices
      • Working with content
      • Sharing and delegation
      • Storage, plans and feedback
      • Progressive Web App
      • Feedback
      • Upsell
      • Triggers
    • Mail
      • Reading and organizing
      • Attachments
      • Writing and sending
      • Security and trust
      • Accounts and automation
      • Signatures and templates
      • Working with the other apps
      • BIMI
    • Calendar
      • Seeing your day
      • Appointments
      • People and invitations
      • Calendars and subscriptions
      • Rooms and resources
      • Video meetings
      • Search, print and transfer
    • Address Book
      • Contacts
      • Address books
      • Finding people
      • Lists and the other apps
    • Tasks
      • Tasks
      • Task lists and delegation
      • Working with the other apps
    • Drive
      • Working with files
      • Finding and arranging
      • Sharing
      • Storages and capacity
      • Working with the other apps
      • OpenCloud Drive Integration
    • Portal
    • Enterprise and Provider Edition
    • Compliance

      • Accessibility
      • Accessibility Conformance Report
      • Data protection
  • Upgrade Guide
    • Everything new since 7.10.6
    • From 7.10.6 to 8.35
    • From 8.35 to 8.47
    • From 8.47 to 8.55
    • Breaking changes and requirements
  • Deployment Guide

    • Configuration
    • Settings list
    • Login page
    • What's New dialog
    • Mail assets
    • Mail rendering and security
    • All messages folder
    • Unseen messages folder
    • Theming
    • Authentication
    • Browser support
  • Customize & Extend
    • Manifests
    • Toolbars and menus
    • Portal widget
    • Sign In
    • Internationalization
  • Architecture
    • Core UI service

Architecture overview

This section describes how App Suite UI is put together and where the seams are. It is written for engineers who integrate with the UI, write plugins against it, or need to reason about a deployment. For step-by-step instructions see Customize & Extend; for settings and operations see the Deployment Guide.

What gets deployed

App Suite UI ships as a single container that runs two things at once:

  • The web client - a single-page application that runs entirely in the browser.
  • The Core UI service - a Node.js service that serves the client's static assets and provides a small set of UI-facing HTTP endpoints. See Core UI service.

Until 8.46 the container was a static nginx server. It is now a Fastify-based Node.js service, which has operational consequences - see Breaking changes and requirements before upgrading.

The client talks to three places:

TargetUsed for
App Suite MiddlewareAll domain data: mail, calendar, contacts, tasks, files, folders, sessions
Core UI serviceUI-specific endpoints such as BIMI logos, JWT issuance, mail asset catalogs
Third-party servicesOnly where a feature explicitly integrates one (for example an AI service)

The Middleware remains the system of record. The Core UI service never duplicates domain data; it exists for work that is specific to the frontend and does not belong in the Java middleware.

Runtime composition

The client is not one monolithic bundle. It is assembled at runtime from three layers.

Boot. The HTML entry points (index.html for the application, plus blank.html, busy.html and print.html for auxiliary windows) load a small set of concatenated bundles. Boot establishes the session, loads the user's settings and capabilities, and then hands over to the application.

Modules. Everything below src/io.ox/ is a module. The io.ox path segment is historical and is best read as "the application root". The top-level split follows the product:

PathContents
src/io.ox/mail/, calendar/, contacts/, tasks/, files/The applications
src/io.ox/settings/Settings UI
src/io.ox/core/Shared platform: session, folders, capabilities, extensions, date/time
src/io.ox/backbone/Shared view and model base classes
src/pe/Modules specific to the Provider Edition
src/plugins/Plugin entry points

Manifests and plugins. Modules declare themselves through manifests, which are collected at build time into module and plugin metadata. The manifest decides when a piece of code is loaded and under which capability. Plugins are discovered the same way, which is why custom code does not need to be linked into the application - registering a manifest is enough. See Manifests.

Extension points

Extension points are the composition mechanism of the UI and the main reason custom code can change behavior without forking. A view does not hard-code its contents; it renders an extension point, and anything registered on that point - by core, by the Provider Edition, or by a plugin - contributes to the result. Registrations carry an index, which determines order, so a plugin can place itself before or after an existing entry rather than replacing it.

Toolbars, context menus, detail views, settings panes and the folder tree are all built this way. Where entries end up, and how a toolbar decides what becomes a button and what moves into the overflow menu, is described in Toolbars and menus.

Mixed Backbone and Vue

The codebase contains both legacy Backbone/jQuery views and modern Vue 3 components, by design and for some time to come. New functionality is written in Vue; existing Backbone code is migrated when there is a reason to touch it, not wholesale.

For integrators the practical consequence is that the surface you extend depends on where you attach. Extension points, manifests and capabilities work identically on both sides. Direct DOM assumptions do not, and are the thing most likely to break across releases.

Settings and capabilities

Two separate mechanisms decide what a user gets.

Capabilities come from the Middleware and express what the user is licensed and permissioned to use. The client reads them at boot and gates functionality on them. A missing capability can either hide a feature or surface an upsell trigger.

Settings are delivered as JSlobs - JSON structures the Middleware assembles from property files and exposes over the JSlob API. A setting can be protected, in which case it is read-only for both the user and UI code. This is the lever operators use to enforce a value; it is described in full under Configuration.

Deployment-wide feature toggles live in the same settings space under io.ox/core//features/. They are never user-editable and are how functionality is rolled out gradually.

Theming and assets

Themes are SCSS, compiled at build time, with a shared variable layer that custom themes override. Colors, logos and the login page can additionally be changed at runtime through configuration, without building a theme - see Theming and Login page. Dynamic theming selects a theme by brand, which is why a hoster can serve several brands from one deployment.

Internationalization

Translatable text uses gettext. Strings are extracted into .po catalogs per language and compiled into runtime dictionaries at build time; the default dictionary is io.ox/core and the source language is en_US. Plural handling, context and the rules for interpolating values into strings are covered in Internationalization.

Date and time

Date and time handling is built on the ECMAScript Temporal API, wrapped in a thin internal layer so the application has one date/time surface instead of several. This replaced the previous moment.js and luxon usage. The distinction that matters for integrators is between a point in time, a wall-clock time in a time zone, and a plain calendar date - the UI keeps those apart deliberately, because all-day appointments and timed appointments are not the same kind of value.

Last Updated: 10/7/26, 2:41 PM
Prev
Customize & Extend