---
title: Widget
description: Widget protocol schemas
---

{/* ⚠️  AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs go in content/docs/guides/. */}

Widget Lifecycle Hooks Schema

Defines lifecycle callbacks for custom widgets inspired by Web Components and React.

These hooks allow widgets to perform initialization, cleanup, and respond to changes.

@see https://developer.mozilla.org/en-US/docs/Web/API/Web_components

@see https://react.dev/reference/react/Component#component-lifecycle

@example

```typescript

const widget = \{

lifecycle: \{

onMount: "console.log('Widget mounted')",

onUpdate: "if (prevProps.value !== props.value) \{ updateUI() \}",

onUnmount: "cleanup()",

onValidate: "return value.length > 0 ? null : 'Required field'"

\}

\}

```

<Callout type="info">
**Source:** `packages/spec/src/ui/widget.zod.ts`
</Callout>

## TypeScript Usage

```typescript
import { WidgetEvent, WidgetLifecycle, WidgetManifest, WidgetProperty, WidgetSource } from '@objectstack/spec/ui';
import type { WidgetEvent, WidgetLifecycle, WidgetManifest, WidgetProperty, WidgetSource } from '@objectstack/spec/ui';

// Validate data
const result = WidgetEvent.parse(data);
```

---

## WidgetEvent

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **name** | `string` | ✅ | Event name |
| **label** | `string` | optional | Human-readable event label |
| **description** | `string` | optional | Event description and usage |
| **bubbles** | `boolean` | ✅ | Whether event bubbles |
| **cancelable** | `boolean` | ✅ | Whether event is cancelable |
| **payload** | `Record<string, any>` | optional | Event payload schema |


---

## WidgetLifecycle

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **onMount** | `string` | optional | Initialization code when widget mounts |
| **onUpdate** | `string` | optional | Code to run when props change |
| **onUnmount** | `string` | optional | Cleanup code when widget unmounts |
| **onValidate** | `string` | optional | Custom validation logic |
| **onFocus** | `string` | optional | Code to run on focus |
| **onBlur** | `string` | optional | Code to run on blur |
| **onError** | `string` | optional | Error handling code |


---

## WidgetManifest

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **name** | `string` | ✅ | Widget identifier (snake_case) |
| **label** | `string` | ✅ | Widget display name |
| **description** | `string` | optional | Widget description |
| **version** | `string` | optional | Widget version (semver) |
| **author** | `string` | optional | Widget author |
| **icon** | `string` | optional | Widget icon |
| **fieldTypes** | `string[]` | optional | Supported field types |
| **category** | `Enum<'input' \| 'display' \| 'picker' \| 'editor' \| 'custom'>` | ✅ | Widget category |
| **lifecycle** | `Object` | optional | Lifecycle hooks |
| **events** | `Object[]` | optional | Custom events |
| **properties** | `Object[]` | optional | Configuration properties |
| **implementation** | `Object \| Object \| Object` | optional | Widget implementation source |
| **dependencies** | `Object[]` | optional | Widget dependencies |
| **screenshots** | `string[]` | optional | Screenshot URLs |
| **documentation** | `string` | optional | Documentation URL |
| **license** | `string` | optional | License (SPDX identifier) |
| **tags** | `string[]` | optional | Tags for categorization |
| **aria** | `Object` | optional | ARIA accessibility attributes |
| **performance** | `Object` | optional | Performance optimization settings |


---

## WidgetProperty

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **name** | `string` | ✅ | Property name (camelCase) |
| **label** | `string` | optional | Human-readable label |
| **type** | `Enum<'string' \| 'number' \| 'boolean' \| 'array' \| 'object' \| 'function' \| 'any'>` | ✅ | TypeScript type |
| **required** | `boolean` | ✅ | Whether property is required |
| **default** | `any` | optional | Default value |
| **description** | `string` | optional | Property description |
| **validation** | `Record<string, any>` | optional | Validation rules |
| **category** | `string` | optional | Property category |


---

## WidgetSource

### Union Options

This schema accepts one of the following structures:

#### Option 1

**Type:** `npm`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **packageName** | `string` | ✅ | NPM package name |
| **version** | `string` | ✅ |  |
| **exportName** | `string` | optional | Named export (default: default) |

---

#### Option 2

**Type:** `remote`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **url** | `string` | ✅ | Remote entry URL (.js) |
| **moduleName** | `string` | ✅ | Exposed module name |
| **scope** | `string` | ✅ | Remote scope name |

---

#### Option 3

**Type:** `inline`

### Properties

| Property | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| **type** | `string` | ✅ |  |
| **code** | `string` | ✅ | JavaScript code body |

---


---

