ObjectStackObjectStack Protocol

ObjectOS Overview

The runtime orchestration layer - Lifecycle, plugins, configuration, and system services

ObjectOS: The System Protocol

ObjectOS is ObjectStack's runtime orchestration layer that manages the complete lifecycle of the platform. It provides the "operating system" services that coordinate ObjectQL (data) and ObjectUI (interface) into a cohesive application runtime.

The Core Problem

Traditional enterprise platforms tightly couple infrastructure concerns with business logic:

  • Deployment Hell: Change one configuration file? Rebuild entire monolith, redeploy all services, pray nothing breaks
  • Plugin Chaos: Want to add Stripe billing? Write custom integration code, manage dependencies manually, debug version conflicts
  • Configuration Drift: Dev environment uses JSON files, staging uses environment variables, prod uses database config. Which is the source of truth?
  • Lifecycle Management: Installing a package requires 47-step runbook: create database tables, run migrations, configure permissions, restart services
  • Multi-Tenancy Nightmare: Each customer tenant needs isolated configuration, but they all run the same codebase. How do you manage 500 tenant-specific settings?

Result: DevOps teams spend 60% of their time on deployment mechanics instead of building features. Configuration errors cause 80% of production incidents.

The ObjectOS Solution

Declarative Lifecycle

Define system state in manifests. ObjectOS ensures runtime matches declarationβ€”no manual runbooks.

Plugin Isolation

Microkernel architecture: Core runtime <10MB. All features are plugins with dependency management.

Unified Configuration

Single source of truth: Merge environment vars, config files, tenant settings, user preferencesβ€”deterministically.

Built-in i18n

Multi-language support at the platform level. No library integration, no translation service APIs.

Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     Application Layer                            β”‚
β”‚  ObjectQL (Data) + ObjectUI (Interface) + Business Logic         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        ObjectOS                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚ Lifecycle Mgmt β”‚  β”‚ Plugin Registry β”‚  β”‚ Config Resolver  β”‚   β”‚
β”‚  β”‚  Boot/Install  β”‚  β”‚  Dependencies   β”‚  β”‚  Merge Strategy  β”‚   β”‚
β”‚  β”‚    Upgrade     β”‚  β”‚   Versioning    β”‚  β”‚  Multi-tenant    β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  i18n Engine   β”‚  β”‚  Event Bus     β”‚  β”‚  Job Scheduler   β”‚   β”‚
β”‚  β”‚  Translations  β”‚  β”‚  Pub/Sub       β”‚  β”‚  Cron/Interval   β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Audit Logger  β”‚  β”‚  Secret Store  β”‚  β”‚  Tenant Isolator β”‚   β”‚
β”‚  β”‚  Change Track  β”‚  β”‚  Encryption    β”‚  β”‚  Multi-org       β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β–Ό                   β–Ό
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚  PostgreSQL  β”‚    β”‚    Redis     β”‚
        β”‚   (Primary)  β”‚    β”‚   (Cache)    β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Insight: ObjectOS is the control plane. ObjectQL and ObjectUI are the data plane. Separating concerns allows independent evolution.

Core Components

Why ObjectOS Exists

Problem: Deployment Complexity Kills Agility

Traditional Approach:

# 47-step deployment runbook
1. Pull latest code
2. Run database migrations (hope they don't fail)
3. Update config.yaml (which version?)
4. Restart service 1, wait 30s
5. Restart service 2, wait 30s
...
47. Pray to the demo gods

ObjectOS Approach:

# Declarative deployment
objectstack deploy @mycompany/crm@2.0.0
# βœ“ Validated dependencies
# βœ“ Applied schema changes
# βœ“ Updated configuration
# βœ“ Zero-downtime restart
# Done in 12 seconds.

Business Value: A SaaS company reduced deployment time from 45 minutes (with 20% failure rate) to 90 seconds (with 0.1% failure rate). They now deploy 10x per day instead of weekly.

Problem: Plugin Dependency Hell

Traditional Approach:

// package.json
"dependencies": {
  "stripe": "^10.0.0",      // Need 10.x
  "accounting-plugin": "*",  // This needs stripe@9.x
  // πŸ’₯ Conflict! Manual resolution required.
}

ObjectOS Approach:

# plugin.manifest.yml
name: @mycompany/billing
version: 2.0.0
dependencies:
  '@objectstack/core': '^2.0.0'
  'com.stripe.plugin': '>=10.0.0 <11.0.0'

ObjectOS validates the entire dependency graph at install time. Incompatible plugins fail installation with clear error messages, not runtime crashes.

Business Value: A marketplace with 200+ plugins has zero "it works on my machine" issues. Dependency conflicts are caught before customers hit "Install."

Problem: Configuration Management Chaos

Traditional Approach:

// Where is the source of truth?
const apiKey = 
  process.env.API_KEY ||              // Environment variable
  config.get('stripe.apiKey') ||      // Config file
  tenant.settings.apiKey ||           // Database
  'fallback-key';                     // πŸ’€ Hardcoded default

ObjectOS Approach:

// Declarative merge strategy
const config = context.config.resolve('stripe.apiKey', {
  sources: ['environment', 'tenant', 'plugin', 'default'],
  required: true
});
// ObjectOS merges in precedence order, validates, throws clear error if missing

Business Value: Configuration errors dropped 90% after adopting ObjectOS. New engineers can understand config logic in 5 minutes instead of 5 hours.

Real-World Use Cases

Multi-Tenant SaaS Platform

Challenge: A B2B SaaS company serves 500 enterprise customers. Each customer needs custom:

  • Branding (logo, colors)
  • Feature flags (Customer A has AI, Customer B doesn't)
  • Integrations (Customer A uses Salesforce, Customer B uses HubSpot)
  • Language (Customer A is US English, Customer B is German)

ObjectOS Solution:

  • Tenant Isolation: Each customer is a "tenant" with scoped configuration
  • Config Merging: Global defaults β†’ Tenant overrides β†’ User preferences
  • Plugin System: Each integration is a plugin; tenants enable only what they need
  • i18n Engine: Language bundles loaded per user session

Results:

  • Onboard new enterprise customer in 1 hour (previously 2 weeks)
  • Zero cross-tenant data leaks (config isolation enforced by runtime)
  • 40% reduction in support tickets (consistent config management)

Marketplace Ecosystem

Challenge: Build a plugin marketplace like Salesforce AppExchange where third-party developers sell integrations.

ObjectOS Solution:

  • Plugin Manifest: Standardized plugin.manifest.yml declares what plugin provides and needs
  • Dependency Resolution: Automatic validation that plugin versions are compatible with core platform
  • Lifecycle Hooks: onInstall, onEnable, onDisable hooks for setup/teardown
  • Sandboxing: Plugins can't access each other's data or crash each other

Results:

  • Launched marketplace with 50 third-party plugins in 6 months
  • Zero "this plugin broke my system" incidents (validation prevents bad installs)
  • 30% revenue growth from plugin marketplace sales

Global Enterprise Rollout

Challenge: A company expands from US to 12 countries (Europe, APAC, LATAM). Same app must support:

  • 15 languages
  • Different date/number formats (MM/DD/YYYY vs DD/MM/YYYY)
  • Regional compliance (GDPR in EU, LGPD in Brazil)
  • Local integrations (EU uses SEPA payments, US uses ACH)

ObjectOS Solution:

  • i18n Standard: Translation bundles with fallback chains (de-AT β†’ de β†’ en)
  • Region Config: Configuration profiles per region (defaults + region overrides)
  • Plugin System: Regional plugins (SEPA plugin for EU, ACH plugin for US)
  • Locale Resolution: Automatic detection from user preferences, IP geolocation, or explicit selection

Results:

  • Launched in 12 countries in 4 months (previously 18-month estimate)
  • Zero code changes for new languages (just upload translation files)
  • 95% translation coverage on day one (tooling validates translation completeness)

How ObjectOS Orchestrates ObjectQL and ObjectUI

ObjectOS is the runtime coordinator that makes ObjectQL and ObjectUI work together:

1. Boot Sequence

// Startup flow
ObjectOS.boot({
  // Step 1: Load configuration
  config: await ConfigResolver.merge(['environment', 'file', 'default']),
  
  // Step 2: Initialize plugins
  plugins: await PluginRegistry.loadAll({
    enabled: ['@objectstack/core', '@mycompany/crm'],
    // ObjectOS resolves dependencies and loads in correct order
  }),
  
  // Step 3: Register ObjectQL objects
  objects: await ObjectQL.loadSchemas(plugins.flatMap(p => p.objects)),
  
  // Step 4: Register ObjectUI views
  views: await ObjectUI.loadLayouts(plugins.flatMap(p => p.views)),
  
  // Step 5: Start services
  services: {
    eventBus: EventBus.start(),
    scheduler: JobScheduler.start(),
    audit: AuditLogger.start(),
  }
});

2. Request Handling

// Incoming API request: GET /api/accounts/123
async function handleRequest(req) {
  // ObjectOS provides context
  const context = await ObjectOS.createContext({
    tenantId: req.headers['x-tenant-id'],
    userId: req.user.id,
    locale: req.headers['accept-language'],
  });
  
  // ObjectOS resolves configuration
  const config = context.config.resolve();
  
  // ObjectQL executes query
  const account = await ObjectQL.findById('account', '123', {
    context,  // ObjectOS injects permissions, audit, etc.
  });
  
  // ObjectUI renders response
  const view = await ObjectUI.render('account_detail', {
    record: account,
    locale: context.locale,  // ObjectOS provides i18n
  });
  
  // ObjectOS logs audit trail
  context.audit.log('account.view', { accountId: '123' });
  
  return view;
}

3. Plugin Installation

// Install a plugin: objectstack plugin install @vendor/salesforce-sync
await ObjectOS.installPlugin({
  source: '@vendor/salesforce-sync@1.5.0',
  
  // Step 1: Validate dependencies
  validate: (manifest) => {
    PluginRegistry.checkDependencies(manifest.dependencies);
    // Ensures '@objectstack/core@^2.0.0' is installed
  },
  
  // Step 2: Run onInstall hook
  onInstall: async (plugin) => {
    // Plugin may create custom objects (ObjectQL)
    await ObjectQL.createObjects(plugin.objects);
    
    // Plugin may register UI views (ObjectUI)
    await ObjectUI.registerViews(plugin.views);
    
    // Plugin may set default config
    await ConfigStore.set(plugin.defaultConfig);
  },
  
  // Step 3: Enable plugin
  enable: () => {
    PluginRegistry.enable('@vendor/salesforce-sync');
  }
});

Philosophy: Infrastructure as Code

ObjectOS embodies "Infrastructure as Code" principles:

Declarative, Not Imperative

Bad (Imperative):

// Manual steps
db.createTable('accounts');
db.addColumn('accounts', 'name', 'string');
permissions.grant('admin', 'accounts', 'read');
// Miss a step? System broken.

Good (Declarative):

# plugin.manifest.yml
objects:
  - name: account
    fields:
      - name: name
        type: text
permissions:
  - role: admin
    object: account
    access: read
# ObjectOS ensures runtime matches manifest

Idempotent Operations

Run objectstack deploy 100 times β†’ Same result.

  • Installing a plugin twice does nothing (it's already installed)
  • Applying same configuration twice doesn't duplicate settings
  • Schema migrations are versioned (run once, skip if already applied)

Version Control Everything

All system configuration lives in Git:

  • Plugin manifests: plugin.manifest.yml
  • Configuration files: objectstack.config.yml
  • Translation bundles: i18n/en.json, i18n/de.json

Business Value: Rollback a bad deployment by reverting Git commit. No database state to recover, no manual cleanup.

Developer Experience

Plugin Development

# Scaffold new plugin
objectstack plugin create @mycompany/slack-integration

# Generated structure:
slack-integration/
  plugin.manifest.yml    # Metadata, dependencies, version
  src/
    objects/             # ObjectQL schemas
    views/               # ObjectUI layouts
    actions/             # Business logic
    i18n/                # Translations
  tests/
  README.md

Configuration Management

// Define plugin configuration schema
export const configSchema = z.object({
  apiKey: z.string().describe('Slack API Key'),
  channel: z.string().default('#general'),
  enabled: z.boolean().default(true),
});

// Access in plugin code
const config = context.config.get('slack', configSchema);
// ObjectOS validates against schema, throws clear error if invalid

Internationalization

// Define translations
// i18n/en.json
{
  "slack.button.send": "Send to Slack",
  "slack.error.invalid_channel": "Channel {{channel}} not found"
}

// i18n/de.json
{
  "slack.button.send": "An Slack senden",
  "slack.error.invalid_channel": "Kanal {{channel}} nicht gefunden"
}

// Use in code
const message = context.i18n.t('slack.button.send');
// ObjectOS automatically uses user's locale

Best Practices

1. Embrace the Microkernel Philosophy

Principle: Core runtime does almost nothing. All features are plugins.

Why: Keeps core stable. Plugins evolve independently. Customers pay for only what they use.

Example: Don't build email sending into ObjectOS core. Create @objectstack/email plugin. Customers who don't send emails don't load the plugin (smaller memory footprint, faster boot).

2. Configuration Over Code

Principle: Behavior should be configurable without code changes.

Why: Reduces deployment frequency. Business users can toggle features without engineering.

Example: Instead of hardcoding maxRetries: 3 in plugin code, define maxRetries in config schema. Customers can override to 5 without touching code.

3. Design for Multi-Tenancy from Day One

Principle: Every piece of state (config, data, UI) should be tenant-scoped.

Why: Easier to add multi-tenancy later = rebuild entire system.

Example: Don't store config in global variables. Use context.config.get() which automatically scopes to current tenant.

4. Version Everything

Principle: All artifacts (plugins, schemas, configs) have semantic versions.

Why: Enables safe upgrades, rollbacks, and dependency management.

Example: Plugin manifest declares version: 2.1.0. Breaking change? Bump to 3.0.0. Consumers can pin to ^2.0.0 until they're ready to upgrade.

5. Fail Fast, Fail Loud

Principle: Invalid configuration should fail at boot time, not runtime.

Why: Catch errors before customers see them.

Example: Plugin requires apiKey config. If missing, ObjectOS throws error during boot with clear message: "Plugin @vendor/slack requires config key 'slack.apiKey' (not found in environment, tenant, or default config)".

Comparison: ObjectOS vs Alternatives

FeatureObjectOSKubernetesCloudFoundryHeroku
Plugin SystemBuilt-in manifest-basedHelm charts (external)BuildpacksAdd-ons marketplace
Config ManagementHierarchical mergeConfigMaps/SecretsEnvironment varsConfig vars
Multi-TenancyNative tenant isolationNamespace per tenantNot supportedOne app = one tenant
i18nBuilt-in engineManual (libraries)ManualManual
Dependency ResolutionSemantic versioningManual (YAML)ManualManual
Zero-Downtime UpgradesDeclarativeRolling updatesBlue-greenGit push
Developer UXobjectstack deploykubectl applycf pushgit push heroku

Key Differentiator: ObjectOS is application-aware. Kubernetes knows about containers, not plugins. ObjectOS knows about ObjectQL objects, ObjectUI views, and business logic dependencies.

Next Steps

Summary

ObjectOS is the control plane that orchestrates ObjectStack:

  • Lifecycle Management: Declarative deployment, zero-downtime upgrades, rollback safety
  • Plugin System: Microkernel architecture with dependency resolution and sandboxing
  • Configuration: Unified config with merge strategies and tenant isolation
  • i18n: Multi-language support built into the platform

Think of it this way:

  • ObjectQL is the database driver (handles data CRUD)
  • ObjectUI is the rendering engine (handles presentation)
  • ObjectOS is the operating system (handles coordination, configuration, lifecycle)

Without ObjectOS, you'd manually wire ObjectQL and ObjectUI together, manage deployments with runbooks, and fight configuration drift. With ObjectOS, the platform handles the "plumbing" so you focus on business logic.

On this page