---
title: "createEvent()"
description: "Dispatch custom events with type safety, without decorators."
group: Helpers
order: 3
---
# createEvent
`createEvent` creates a type-safe `EventEmitter` bound to a host element and registers it on the host's internal emitter registry. It is the functional equivalent of the [`@event`](/docs/decorators/event) decorator.
## Usage
```typescript
import type { EventEmitter } from '@ecopages/radiant/tools/event-emitter';
import { RadiantElement } from '@ecopages/radiant';
import { createEvent } from '@ecopages/radiant/helpers/create-event';
import { createEventListener } from '@ecopages/radiant/helpers/create-event-listener';
class CounterButton extends RadiantElement {
#countChanged: EventEmitter<{ count: number }>;
#count = 0;
constructor() {
super();
this.#countChanged = createEvent(this, {
name: 'count-changed',
bubbles: true,
composed: true,
});
createEventListener(this, { selector: 'button', type: 'click' }, () => {
this.#count++;
this.#countChanged.emit({ count: this.#count });
});
}
}
customElements.define('counter-button', CounterButton);
```
Use it with authored light DOM:
```html
```
## Parameters
`createEvent(host, config)` accepts:
| Parameter | Type | Required | Description |
| :-------- | :--- | :------- | :---------- |
| `host` | `RadiantElement` | Yes | The element that will dispatch events. |
| `config` | `EventEmitterConfig` | Yes | Event configuration (see below). |
### EventEmitterConfig
| Field | Type | Required | Description |
| :---- | :--- | :------- | :---------- |
| `name` | `string` | Yes | The event name (e.g., `'value-changed'`). |
| `bubbles` | `boolean` | No | Whether the event bubbles up the DOM. If omitted, `CustomEvent` uses its platform default of `false`. |
| `composed` | `boolean` | No | Whether the event crosses shadow DOM boundaries. If omitted, `CustomEvent` uses its platform default of `false`. |
| `cancelable` | `boolean` | No | Whether the event can be cancelled (default: `false`). |
If parent elements should observe the event through bubbling or delegated listeners, set `bubbles: true` explicitly.
## Return Value
Returns an `EventEmitter` instance. Call `.emit(detail)` to dispatch a `CustomEvent` with the provided detail payload.
```typescript
const emitter = createEvent<{ value: string }>(host, { name: 'change' });
emitter.emit({ value: 'hello' });
```
## Listening to Emitted Events
Pair `createEvent` with [`createEventListener`](/docs/helpers/create-event-listener) on a parent element.
```typescript
import { RadiantElement } from '@ecopages/radiant';
import { createEventListener } from '@ecopages/radiant/helpers/create-event-listener';
class ParentComponent extends RadiantElement {
constructor() {
super();
createEventListener(
this,
{ selector: 'counter-button', type: 'count-changed' },
(event) => {
const detail = (event as CustomEvent<{ count: number }>).detail;
console.log('Count:', detail.count);
},
);
}
}
customElements.define('parent-component', ParentComponent);
```
Use it with nested authored elements:
```html
```
## Learn More
- [`@event`](/docs/decorators/event) — Decorator equivalent.
- [`createEventListener`](/docs/helpers/create-event-listener) — Subscribe to events without decorators.