Build custom components for the Unqork platform using vanilla JavaScript, React, Vue, Angular, or Lit. BYO (Bring Your Own) gives Creators full control over component behavior and appearance while integrating with the Unqork runtime.
BYO is a developer feature that requires JavaScript expertise. Creators evaluating whether a project needs a custom component will find the relevant context in this overview. Developers ready to build can skip directly to Building Components.
What Is BYO?
BYO lets Creators build custom components that run inside Unqork applications. BYO components can do the following:
- Integrate with platform state: Receive data from submission data and other components.
- Trigger workflows: Dispatch events that can execute platform logic.
- Use any framework: Build with vanilla JavaScript, React, Vue, Angular, or Lit.
- Deploy globally: Upload once, use across all applications in the environment.
When to Use BYO
Appropriate Use Cases
Use BYO when the following apply:
- Third-party libraries: A specific JavaScript library provides functionality Unqork doesn't offer natively: charting (D3.js, Chart.js), payment processing (Stripe elements, Plaid), document signing (DocuSign, Adobe Sign), or embedded analytics (Power BI).
- Existing proprietary logic: Code that already exists, like a pricing engine, insurance rater, or domain-specific algorithm, must run inside an Unqork application.
- Specialized UI components: Branded or domain-specific components from an existing system need to integrate with Unqork.
When to Avoid BYO
Avoid BYO when the following apply:
- Built-in Unqork components can meet the need with configuration.
- Simple CSS styling achieves the visual goal.
- Logic components like Triggers or Calculators can implement the business logic.
- The requirement is temporary or one-off. The maintenance overhead is not worth it.
Decision Flowchart
Do you need a specific third-party library?
├─ Yes → ✅ BYO is appropriate
└─ No → Do you have existing proprietary logic to reuse?
├─ Yes → Is it complex or proprietary?
│ ├─ Yes → ✅ BYO is appropriate
│ └─ No → Can logic components handle it?
│ ├─ Yes → ❌ Use logic components
│ └─ No → ✅ BYO is appropriate
└─ No → Can built-in components meet your needs?
├─ Yes → ❌ Use built-in components
└─ No → ✅ BYO might be appropriate
How It Works
BYO components use a properties + callbacks model with the following interactions:
- Platform → Component: The platform sets data as JavaScript properties on your component.
- Component → Platform: Your component calls callback functions to dispatch events.
Your component is intentionally isolated from the platform's internal APIs. All integration happens through a clean, versioned contract.
┌─────────────────┐ ┌──────────────────┐
│ Platform State │────Props──────▶│ Your Component │
│ │ │ │
│ │◀──Callbacks────│ │
│ │ │ │
│ │──Commands─────▶│ │
└─────────────────┘ └──────────────────┘
▲ │
│ │
│ ▼
│ ┌──────────────────┐
│ │ Platform Triggers│
│ │ │
│ └──────────────────┘
│ │
│ │
│ ▼
│ ┌──────────────────┐
└─────────────────────────│ Workflow / Ops │
│ │
└──────────────────┘
Example: Button Component
// Define your component as a Web Component
class MyButton extends HTMLElement {
// Platform sets these properties
set label(value: string) {
this._label = value
this.render()
}
set disabled(value: boolean) {
this._disabled = value
this.render()
}
// Your component calls this callback
handleClick() {
this.onButtonClicked?.({ label: this._label })
}
render() {
this.innerHTML = `
<button ${this._disabled ? 'disabled' : ''} onclick="this.getRootNode().host.handleClick()">
${this._label}
</button>
`
}
}
In the Module Builder, configure a trigger that executes when onButtonClicked fires:
{
"key": "myButton",
"type": "byoc",
"triggers": {
"onButtonClicked": {
"contextId": "clickData",
"targetId": "someLogicComponent"
}
}
}
When the button is clicked, clickData is populated with { label: "Click me" } and the logic component executes.
Key Concepts
Properties (Platform → Component)
The platform sets the following properties on the component element:
submissionData: The component's current submission value.- State properties: Any properties defined in your component's model, like
label,items, anddisabled.
Implement a setter for each property your component must handle:
set label(value: string) {
this._label = value
this.render()
}
Callbacks (Component → Platform)
The platform wires callback functions as properties on your component. Call them to dispatch the following events:
onSubmissionUpdate(value): Updates the component's submission data.on<EventName>(payload): Fires a trigger configured in the Module Builder.
Always guard with optional chaining because callbacks are set after mount:
this.onButtonClicked?.({ label: this._label })
Triggers (Module Builder Configuration)
Triggers connect component events to platform logic:
{
"triggers": {
"onItemSelected": {
"contextId": "selectedItem",
"targetId": "processSelectionLogic"
}
}
}
When your component calls this.onItemSelected({ id: 123 }), the platform stores { id: 123 } in the selectedItem context field and executes the processSelectionLogic component.
Commands (Platform → Component)
Commands are fire-and-forget CustomEvents dispatched to your component from the platform. They enable imperative method-like interactions for headless or service components.
Your component listens for commands using event listeners on the element:
// Listen for commands via event listeners
element.addEventListener('reset', (e) => {
const { silent } = e.detail || {}
this.resetState(silent)
})
Commands are dispatched when BYOC Execute outputs are triggered from logic components like the Initializer, Decision, and Logic Block components. Configure them in the Module Builder:
{
"outputs": [
{
"targetId": "myComponent",
"type": "byocExecute",
"value": {
"componentType": "myComponent",
"commandType": "reset",
"args": { "silent": true }
}
}
]
}
When to Use Commands
- Imperative operations like reset, refresh, focus, and validate.
- Headless or service components like payment gateways and analytics integrations.
- Third-party library integrations with method-based APIs.
How Commands Differ from Events
- Direction: Commands flow to components; events flow from components.
- Pattern: fire-and-forget with no return value; events trigger workflows.
- Use case: Imperative actions; events represent state changes.
Differences from Vega BYO
Centauri BYO is the recommended architecture for new components. Creators with existing Vega BYO components can migrate using the Migration Guide. Centauri BYO has a simpler, more explicit integration model:
| Feature | Vega BYO | Centauri BYO |
|---|---|---|
| Platform integration | Operations API — call platform methods directly | Properties + callbacks — declarative data flow |
| Event dispatch | Direct API calls | Callbacks configured as triggers |
| State management | Manual sync with platform state | Automatic property updates from platform |
| Configuration | API keys and methods | Properties defined in model schema |
Learn more in the Migration Guide
Getting Started
BYO development has two phases: a one-time environment setup and a per-component build cycle. Complete the setup steps once per developer environment. Repeat the build cycle for each component you create or update.
One-Time Setup
1. Download and Install the BYO SDK
Download the BYO SDK from the Unqork administration screen:
- In the Unqork IDE, navigate to Administration > Environment Settings > Assets > Custom Assets Administration.
- Click BYO SDK.
- Follow the BYO SDK installation instructions.
For Each Component
1. Scaffold a New Project
npx --package=./sdk.tgz create my-button --framework react --ts
cd my-button
npm install
2. Start the Dev Server
npm run dev
The dev harness opens at http://localhost:5173, simulating how the platform will mount your component.
3. Build for Production
npm run build:prod
This creates a .tar.gz archive in dist/ ready for upload to the Unqork platform.
4. Upload to Unqork
Upload the .tar.gz file through the Unqork administration interface to make your component available in the Module Builder.
Documentation
Getting Started
- Build your first component — step-by-step guide.
Development
- Styling guide — CSS best practices, Shadow DOM, theming.
- Best practices — performance, security, maintainability.
- Testing guide — write tests for your components.
- CLI reference — complete command documentation.
Migration & Support
- Migration guide — migrate from Vega BYO.
- FAQ — common questions and answers.
- Troubleshooting — solve common issues.
Technical Details
- Contract version: 1.0.0
- Module Builder type:
byoc - Bundle format: ESM (ECMAScript modules)
- Runtime environment: modern browsers (ES2020+)