--- title: "Vega to Centauri BYO Migration Guide" slug: "vega-to-centauri-byo-migration-guide" updated: 2026-10-07T20:50:34Z published: 2026-10-07T20:50:34Z canonical: "docs.unqork.io/vega-to-centauri-byo-migration-guide" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.unqork.io/llms.txt > Use this file to discover all available pages before exploring further. # Vega to Centauri BYO Migration Guide > [!WARNING] > Vega was retired on May 15, 2026. Centauri BYO is the supported architecture going forward. If you have existing Vega BYO components, the Migration Guide walks through updating them to Centauri BYO. > [!NOTE] > If you are re-uploading an existing Vega BYO package after upgrading to platform version 9.0 or later, add the following field to your `manifest.json` before uploading. Packages installed before 9.0 were updated automatically and do not require this change. > > > ```json > "runtimeVersion": "2.0.0" > ``` Centauri BYO introduces a simplified integration model based on **properties + callbacks** instead of the Vega operations API. This guide covers the key differences and migration steps. ## Key Differences ### Integration Model #### Vega Components received an API object with state and event methods: ```javascript // Vega pattern - components received an api object class VegaComponent {  constructor(api) {    this.api = api  }    // Access state  getValue() {    const currentState = this.api.state.currentState()    return currentState.label  }    // Update state  updateValue(value) {    this.api.state.set({ label: value })  }    // Emit events  handleClick() {    this.api.events.emit('buttonClicked', { label: this.api.state.currentState().label })  } } ``` #### Centauri Components receive data through properties and dispatch events through callbacks: ```typescript // Centauri pattern - standard Web Components class CentauriComponent extends HTMLElement {  private _label: string = ''    // Platform sets properties automatically  set label(value: string) {    this._label = value    this.render()  }    // Call callbacks to communicate back  handleClick() {    this.onButtonClicked?.({ label: this._label })  } } ``` ### State Management #### Vega Components manually accessed and updated state using the API: ```javascript // Read state const state = this.api.state.currentState() const label = state.label // Update state this.api.state.set({ label: 'New Label' }) // Subscribe to state changes this.api.state.state$.subscribe((state) => {  this.render(state) }) ``` #### Centauri The platform automatically sets properties when state changes. Your component reacts to setters: ```typescript // Platform calls setters automatically set label(value: string) {  this._label = value  this.render() } // No manual subscription needed ``` ### Event Dispatch #### Vega Events were dispatched through the API's emit method: ```javascript this.api.events.emit('itemSelected', { id: 123 }) ``` #### Centauri Events are callbacks wired through **triggers** configured in the Module Builder: ```typescript // Component code this.onItemSelected?.({ id: 123 }) ``` ```json // Module Builder configuration {  "triggers": {    "onItemSelected": {      "contextId": "selectedItem",      "targetId": "logicComponent"    }  } } ``` The platform handles routing. Your component doesn't need to specify targets. ### Configuration #### Vega Components accessed configuration through the API's state methods. #### Centauri Configuration is declarative through: 1. **Model schema**: Defines the available properties. 2. **Module Builder**: Creators configure property values and triggers. 3. **Properties**: The platform sets values on your component. ## Centauri BYOC_UPDATE Output Type Centauri introduces a special output type `BYOC_UPDATE` for updating BYO component properties from operations. This requires the `.property()` syntax to target specific properties. #### Syntax ``` componentId.property(propertyPath) ``` #### Examples ```javascript // Update a simple property myButton.property(label)           // Updates myButton's label property // Update nested properties myTaskList.property(items[0].completed)  // Updates first item's completed status myChart.property(options.title)          // Updates nested configuration ``` #### Usage in Operations When configuring outputs in the Module Builder: 1. Set output type to `BYOC_UPDATE` 2. Set target to: `componentId.property(propertyPath)` 3. The platform will update that specific property on the BYO component. This lets operations update specific BYO component properties without replacing the entire state. ## Migration Steps ### 1. Update Component Contract #### Vega ```javascript // Vega components received an api object class VegaButton {  constructor(api) {    this.api = api  }    handleClick() {    const state = this.api.state.currentState()    const label = state.label    this.api.events.emit('buttonClicked', { label })  } } ``` #### Centauri ```typescript // Centauri components are standard Web Components class CentauriButton extends HTMLElement {  private _label: string = ''    // Platform sets properties via setters  set label(value: string) {    this._label = value    this.render()  }    // Component calls callbacks to communicate back  handleClick() {    this.onButtonClicked?.({ label: this._label })  } } ``` ### 2. Replace Vega API Calls | Vega API | Centauri Equivalent | | --- | --- | | `api.state.currentState()` | Access through local state from setters | | `api.state.set({ prop: value })` | Use triggers + operations with `BYOC_UPDATE` output type | | `api.state.state$.subscribe()` | Not needed — setters are called automatically when state changes | | `api.state.resolveByKey(key)` | Use triggers + operations with `BYOC_UPDATE` output type and `.property()` syntax | | `api.state.updateExternalComponentState()` | Use triggers + operations with `BYOC_UPDATE` output type | | `api.events.emit(name, payload)` | `this.onEventName?.(payload)` | ### 3. Define Model Schema Create a component definition using `defineComponent` from `@unqork/byo-sdk/schema`. This wraps your Zod schema and generates a `ModelClass` constructor that the platform requires: ```typescript import { z } from 'zod' import { defineComponent } from '@unqork/byo-sdk/schema' export const myButtonDefinition = defineComponent({  name: 'My Button',  type: 'my-button',  description: 'A custom button component',  schema: z.object({    label: z.string().default('Click me'),    disabled: z.boolean().default(false),    variant: z.enum(['primary', 'secondary']).default('primary'),  }), }) export type MyButtonModel = z.infer ``` In `entry.ts`, reference `myButtonDefinition.ModelClass` as the `model` export: ```typescript export const myButton = {  view: async () => MyButtonElement,  model: async () => myButtonDefinition.ModelClass, } ``` This schema: - Defines available properties in the Module Builder. - Provides default values. - Enables type checking. ### 4. Implement Property Setters For each property in your model, implement a setter: ```typescript class MyButton extends HTMLElement {  private _label: string = ''  private _disabled: boolean = false    set label(value: string) {    this._label = value    this.render()  }    set disabled(value: boolean) {    this._disabled = value    this.render()  }    set submissionData(value: unknown) {    // Handle submission data updates from the platform    this._data = value    this.render()  } } ``` ### 5. Update Event Handlers #### Vega ```javascript handleSelection(item) {  // Emit event  this.api.events.emit('itemSelected', {    itemId: item.id,    itemName: item.name  })    // Update component's own state  this.api.state.set({ selectedItemId: item.id }) } ``` #### Centauri ```typescript handleSelection(item: Item) {  // Dispatch event — routing configured in Module Builder  this.onItemSelected?.({    itemId: item.id,    itemName: item.name  })    // Update submission data  this.onSubmissionUpdate?.(item.id) } ``` ### 6. Configure Triggers in Module Builder Instead of specifying targets directly in your component code, configure triggers declaratively: ```json {  "triggers": {    "onItemSelected": {      "contextId": "selectedItem",      "targetId": "processSelection"    }  } } ``` When `onItemSelected` fires: 1. The platform stores the payload in the `selectedItem` context field. 2. The `processSelection` component executes. 3. That component reads `selectedItem` from the context. ## Breaking Changes ### No Operation Handlers Centauri BYO has no concept of Operations. Vega allowed components to register operation handlers like `MyOperationHandler` that the platform could invoke. **Migration**: Implement all logic directly in your component. Use properties to receive configuration and callbacks to trigger platform workflows. #### Example ```javascript // ❌ Vega - operation handler class MyOperationHandler {  execute(params) {    // Custom logic  } } // ✅ Centauri - implement in component class MyComponent extends HTMLElement {  handleAction(params) {    // Custom logic here    this.onActionComplete?.(result)  } } ``` ### No Direct Platform API Access Centauri components cannot: - Call operations to modify other components directly. - Access the Redux store. - Navigate to other pages directly. - Execute workflow operations. **Migration**: Use triggers to invoke platform logic that performs the required actions. ### No Synchronous State Access Vega allowed reads of platform state. Centauri sets state through properties in the background. **Migration**: Store necessary state locally in your component, updated through setters. ### Event Routing Changes Vega events specified targets directly. Centauri events are routed through Module Builder configuration. **Migration**: Move event routing from component code to Module Builder trigger configuration. ## Benefits of the New Model ### Simpler Component Code - No operations API to learn. - No manual state synchronization. - Properties in, callbacks out. ### Better Testability Components are pure Web Components with no platform dependencies: ```typescript import { mountByoComponent, createCallbackSpy } from '@unqork/byo-sdk/testing' it('fires callback on click', async () => {  const el = await mountByoComponent(myButton)  const spy = createCallbackSpy()    el.onButtonClicked = spy.fn  el.querySelector('button')!.click()    expect(spy.calls).toHaveLength(1) }) ``` ### Declarative Configuration Event routing is visible in the module definition, not hidden in component code. ### Framework Flexibility The properties + callbacks model works naturally with any framework: - Vanilla JavaScript. - React. - Vue. - Angular. - Lit. ## Need Help? - **[Building Components Guide](/unqorkai/docs/building-components-byo-sdk)** — step-by-step component development. - **[CLI Reference](/unqorkai/docs/cli-reference-byo-sdk)** — complete SDK command documentation. - **[Testing Guide](/unqorkai/docs/testing-guide-byo-sdk)** — write tests for migrated components. --- **Changelog** | Date | Change | | --- | --- | | 2026-09-29 | Accuracy fix: Step 3 now uses defineComponent from @unqork/byo-sdk/schema to generate ModelClass, matching the required ByoComponentExport contract (EN-8153). | | 2026-05-01 | Initial publication | The Vega (v 2.0.0) runtime is the next-generation engine of the UDesigner platform. Vega uses cutting-edge technologies to improve the Creator and end-user experience. The Centauri (v 1.0.0) runtime is the first-generation foundation of the Unqork Designer Platform. Centauri provides Creators a codeless experience for developing applications. APIs (application programming interfaces) are a set of protocols and definitions developers use to build and integrate application software. APIs act as the connective tissue between products and services. A key-value pair is a fundamental data structure where a unique "key" is associated with a specific "value," used for organizing and retrieving data efficiently, like in dictionaries or databases. Schema is a declarative language that defines the structure, content, and constraints of the data. Also known as Unqork Users, or Designer Users; is anyone who is inside the Unqork platform. A JavaScript property is a member of an object that associates a key with a value. A JavaScript object is a data structure that stores a collection of properties. Triggers activate another component when certain requirements are met. Trigger types include Concurrent, Post, and Error. Some components do not have the ability to trigger others. JavaScript is an object-oriented computer programming language. It is most-commonly used for interactive effects in the browser. AngularJS is a JavaScript framework added to an HTML page with a