Official package · Frameworks

Angular signals for realtime WebSockets

Events, presence members, client events and connection state as signals, with one connection for the whole app. For Angular 17 and later, standalone or NgModule, with or without zone.js.

  • injectEvent, injectPresence, injectTrigger and injectConnectionState; channel names can be signals or component inputs, and subscriptions follow them.
  • Safe with server rendering and prerendering: nothing connects on the server, and everything is released when the component is destroyed.
  • streamToChannel() sends LLM output from your backend, and injectStream() shows it in every open tab as it is written.

Sign in to see these snippets with your own cluster host. Sign in

  1. Install

    npm install @hibira-io/angular pusher-js
  2. Set it up

    // app.config.ts
    import { ApplicationConfig } from '@angular/core';
    import { provideHibira } from '@hibira-io/angular';
    import { environment } from '../environments/environment';
    
    export const appConfig: ApplicationConfig = {
      providers: [
        provideHibira({
          appKey: environment.hibiraKey,
          options: {
            wsHost: 'ws.hibira.io',
            channelAuthorization: { endpoint: '/api/hibira/auth', transport: 'ajax' },
          },
        }),
      ],
    };
  3. Use it

    import { Component, signal } from '@angular/core';
    import { injectEvent, injectPresence } from '@hibira-io/angular';
    
    @Component({
      selector: 'app-dashboard',
      template: `<p>{{ dashboard.count() }} online, {{ orders().length }} new orders</p>`,
    })
    export class Dashboard {
      orders = signal<Order[]>([]);
      dashboard = injectPresence('presence-dashboard');
    
      constructor() {
        injectEvent<Order>('orders', 'order.created', (order) => this.orders.update((list) => [order, ...list]));
      }
    }

Before you start

  • On the Free plan, list every origin your pages load from in the app’s allowed origins (http://localhost:4200 while developing, then your domain). "*" needs a paid plan.
  • Private and presence channels need an auth endpoint on your backend that signs subscriptions with the app secret, as with pusher-js.

Use the app key from your dashboard; the secret stays on your server. Channels, events and authorization endpoints work exactly as they do with Pusher. Create your free account →