Skip to main content

Architecture Overview

Every Oidis application follows the same architectural principles: a clear frontend/backend split within a single TypeScript project, a namespace-driven filesystem, and a layered dependency chain that promotes code reuse.

Frontend / Backend Split​

An Oidis project contains both server-side and client-side code in a single repository. The split is determined by directory structure:

source/typescript/Io/Oidis/YourProject/
├── Models/ # ← Backend (Node.js)
├── Utils/ # ← Backend
├── HttpProcessor/ # ← Backend
├── Connectors/ # ← Backend
├── Interfaces/ # ← Shared
├── Loader.ts # ← Backend entry point
├── ForceCompile.ts # ← Backend compile manifest
│
└── Gui/ # ← Frontend (Browser)
├── Models/ # ← Frontend models
├── Pages/ # ← Frontend page layouts
├── Panels/ # ← Frontend panel views
├── Controllers/ # ← Frontend controllers
├── Connectors/ # ← Frontend RPC stubs
├── Stores/ # ← Frontend state
├── Loader.ts # ← Frontend entry point
└── ForceCompile.ts # ← Frontend compile manifest

The rule is simple: everything under Gui/ runs in the browser. Everything else runs on the server. The Interfaces/ directory can contain types shared by both sides.

Each side has its own Loader.ts that bootstraps the application — registering classes, setting up symbol mappings, and initializing the runtime environment.

Large Project Variant: Separate GUI Repository​

In smaller projects, Gui/ is a subdirectory of the same repository. In larger projects — Hub, Home, and Studio — the Gui/ subtree lives in a separate git repository (io-oidis-hub-gui, io-oidis-home-gui, io-oidis-studio-gui) declared as a dependency in package.conf.jsonp.

io-oidis-hub/                  ← Backend repository
├── source/typescript/.../ ← BE code
└── dependencies/
└── io-oidis-hub-gui/ ← Frontend repo (cloned by oidis install, gitignored)

io-oidis-hub-gui/ ← Frontend repository (standalone, noServer: true)
└── source/typescript/.../Gui/ ← FE code only

This hard separation prevents native Node.js imports from accidentally reaching the browser bundle. The GUI repo has noServer: true in its package.conf.jsonp and produces only a browser bundle. The backend serves this bundle via its FrontEndLoader.ts resolver.

tip

The developer workflow for editing GUI code in this pattern (using IntelliJ Compare or Beyond Compare to sync changes between the dependencies/ context and the standalone clone) is covered in detail in Separate GUI Repository. For the complete cross-repo workflow including merge pitfalls, reverse sync, and Claude Code automation, see Cross-Repository Workflow.

Namespace Convention​

Oidis uses a Java/C#-style namespace convention reflected in the filesystem:

Io/Oidis/[LibraryName]/[SubModule]/[ClassName].ts

For example:

  • Io/Oidis/YourProject/Models/ProductRecord.ts → namespace Io.Oidis.YourProject.ProductRecord
  • Io/Oidis/Hub/Utils/AuthManager.ts → namespace Io.Oidis.Hub.AuthManager

This namespace is used throughout the framework for:

  • LCP routing — Backend classes are resolved by namespace string
  • Symbol mapping — Loader.setSymbolMapping() creates aliases
  • Configuration — JSONP config files reference classes by namespace

Dependency Chain​

Oidis projects are built on a layered dependency chain. Each layer adds functionality:

io-oidis-commons          ← Core utilities, decorators, BaseModel
↓
io-oidis-services ← Backend services, DAO layer, connectors base
↓
io-oidis-gui ← BasePanel, EventsBinding, GuiCommons
↓
io-oidis-usercontrols ← Button, TextField, Table, Dialog, Toast, ...
↓
io-oidis-localhost ← @Extern, @Route, local system connectors
↓
io-oidis-hub ← Hub backend (AuthManager, SystemLog, DB context)
↓
io-oidis-hub-gui ← Hub frontend (BasePanelController, Convert, base panels)
↓
io-oidis-[your-project] ← Your application

Key principle: Lower layers know nothing about higher layers. A utility in io-oidis-commons cannot import from io-oidis-hub. Dependencies flow strictly downward.

What Each Layer Provides​

PackageKey Exports
io-oidis-commonsBaseModel<T>, @Entity, @Property, @Resolver, @Partial, LogIt, ObjectValidator, StringUtils, JsonUtils, Convert, Echo, Stopwatch, Reflection, Counters — see Utilities Overview
io-oidis-servicesBaseConnector (backend), DAO abstractions, FileFetch
io-oidis-guiBasePanel, EventsBinding, GuiCommons, ElementEventsManager, data-oidis-bind system
io-oidis-usercontrolsButton, TextField, Label, DropDownList, Table<T>, Dialog, Toast, CheckBox, ValidationBinding, DialogBinding
io-oidis-localhost@Extern, @Route, BaseConnector (extended), LiveContentResolver
io-oidis-hubAuthManager, SystemLog, MongoContext, Threads, ConnectorsRegister
io-oidis-hub-guiBasePanelController, BasePageController, Convert, hub base panels

Import Conventions​

Imports always use package aliases with .js extensions:

import { LogIt } from "@io-oidis-commons/.../Utils/LogIt.js";
import { BasePanel } from "@io-oidis-gui/.../BasePanel.js";
import { BasePanelController } from "@io-oidis-hub-gui/.../BasePanelController.js";

For files within the same project, use relative imports:

import { ProductRecord } from "../../Models/ProductRecord.js";
import { InventoryManagerConnector } from "../../Connectors/InventoryManagerConnector.js";

The Loader System​

Each side of an Oidis application has a Loader.ts that serves as the bootstrap entry point.

Backend Loader​

The backend Loader typically:

  • Extends the parent hub Loader
  • Sets up ConnectorsRegister symbol mappings (namespace aliases)
  • Registers backend-specific services
  • Initializes database connections
// Simplified example — real loaders extend hub Loader
export class Loader extends HubLoader {

public constructor() {
super();
// Map namespace aliases for LCP resolution
ConnectorsRegister.setSymbolMapping(
"*.AuthManager",
"Io.Oidis.YourProject.Utils.AuthManager"
);
}
}

Frontend Loader (Gui/Loader.ts)​

The frontend Loader:

  • Extends the hub-gui Loader
  • Registers frontend-specific classes
  • Initializes the GUI environment

Both Loaders inherit from their respective parent layers and add project-specific registrations on top.

ForceCompile.ts​

Each side also has a ForceCompile.ts file that ensures certain classes are included in the compiled output even when they have no direct import chain. This is essential for:

  • LCP-referenced classes — Backend connectors called via @Extern must be compiled even though no frontend code directly imports them
  • Dynamically resolved classes — Any class found by namespace string at runtime
// ForceCompile.ts — ensures these classes are in the bundle
import { AuthManager } from "./Utils/AuthManager.js";
import { InventoryManager } from "./Utils/InventoryManager.js";

// generated-code-start
// Builder auto-generates additional imports here
// NEVER edit between these markers
// generated-code-end
warning

The section between generated-code-start and generated-code-end markers is managed by the Oidis Builder. Manual edits in this section will be overwritten on the next build.

Configuration Layer​

tip

The JSONP configuration system — including extendsConfig, imports, and how the Builder generates standard files — is covered in detail in JSONP System.

Oidis projects use a JSONP-based configuration system instead of standard package.json:

  • package.conf.jsonp — Source of truth for project identity, dependencies, build settings
  • commons.jsonp — Runtime configuration (database, auth, APIs)
  • licensesRegister.jsonp — Software Content Register entries

The Builder reads these files and generates package.json, tsconfig.json, webpack.config.js, and other standard files. See JSONP System for details.

Build Process​

Oidis uses its own build toolchain (Oidis Builder) rather than raw tsc or webpack:

  1. oidis install — Resolves JSONP dependencies, generates config files, installs npm packages
  2. oidis rebuild — Compiles TypeScript, processes SCSS, bundles frontend assets
  3. oidis test — Runs unit tests, Selenium tests, and linting

The Builder handles:

  • JSONP → JSON generation (package.json, tsconfig.json, etc.)
  • extendsConfig / imports resolution (config inheritance and composition)
  • TypeScript compilation with project-specific settings
  • SCSS compilation with theme support
  • dev:start / dev:end marker stripping in production builds
  • Copyright header validation
  • Software Content Register generation

Two GUI Systems​

Bootstrap 5 system is the only option for new development

The Oidis GUI layer contains two systems: the Bootstrap 5 system (modern, active) and the legacy system (deprecated). All new development must use the Bootstrap 5 system. The legacy system exists for backward compatibility of older projects only.

See Bootstrap 5 vs Legacy for a full comparison, how to identify each, and migration guidance.

Summary​

ConceptDescription
FE/BE splitGui/ = browser, everything else = server
Separate GUI repoLarge projects (Hub, Home, Studio) keep GUI in a separate git repo — see Separate GUI Repository
Cross-repo workflowForward and reverse sync between dependencies/ and standalone clones — see Cross-Repository Workflow
NamespaceIo.Oidis.[Library].[Class] mirrored in filesystem
DependenciesLayered chain: commons → services → gui → hub → project
Two GUI systemsBootstrap 5 (active) and Legacy (deprecated) — see Bootstrap 5 vs Legacy
LoadersBootstrap entry points for each side
ForceCompileEnsures dynamically-resolved classes are compiled
JSONP configSource of truth; Builder generates standard files
BuilderCustom toolchain for install, build, test, deploy
Request ForwardingHub acts as reverse proxy for agents behind firewalls via WebSocket tunneling — see Request Forwarding
User ProfilePer-user data and preferences (avatar, personal info, 2FA) with admin and self-service interfaces — see User Profile
UserContextRuntime session object holding auth state, user identity, group flags, and device info — see UserContext
System GroupsGroup-based authorization with predefined roles, wildcard method patterns, and extensible permissions — see System Groups
HttpProcessor (Services)Services-level HTTP layer: JRE-aware HttpManager, DAO-based page controllers, auth/error pages — see HttpProcessor Services
Connectors ReferenceComprehensive reference for BaseConnector, transport clients, and all frontend connectors — see Connectors Reference
io-oidis-localhostCore server runtime — HTTP server, routing, connectors, response API, and backend utilities — see Localhost Overview
HTTP Processing PipelineRequest processing chain from raw socket through HttpServer, HttpManager, and HttpResolver — see HTTP Processing Pipeline
Response APITyped HTTP response handlers — REST, Stream, LiveContent, WebSocket, and Callback — see Response API
LCP Protocol InternalsWire format, response deserialization, error propagation, event polling, and callback chain — see LCP Protocol Internals

See also: Bootstrap 5 vs Legacy | Page-Panel-Controller | Separate GUI Repository | JSONP System | Framework Overview