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
Lifecycle Management
Boot sequence, plugin installation, zero-downtime upgrades, rollback strategies
Plugin Specification
Manifest structure, dependency graph, versioning semantics, distribution format
Configuration Resolution
Merge strategies, precedence rules, environment overrides, tenant isolation
i18n Standard
Translation bundles, locale resolution, date/number formatting, dynamic loading
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 godsObjectOS 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 defaultObjectOS 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 missingBusiness 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.ymldeclares what plugin provides and needs - Dependency Resolution: Automatic validation that plugin versions are compatible with core platform
- Lifecycle Hooks:
onInstall,onEnable,onDisablehooks 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 manifestIdempotent 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.mdConfiguration 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 invalidInternationalization
// 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 localeBest 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
| Feature | ObjectOS | Kubernetes | CloudFoundry | Heroku |
|---|---|---|---|---|
| Plugin System | Built-in manifest-based | Helm charts (external) | Buildpacks | Add-ons marketplace |
| Config Management | Hierarchical merge | ConfigMaps/Secrets | Environment vars | Config vars |
| Multi-Tenancy | Native tenant isolation | Namespace per tenant | Not supported | One app = one tenant |
| i18n | Built-in engine | Manual (libraries) | Manual | Manual |
| Dependency Resolution | Semantic versioning | Manual (YAML) | Manual | Manual |
| Zero-Downtime Upgrades | Declarative | Rolling updates | Blue-green | Git push |
| Developer UX | objectstack deploy | kubectl apply | cf push | git 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
Learn Lifecycle Management
Understand boot sequence, installation, upgrade strategies, and rollback procedures
Build Your First Plugin
Create a plugin manifest, define dependencies, and implement lifecycle hooks
Master Configuration
Learn merge strategies, environment overrides, and tenant-specific settings
Internationalize Your App
Add multi-language support with translation bundles and locale resolution
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.