---
title: "FAQ - BYO"
slug: "faq-byo"
updated: 2026-10-07T18:52:38Z
published: 2026-10-07T18:52:38Z
canonical: "docs.unqork.io/faq-byo"
---
> ## 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.
# FAQ - BYO
Common questions about BYO (Bring Your Own) custom components.
## General
Answers to the most fundamental questions about BYO and how it works.
### What Is BYO?
BYO (Bring Your Own) lets you create custom components that run inside Unqork applications. With BYO you can:
- Build custom components using vanilla JavaScript, React, Vue, Angular, or Lit.
- Integrate third-party libraries like D3, Chart.js, AG Grid, and Stripe.
- Reuse existing code from other systems or applications.
- Create no-code assets that work like built-in Unqork components.
BYO gives you flexibility to extend the platform while maintaining the benefits of no-code configuration.
### How Is BYO Different from Custom Code?
BYO is structured and centrally maintained, unlike ad-hoc custom code:
| Aspect | Traditional Custom Code | BYO |
| --- | --- | --- |
| **Structure** | Unstructured scripts | Defined component contract |
| **Reusability** | Copy-paste between modules | Drag-and-drop from component tray |
| **Updates** | Manual updates everywhere | Update, reflects everywhere |
| **Testing** | Manual, inconsistent | Built-in testing utilities |
| **Maintenance** | High overhead | Centralized updates |
| **Configuration** | Hardcoded values | No-code settings in Module Builder |
### What Can I Build with BYO?
You can create **custom components** that:
- Display custom UI like charts, grids, and visualizations.
- Integrate third-party services like payments, document signing, and maps.
- Implement bespoke business logic.
- Wrap existing JavaScript libraries.
Components can:
- Dispatch **events** that platform workflows.
- Receive **properties** from Module Builder configuration.
- Update **submission data** for use elsewhere in the application.
## Getting Started
Step-by-step answers to help you build and deploy your first BYO component.
### How Do I Create a BYO Component?
1. **Download the SDK**:
- Navigate to Custom Assets Administration > **BYO SDK**
- Download and install the SDK package for your operating system
2. **Scaffold a project**:
```bash
npx --package=./sdk.tgz create my-component --framework react --ts
```
3. **Build your component**:
- Define properties with Zod schema
- Implement UI with your chosen framework
- Wire up callbacks for events
4. **Test locally**:
```bash
npm run dev
```
5. **Build for production**:
```bash
npm run build:prod
```
6. **Upload to Unqork**: Upload the `.tar.gz` file from `dist/` to your Unqork environment
See the [Building Components Guide](/unqorkai/docs/building-components-byo-sdk) for a complete walkthrough.
### What Frameworks Are Supported?
The BYO SDK supports:
- **Vanilla JavaScript/TypeScript**: Plain Web Components.
- **React**: Using @r2wc/react-to-web-component bridge.
- **Vue**: Vue 3 with `defineCustomElement`.
- **Angular**: Angular 19+ with `@angular/elements`.
- **Lit**: Lit 3 Web Components.
Choose the framework your team knows best.
### Do I Need to Know JavaScript?
Yes, creating BYO components requires JavaScript/TypeScript knowledge. However:
- Using BYO components requires no code. Creators drag and drop them in the Module Builder.
- The SDK provides templates and scaffolding to minimize boilerplate.
- Documentation includes working examples to get started.
- TypeScript provides autocomplete and type safety.
If your team lacks JavaScript expertise, consider:
- Training developers on the SDK.
- Hiring contractors for initial component development.
- Using built-in Unqork components instead.
## Platform Integration
How BYO components communicate with the UnqorkAI platform.
### How Does BYO Integrate with the Platform?
BYO components use a **properties + callbacks** model:
**Platform → Component (Properties)**:
- Platform sets data as JavaScript properties.
- Component reacts to property changes.
- Includes `submissionData` and user-configured settings.
**Component → Platform (Callbacks)**:
- Component calls callback functions.
- Platform routes events to configured triggers.
- Triggers execute workflows and operations.
This creates a clean separation: your component doesn't need to know about platform internals.
### Can I Nest Built-in Components in BYO?
No, you cannot drag other Unqork components directly into your BYO component.
**Alternative approaches**:
- Pass data to your component through properties.
- Use the component's submission data to inform child rendering.
- Create multiple BYO components that coordinate through events.
**Example**:
```typescript
// Component receives items through properties
set items(value: Item[]) {
// Render child elements based on items
this.render(value)
}
```
### How Do I Trigger Platform Logic?
Use **callbacks** configured as **triggers** in Module Builder.
**1. Call a callback in your component**:
```typescript
handleClick() {
this.onButtonClicked?.({ label: this._label })
}
```
**2. Configure a trigger in Module Builder**:
```json
{
"triggers": {
"onButtonClicked": {
"contextId": "clickData",
"targetId": "processClickLogic"
}
}
}
```
When the button is clicked:
1. Callback fires with payload `{ label: "..." }`
2. Platform stores payload in `clickData` context field.
3. `processClickLogic` component executes.
4. That component can access `clickData`
## Development
Common questions about building components with specific frameworks and libraries.
### Can I Use React, Angular, or Vue?
Yes, as long as your components are exported as valid Web Components. The BYO SDK provides templates and scaffolding for:
- React, using TypeScript or JavaScript.
- Angular (TypeScript).
- Vue 3.
- Lit.
- Vanilla JavaScript/TypeScript.
**Important**: Framework components must be wrapped as Web Components. This is not automatic. Use the appropriate wrapper:
- **React**: Use `@r2wc/react-to-web-component`, which is included in SDK templates.
- **Vue**: Use `defineCustomElement`, which is included in SDK templates.
- **Angular**: Use `@angular/elements`, which is included in SDK templates.
- **Lit**: Already Web Components by default.
The SDK templates handle the conversion for you when you scaffold a new project.
### Can I Use Third-Party Libraries?
Yes, you can use any JavaScript library that:
- Supports plain JavaScript with no framework lock-in.
- Works in browser environments.
- Is properly licensed for your use.
**Popular libraries**:
- **Charts**: [D3](https://d3js.org), [Chart.js](https://www.chartjs.org), Plotly.
- **Grids**: AG Grid, Handsontable.
- **Payments**: Stripe, Plaid.
- **Utilities**: Lodash, date-fns, uuid.
**Install using npm**:
```bash
npm install d3
```
**Use in your component**:
```typescript
import * as d3 from 'd3'
renderChart() {
const svg = d3.select(this.querySelector('svg'))
// use d3...
}
```
### How Do I Style My Component?
Use CSS with shadow DOM encapsulation:
**Import CSS as a string**:
```typescript
import styles from './MyComponent.css?raw'
export class MyComponent extends HTMLElement {
connectedCallback() {
this.attachShadow({ mode: 'open' })
// Inject styles
const sheet = new CSSStyleSheet()
sheet.replaceSync(styles)
this.shadowRoot.adoptedStyleSheets = [sheet]
this.render()
}
}
```
Styles are scoped to your component and won't affect the rest of the page.
### How Do I Handle DOM Manipulation?
**✅ Do**:
- Manipulate your component's own DOM.
- Use `this.querySelector()` for elements inside your component.
- Modify elements you created.
**❌ Don't**:
- Manipulate the UnqorkAI platform DOM.
- Use `document.querySelector()` for platform elements.
- Modify Unqork components outside your component.
**Example**:
```typescript
// ✅ Good - your DOM
render() {
this.innerHTML = ``
this.querySelector('button')?.addEventListener('click', this.handleClick)
}
// ❌ Bad - modifies platform DOM
connectedCallback() {
document.querySelector('.unqork-module')?.classList.add('custom')
}
```
## Testing
How to test your BYO components locally and in automated suites.
### How Do I Write Tests?
Use the SDK testing utilities with Vitest:
```typescript
import { describe, it, expect } from 'vitest'
import { mountByoComponent, createCallbackSpy } from '@unqork/byo-sdk/testing'
import { myButton } from './entry'
describe('MyButton', () => {
it('fires callback on click', async () => {
const el = await mountByoComponent(myButton) as any
const spy = createCallbackSpy()
el.onButtonClicked = spy.fn
el.querySelector('button')!.click()
expect(spy.calls).toHaveLength(1)
})
})
```
**Run tests**:
```bash
npm test
```
See the [Testing Guide](/unqorkai/docs/testing-guide-byo-sdk) for comprehensive patterns.
### How Do I Test Locally?
Use the **dev harness**:
```bash
npm run dev
```
This opens a browser at `http://localhost:5173` with:
- Your component rendered.
- Mock scenarios selector.
- Callback log panel.
- Hot reload on file changes.
Define mock scenarios in `*.mocks.ts` files:
```typescript
import { defineMockScenario } from '@unqork/byo-sdk/testing'
export const defaultScenario = defineMockScenario({
name: 'Default',
props: {
label: 'Click me',
},
callbacks: ['onButtonClicked'],
})
```
## Deployment
How to deploy, update, and manage BYO components in Unqork.
### How Do I Deploy to Unqork?
1. **Build for production**:
```bash
npm run build:prod
```
2. **Locate the archive**: Find `dist/<component-name>.tar.gz`
3. **Upload to Unqork**:
- Go to Admin → Custom Assets
- Upload the `.tar.gz` file
- Review extracted metadata
- Save
4. **Use in Module Builder**:
- Drag "Custom Component" from component tray
- Select your component from the selector
- Configure settings
- Add triggers for events
### How Do I Update My Component?
1. **Make changes locally**.
2. **Build**: `npm run build:prod` — auto-bumps the patch version and creates the `.tar.gz`.
3. **Upload new** `.tar.gz` to Unqork.
4. **Changes reflect everywhere** the component is used.
**Note**: Breaking changes might require updating module configurations. Document breaking changes in your CHANGELOG.
### Can I Have Multiple Versions?
Currently, version of a component can be active at a time. Uploading a new version replaces the previous version.
**Best practices**:
- Use semantic versioning.
- Test thoroughly before uploading.
- Communicate breaking changes.
- Provide migration guides.
## Limitations
What BYO components cannot do and how to work around common constraints.
### What Are the Limitations of BYO?
**Framework Limitations**:
- Cannot nest Unqork components inside BYO components.
**Platform Limitations**:
- Components run client-side, with no server-side rendering.
- Cannot directly modify other Unqork components.
- Must use platform APIs for integration.
**Performance Considerations**:
- Each BYO asset adds to page load time.
- Large bundles impact performance.
- Many BYO components can slow down modules.
See [Best Practices](/unqorkai/docs/best-practices-byo) for mitigation strategies.
### Does BYO Support Server-Side Execution?
No, BYO components run client-side. They cannot be executed server-side.
**Alternatives for server-side logic**:
- Use logic components with triggers.
- Create backend services accessed through an API.
- Use Unqork's server-side features.
## Troubleshooting
Quick answers for the most common issues during development.
### Why Isn't My Component Rendering?
1. Check the browser console for errors.
2. Verify the bundle loaded in the Network tab.
3. Check that the custom element is defined in the Elements tab.
4. Test in the dev harness with `npm run dev`.
See [Troubleshooting](/unqorkai/docs/troubleshooting-byo) for detailed debugging steps.
### Why Aren't My Callbacks Firing?
1. The callback is not wired in the Module Builder triggers.
2. The callback name doesn't match what's configured in manifest.json.
3. Optional chaining is missing: use `this.onEvent?.()`, not `this.onEvent()`.
4. The callback was called before the platform finished setting it up.
To debug, log the callback before calling it:
```typescript
handleClick() {
console.log('Callback exists?', typeof this.onButtonClicked)
this.onButtonClicked?.({ label: this._label })
}
```
### How Do I Debug Bundling Issues?
**Check build output**:
```bash
npm run build
ls -la dist/
```
**Common issues**:
- Missing exports in `entry.ts`
- Incorrect export names that don't match the manifest.
- Build errors: check the console for details.
## Best Practices
Recommendations for building efficient, maintainable BYO components.
### How Many Components Per Asset?
**Prefer fewer, well-designed components**:
**✅ Good**:
- `form-inputs.tar.gz`: Text, number, email, and phone inputs.
- `data-visualization.tar.gz`: Charts, graphs, and tables.
**❌ Avoid**:
- `text-input.tar.gz`
- `number-input.tar.gz`
- `email-input.tar.gz`
Each BYO asset adds overhead. Combine related components into asset.
### How Do I Keep Bundle Size Small?
1. Use code splitting with dynamic imports.
2. Load heavy libraries when needed.
3. Import the functions you use from a library.
4. Avoid duplicate dependencies.
5. The SDK minifies in production automatically.
Monitor the bundle size after each build:
```bash
npm run build
ls -lh dist/*.js
```
Target: < 100KB per component, minified and compressed.
### What Accessibility Standards Should I Follow?
Follow **WCAG 2.1 Level AA**:
- ✓ Semantic HTML.
- ✓ ARIA labels.
- ✓ Keyboard navigation.
- ✓ Color contrast (4.5:1 for text).
- ✓ Focus indicators.
- ✓ Screen reader support.
Test with:
- Chrome DevTools Lighthouse.
- axe DevTools.
- Screen readers (NVDA, JAWS, VoiceOver).
---
**Changelog**
| Date | Change |
| --- | --- |
| 2026-10-01 | Corrected React bridge package name to `@r2wc/react-to-web-component`; updated Angular minimum version to 19+; corrected production build command to `npm run build:prod`; converted em dashes to colons/periods; cleaned up "and so on" list endings; added blank lines before all lists for correct MDX rendering (EN-8151). |
| 2026-05-01 | Initial publication |
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