Same business logic, same workflow — a different UI framework every time.
Choose your favorite framework. The business logic stays unchanged — because it never left the plugin.
View all examples →For the era of LLM-speed code
Polaris Runtime turns your business logic into a self-describing, portable contract — something you can verify, not just hope works.
npm install @polaris-runtime/core
The problem
Working, but a stranger to its author
Six months from now, code written today — by you or an LLM — looks unfamiliar. It runs, but nobody remembers why it was written that way.
Business rules buried in the UI
Approval flows and status checks scattered across components turn every UI rewrite into a business-logic rewrite too.
Re-explaining your domain, every session
A new LLM session means re-teaching it what "meeting" or "approval" means in your business — every single time.
How it works
The runtime never knows what a "Meeting" or "Invoice" is. It only understands four concepts — every business domain lives inside a Plugin built from them.
Learn by example
Four self-contained apps, each adding exactly one new concept — from registering your first plugin to watching an LLM build a UI on top of a business model it never saw the code of.
Basic Note App
Single-plugin registration, capability & workflow orchestration, domain-targeted state management, unified event subscriptions for UI feedback.
React + TypeScript + Polaris Runtime
Note Guard App
OOP domain model encapsulation, declarative allowed guards, exception-driven execution, and ultra-thin UI guards via can().
React + TypeScript + Polaris Runtime
Meeting Notes App
Full-featured meeting management with a state machine, role-based permissions, and real-time event subscription.
React + TypeScript + Polaris Runtime + localStorage
Meeting Notes App — LLM-built UI
Experimental UI generated by an LLM from example 03's business model (Plugin) — the AI-native claim, tested.
React + TypeScript + Polaris Runtime + localStorage
Proof, not a promise
The tutorial above teaches the concepts one at a time. This is the same idea pushed to its limit: the same three plugins — repo, meeting, and workspace — power six independently built front-ends in a separate repository. None of them contain a single business rule. All of them stay correct automatically, because the rules never left the plugin.
Case study
While building the six reference implementations above, a runtime bug that only surfaced in SvelteKit's dual SSR/client module graph was caught and fixed — from an internal auto Explorer feature. Every other framework, all plain Vite SPAs, never triggered it.
That's the point: cross-framework proof isn't a marketing exercise — it's a stress test the core runtime has to survive.
Self-describing
Every Plugin, Workflow, Step, and Capability carries its own metadata — title, description, input/output schema. Explorerreads it directly and turns it into living documentation. The proof: each UI in the gallery was built from five sources — README.md, ARCHITECTURE.md, API.md, one catalog.json snapshot, and the meeting plugin's type definition — never the plugin's implementation.
1. Register plugins, declare who owns context
import { PolarisRuntime } from '@polaris-runtime/core';
import { RepoPlugin } from './plugins/repo.plugin';
import { MeetingPlugin } from './plugins/meeting.plugin';
import { WorkspacePlugin } from './plugins/workspace.plugin';
const runtime = new PolarisRuntime({ dev:true });
// set manually for dev mode or import from @polaris-runtime/core/dev
runtime.register([RepoPlugin, MeetingPlugin, WorkspacePlugin]);
runtime.setAllowedContextWorkflow('workspace/wf-set-context');2. Explorer generates itself — nothing to configure
$ npm run dev [Polaris] 3 plugins registered (repo, meeting, workspace) [Polaris] Explorer generated → ./explorer [Polaris] catalog.json available → ./explorer/catalog.json
Try any tutorial demo — all of them use @polaris-runtime/core/dev, so the Explorer automatically opens in a new tab. If it's blocked by your browser, simply allow pop-ups for this site or if you prefer not to set it permanently "Open BLOB Explorer Manually" inside.
You can also open the browser's Developer Tools (F12) and watch the VERBOSE log — every workflow event, capability execution, and guard evaluation is streamed live as it happens.

3. That catalog is what an LLM (or a new teammate) actually reads
{
"runtime": {
"name": "Polaris Runtime",
"version": "2.0.2",
"allowedContextWorkflow": "workspace/wf-set-context"
},
"statistics": {
"totalPlugins": 3,
"totalWorkflows": 14,
"totalCapabilities": 19
},
"plugins": [
{
"name": "repo",
"version": "1.0.0",
"description": "Repository - localStorage for meeting app",
"capabilities": [
{
"name": "repo/cap-save",
"description": "Save data to repository",
"inputSchema": {
"input": "{ domain, data } // domain exp. meeting just like table name, data include id, exp. { id: 1, name: 'test' }"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }"
}
},
{
"name": "repo/cap-get",
"description": "Get data from repository",
"inputSchema": {
"input": "{ domain, id } // domain exp. meeting just like table name, id is the unique identifier of the record"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }"
}
},
{
"name": "repo/cap-list",
"description": "List all data from repository",
"inputSchema": {
"input": "{ domain } // domain exp. meeting just like table name"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }"
}
},
{
"name": "repo/cap-update",
"description": "Update data in repository",
"inputSchema": {
"input": "{ domain, id, data } // domain exp. meeting just like table name, id is the unique identifier of the record, data contains the fields to update"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }"
}
},
{
"name": "repo/cap-delete",
"description": "Delete data from repository",
"inputSchema": {
"input": "{ domain, id } // domain exp. meeting just like table name, id is the unique identifier of the record"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }"
}
}
],
"workflows": [],
"dependencies": []
},
{
"name": "meeting",
"version": "1.0.0",
"description": "Meeting management with domain model",
"capabilities": [
{
"name": "meeting/cap-prepare-repo",
"description": "Prepare domain and data for repo operations"
},
{
"name": "meeting/cap-get-validation",
"description": "Validate get meeting input"
},
{
"name": "meeting/cap-create",
"description": "Create new meeting from input"
},
{
"name": "meeting/cap-validate-submit",
"description": "Submit approval – auto detect note"
},
{
"name": "meeting/cap-validate-approve",
"description": "Approve schedule"
},
{
"name": "meeting/cap-validate-reject-approval",
"description": "Reject schedule"
},
{
"name": "meeting/cap-validate-add-note",
"description": "Add note"
},
{
"name": "meeting/cap-validate-revise-note",
"description": "Revise note"
},
{
"name": "meeting/cap-validate-approve-note",
"description": "Approve note"
},
{
"name": "meeting/cap-validate-reject-note",
"description": "Reject note"
},
{
"name": "meeting/cap-validate-edit-draft",
"description": "Edit draft"
},
{
"name": "meeting/cap-validate-delete-draft",
"description": "Delete draft"
},
{
"name": "meeting/cap-validate-cancel",
"description": "Cancel meeting"
}
],
"workflows": [
{
"name": "meeting/wf-list",
"description": "List all meetings",
"allowed": [
{
"key": "role",
"value": [
"member",
"secretary",
"leader"
],
"source": "context",
"operator": "in"
}
],
"allowedType": "array",
"steps": [
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo"
},
{
"name": "fetch-repo",
"useCapability": "repo/cap-list"
}
],
"inputSchema": {
"input": "null // no input required but use unique identifier avoid idempotent guard like { _t: Date.now() }"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meetings: Meeting[] } // data is array of records"
}
},
{
"name": "meeting/wf-create",
"description": "Create new meeting",
"allowed": [
{
"key": "role",
"value": [
"member",
"secretary",
"leader"
],
"source": "context",
"operator": "in"
}
],
"allowedType": "array",
"steps": [
{
"name": "create",
"useCapability": "meeting/cap-create"
},
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo"
},
{
"name": "save-repo",
"useCapability": "repo/cap-save"
}
],
"inputSchema": {
"input": "{ meetingData: omit } //use type definition and form to comply"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meeting: Meeting } // data is a single meeting record"
}
},
{
"name": "meeting/wf-get",
"description": "Get meeting by ID",
"allowed": [
{
"key": "role",
"value": [
"member",
"secretary",
"leader"
],
"source": "context",
"operator": "in"
}
],
"allowedType": "array",
"steps": [
{
"name": "validate-get",
"useCapability": "meeting/cap-get-validation"
},
{
"name": "get-repo",
"useCapability": "repo/cap-get",
"dependsOn": [
"validate-get"
]
}
],
"inputSchema": {
"input": "{ id: string } // meeting ID"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meeting: Meeting } // data is a single meeting record"
}
},
{
"name": "meeting/wf-submit-approval",
"description": "Submit meeting for approval",
"allowed": [
{
"key": "status",
"value": "draft",
"source": "input",
"operator": "eq"
},
{
"key": "userId",
"value": {
"key": "createdBy",
"source": "input"
},
"source": "context",
"operator": "eq"
}
],
"allowedType": "array",
"steps": [
{
"name": "validate-get",
"useCapability": "meeting/cap-get-validation"
},
{
"name": "get-meeting",
"useCapability": "repo/cap-get",
"dependsOn": [
"validate-get"
]
},
{
"name": "validate-submit",
"useCapability": "meeting/cap-validate-submit",
"dependsOn": [
"get-meeting"
]
},
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo",
"dependsOn": [
"validate-submit"
]
},
{
"name": "update-repo",
"useCapability": "repo/cap-update",
"dependsOn": [
"prepare-repo"
]
}
],
"inputSchema": {
"input": "{ id: string } // meeting ID"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meeting: Meeting } // data is a single meeting record"
}
},
{
"name": "meeting/wf-approve",
"description": "Approve schedule by leader/secretary but not creator of meeting",
"allowed": {
"expr": "status === 'waiting_approval' && ['leader', 'secretary'].includes(role) && createdBy !== userId",
"input": [
"status",
"createdBy"
],
"context": [
"role",
"userId"
]
},
"allowedType": "expression",
"steps": [
{
"name": "validate-get",
"useCapability": "meeting/cap-get-validation"
},
{
"name": "get-meeting",
"useCapability": "repo/cap-get",
"dependsOn": [
"validate-get"
]
},
{
"name": "validate-approve",
"useCapability": "meeting/cap-validate-approve",
"dependsOn": [
"get-meeting"
]
},
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo",
"dependsOn": [
"validate-approve"
]
},
{
"name": "update-repo",
"useCapability": "repo/cap-update",
"dependsOn": [
"prepare-repo"
]
}
],
"inputSchema": {
"input": "{ id: string } // meeting ID"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meeting: Meeting } // data is a single meeting record"
}
},
{
"name": "meeting/wf-reject-approval",
"description": "Reject schedule by leader/secretary but not creator of meeting",
"allowed": {
"expr": "status === 'waiting_approval' && ['leader', 'secretary'].includes(role) && createdBy !== userId",
"input": [
"status",
"createdBy"
],
"context": [
"role",
"userId"
]
},
"allowedType": "expression",
"steps": [
{
"name": "validate-get",
"useCapability": "meeting/cap-get-validation"
},
{
"name": "get-meeting",
"useCapability": "repo/cap-get",
"dependsOn": [
"validate-get"
]
},
{
"name": "validate-reject-approval",
"useCapability": "meeting/cap-validate-reject-approval",
"dependsOn": [
"get-meeting"
]
},
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo",
"dependsOn": [
"validate-reject-approval"
]
},
{
"name": "update-repo",
"useCapability": "repo/cap-update",
"dependsOn": [
"prepare-repo"
]
}
],
"inputSchema": {
"input": "{ id: string, reason: string } // meeting ID and reason for rejection"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meeting: Meeting } // data is a single meeting record"
}
},
{
"name": "meeting/wf-add-note",
"description": "Add note only creator or leader/secretary",
"allowed": {
"expr": "status === 'scheduled' && (['leader', 'secretary'].includes(role) || createdBy === userId)",
"input": [
"status",
"createdBy"
],
"context": [
"role",
"userId"
]
},
"allowedType": "expression",
"steps": [
{
"name": "validate-get",
"useCapability": "meeting/cap-get-validation"
},
{
"name": "get-meeting",
"useCapability": "repo/cap-get",
"dependsOn": [
"validate-get"
]
},
{
"name": "validate-add-note",
"useCapability": "meeting/cap-validate-add-note",
"dependsOn": [
"get-meeting"
]
},
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo",
"dependsOn": [
"validate-add-note"
]
},
{
"name": "update-repo",
"useCapability": "repo/cap-update",
"dependsOn": [
"prepare-repo"
]
}
],
"inputSchema": {
"input": "{ id: string, note: string } // meeting ID and note content"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meeting: Meeting } // data is a single meeting record"
}
},
{
"name": "meeting/wf-revise-note",
"description": "Revise note",
"allowed": {
"expr": "['waiting_note_approval', 'done'].includes(status) && ( createdBy === userId || ['leader','secretary'].includes(role) )",
"input": [
"status",
"createdBy"
],
"context": [
"userId",
"role"
]
},
"allowedType": "expression",
"steps": [
{
"name": "validate-get",
"useCapability": "meeting/cap-get-validation"
},
{
"name": "get-meeting",
"useCapability": "repo/cap-get",
"dependsOn": [
"validate-get"
]
},
{
"name": "validate-revise-note",
"useCapability": "meeting/cap-validate-revise-note",
"dependsOn": [
"get-meeting"
]
},
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo",
"dependsOn": [
"validate-revise-note"
]
},
{
"name": "update-repo",
"useCapability": "repo/cap-update",
"dependsOn": [
"prepare-repo"
]
}
],
"inputSchema": {
"input": "{ id: string, note: string } // meeting ID and new note content"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meeting: Meeting } // data is a single meeting record"
}
},
{
"name": "meeting/wf-approve-note",
"description": "Approve note",
"allowed": {
"expr": "status === 'waiting_note_approval' && ['leader', 'secretary'].includes(role) && createdBy !== userId",
"input": [
"status",
"createdBy"
],
"context": [
"role",
"userId"
]
},
"allowedType": "expression",
"steps": [
{
"name": "validate-get",
"useCapability": "meeting/cap-get-validation"
},
{
"name": "get-meeting",
"useCapability": "repo/cap-get",
"dependsOn": [
"validate-get"
]
},
{
"name": "validate-approve-note",
"useCapability": "meeting/cap-validate-approve-note",
"dependsOn": [
"get-meeting"
]
},
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo",
"dependsOn": [
"validate-approve-note"
]
},
{
"name": "update-repo",
"useCapability": "repo/cap-update",
"dependsOn": [
"prepare-repo"
]
}
],
"inputSchema": {
"input": "{ id: string } // meeting ID",
"canExecute": "{status, createdBy} // special case createdBy from note activeNote, not from meeting data, approver not creator the note"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meeting: Meeting } // data is a single meeting record"
}
},
{
"name": "meeting/wf-reject-note",
"description": "Reject note",
"allowed": {
"expr": "status === 'waiting_note_approval' && ['leader', 'secretary'].includes(role) && createdBy !== userId",
"input": [
"status",
"createdBy"
],
"context": [
"role",
"userId"
]
},
"allowedType": "expression",
"steps": [
{
"name": "validate-get",
"useCapability": "meeting/cap-get-validation"
},
{
"name": "get-meeting",
"useCapability": "repo/cap-get",
"dependsOn": [
"validate-get"
]
},
{
"name": "validate-reject-note",
"useCapability": "meeting/cap-validate-reject-note",
"dependsOn": [
"get-meeting"
]
},
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo",
"dependsOn": [
"validate-reject-note"
]
},
{
"name": "update-repo",
"useCapability": "repo/cap-update",
"dependsOn": [
"prepare-repo"
]
}
],
"inputSchema": {
"input": "{ id: string, reason: string } // meeting ID and reason for rejection",
"canExecute": "{status, createdBy} // special case createdBy from note activeNote, not from meeting data, approver not creator the note"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meeting: Meeting } // data is a single meeting record"
}
},
{
"name": "meeting/wf-edit-draft",
"description": "Edit draft",
"allowed": [
{
"key": "status",
"value": "draft",
"source": "input",
"operator": "eq"
},
{
"key": "createdBy",
"value": {
"key": "userId",
"source": "context"
},
"source": "input",
"operator": "eq"
}
],
"allowedType": "array",
"steps": [
{
"name": "validate-get",
"useCapability": "meeting/cap-get-validation"
},
{
"name": "get-meeting",
"useCapability": "repo/cap-get",
"dependsOn": [
"validate-get"
]
},
{
"name": "validate-edit-draft",
"useCapability": "meeting/cap-validate-edit-draft",
"dependsOn": [
"get-meeting"
]
},
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo",
"dependsOn": [
"validate-edit-draft"
]
},
{
"name": "update-repo",
"useCapability": "repo/cap-update",
"dependsOn": [
"prepare-repo"
]
}
],
"inputSchema": {
"input": "{ meeting: Meeting } // meeting data to update"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meeting: Meeting } // data is a single meeting record"
}
},
{
"name": "meeting/wf-delete-draft",
"description": "Delete draft",
"allowed": [
{
"key": "status",
"value": "draft",
"source": "input",
"operator": "eq"
},
{
"key": "createdBy",
"value": {
"key": "userId",
"source": "context"
},
"source": "input",
"operator": "eq"
}
],
"allowedType": "array",
"steps": [
{
"name": "validate-get",
"useCapability": "meeting/cap-get-validation"
},
{
"name": "get-meeting",
"useCapability": "repo/cap-get",
"dependsOn": [
"validate-get"
]
},
{
"name": "validate-delete-draft",
"useCapability": "meeting/cap-validate-delete-draft",
"dependsOn": [
"get-meeting"
]
},
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo",
"dependsOn": [
"validate-delete-draft"
]
},
{
"name": "delete-repo",
"useCapability": "repo/cap-delete",
"dependsOn": [
"prepare-repo"
]
}
],
"inputSchema": {
"input": "{ id: string } // meeting ID"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ null } // no data returned if deletion is successful"
}
},
{
"name": "meeting/wf-cancel",
"description": "Cancel meeting",
"allowed": {
"expr": "['waiting_approval', 'scheduled', 'waiting_note_approval'].includes(status) && ['leader', 'secretary'].includes(role) && createdBy !== userId",
"input": [
"status",
"createdBy"
],
"context": [
"role",
"userId"
]
},
"allowedType": "expression",
"steps": [
{
"name": "validate-get",
"useCapability": "meeting/cap-get-validation"
},
{
"name": "get-meeting",
"useCapability": "repo/cap-get",
"dependsOn": [
"validate-get"
]
},
{
"name": "validate-cancel",
"useCapability": "meeting/cap-validate-cancel",
"dependsOn": [
"get-meeting"
]
},
{
"name": "prepare-repo",
"useCapability": "meeting/cap-prepare-repo",
"dependsOn": [
"validate-cancel"
]
},
{
"name": "update-repo",
"useCapability": "repo/cap-update",
"dependsOn": [
"prepare-repo"
]
}
],
"inputSchema": {
"input": "{ id: string, reason: string } // meeting ID and reason for cancellation"
},
"outputSchema": {
"output": "{ status, domain, id, payload, message, error }",
"payload": "{ meeting: Meeting } // data is a single meeting record"
}
}
],
"dependencies": [
"repo"
]
},
{
"name": "workspace",
"version": "1.0.0",
"description": "Workspace management for meeting app",
"capabilities": [
{
"name": "workspace/cap-set-context",
"description": "Set global context (user, role, workspace)"
}
],
"workflows": [
{
"name": "workspace/wf-set-context",
"description": "🔒 ALLOWED: Set global context",
"allowed": [],
"allowedType": "array",
"steps": [
{
"name": "SetContext",
"useCapability": "workspace/cap-set-context"
}
],
"inputSchema": {
"input": "{ data } // example: { user: 'john', role: 'admin', workspace: 'main' }"
},
"outputSchema": {
"output": "{ status, data, message } // data from input store in global context"
}
}
],
"dependencies": []
}
]
}Illustrative excerpt, shaped from real workflow names in this project's meeting plugin — not a byte-for-byte copy of a generated file.
Mark
The face below it is drawn entirely from code syntax —[, |,:, ) — nothing decorative added on top. The mark is made of the same material the runtime is: grammar, not illustration.
When humans and AI share a grammar, intelligence becomes a multiplier.

Get started
npm install @polaris-runtime/core
import { PolarisRuntime } from '@polaris-runtime/core';
const runtime = new PolarisRuntime();
runtime.register([MeetingPlugin]);
const result = await runtime.execute('meeting/wf-list', {});Coming soon
This is built by one person, and the client-side proof above is solid — six frameworks, one plugin, zero duplicated logic. The server side is still a hypothesis: the same plugin grammar, running behind an HTTP framework instead of a UI framework, with per-request context isolation instead of one shared browser session. Nobody has stress-tested it yet.
Solid = proven today. Dashed = the open question — same repo plugin, swapped from localStorage to a real database, no shared global state across requests. Next plan, we consider to tested in Next.js, Fastify.js and Pure Node.js for rest API with validation business logic same plugin use in front end client UI.