npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aviaratech/party

v0.1.0

Published

Headless browser Party lifecycle, bounded channels, and an optional React adapter for small peer-to-peer applications.

Readme

@aviaratech/party

A small, headless browser networking library for peer lifecycle, bounded application channels, request/response, and an optional React adapter.

Party is designed for browser applications that want to own their own identity, authorization, persistence, and game/application protocol while reusing a tested WebRTC connection lifecycle.

What Party owns

  • headless PartyClient connection state and immutable external-store snapshots;
  • connection-scoped opaque peer IDs;
  • browser foreground/online recovery and explicit reload-required signaling;
  • bounded, versioned application-channel envelopes;
  • targeted send, broadcast, and correlated request/response;
  • a Trystero/Nostr transport adapter;
  • optional useSyncExternalStore-based React hooks.

What Party does not own

Party is not a matchmaking service, authoritative game server, persistence layer, account system, moderation system, or game-netcode framework. Consumers remain responsible for application authorization, payload meaning, durable identity, canonical state, simulation, scoring, persistence, and UI.

Install

npm install @aviaratech/party

The package is ESM-only. The core is framework-neutral. React is an optional peer dependency used only by @aviaratech/party/react.

Headless quick start

import { PartyClient } from '@aviaratech/party'
import { createBrowserPartyLifecycleSource } from '@aviaratech/party/browser'
import { TrysteroNostrTransport } from '@aviaratech/party/trystero-nostr'

const party = new PartyClient({
  lifecycle: createBrowserPartyLifecycleSource(),
  createTransport: (handlers) =>
    new TrysteroNostrTransport({
      role: 'host',
      appId: 'your-app-id',
      actionNamespace: 'your-app-v1',
      wakeNamespace: 'YourAppWake',
      relayUrls: ['wss://your-nostr-relay.example'],
      partyId: 'shared-party-id',
      rendezvousCapability: 'shared-secret-capability',
      ...handlers,
    }),
})

await party.start()

The transport configuration is intentionally consumer-owned. Party does not ship application IDs, room IDs, credentials/capabilities, or a privileged relay list.

Bounded channels

A channel owns a stable ID, a pre-parse byte limit, and consumer-defined serialization/validation.

type Control = { type: 'ready' } | { type: 'ping'; sentAt: number }

const control = party.channel<Control>({
  id: 'control',
  maxPayloadBytes: 1024,
  serialize: JSON.stringify,
  parse(serialized) {
    const value = JSON.parse(serialized) as unknown
    // Replace with your own strict parser/schema validation.
    return isControl(value) ? value : null
  },
})

await control.send({ type: 'ready' })

const response = await control.request(
  { type: 'ping', sentAt: Date.now() },
  { to: party.peerIds()[0]!, timeoutMs: 5000 },
)

Remote bytes are untrusted. Party validates its own closed/versioned envelope and enforces the byte bound before the consumer parser runs, but the consumer must validate its own payload schema and authorize each operation. Source connection identity is provided separately from payload data; do not trust an identity claim carried inside a remote payload.

React

import type { PartyClient } from '@aviaratech/party'
import { usePartyPeers, usePartyStatus } from '@aviaratech/party/react'

function ConnectionStatus({ party }: { party: PartyClient }) {
  const status = usePartyStatus(party)
  const peers = usePartyPeers(party)
  return <span>{status} · {peers.length} peers</span>
}

The React adapter only observes the headless external store. It does not own WebRTC objects, transport generations, recovery, or frame-by-frame game state.

Connection states

  • idle — client has not started;
  • connecting — a transport generation is starting or no peer has completed the current bidirectional proof yet;
  • online — at least one current-generation peer has passed the package control-path proof;
  • interrupted — no currently verified peer remains;
  • recovering — Party is revalidating/replacing the transport after a lifecycle signal;
  • reload-required — the current browser/library transport namespace cannot be safely reused in-page;
  • closed — the client was disposed;
  • error — transport startup failed.

online is transport/package readiness, not application synchronization. Your protocol may require its own authenticated handshake, state sync, or readiness gate before gameplay or other authority-sensitive work begins.

Browser lifecycle

createBrowserPartyLifecycleSource() observes foreground-relevant browser signals and lets the headless client coalesce recovery. Party never forces a navigation or reload. If the snapshot reaches reload-required, the consumer decides how to preserve local state and reload/recreate the page.

Trystero / Nostr adapter

@aviaratech/party/trystero-nostr is the currently proven transport adapter. Trystero remains an implementation detail behind the Party transport contract; application code should not use Trystero peer IDs as durable player/member identity.

The current adapter uses public rendezvous plus direct WebRTC and does not configure TURN. Restrictive NAT/firewall environments can therefore fail to establish a direct path. Treat the supported connectivity envelope as evidence-driven rather than universal.

Security and privacy model

  • Treat every remote payload as untrusted.
  • Use strict consumer validation and explicit authorization.
  • Keep durable account/member/player identity outside Party.
  • Treat party IDs, rendezvous capabilities, admission material, and similar secrets as consumer-owned credentials.
  • Do not put credential material or application payloads into diagnostics.
  • A connection ID is opaque and scoped to the active transport generation; it is not a durable identity.
  • Unsafe transport teardown fails closed rather than silently reusing a poisoned generation.

See SECURITY.md for reporting guidance.

Browser support

Party targets modern evergreen browsers with WebRTC, WebSocket, TextEncoder, and standard browser lifecycle events. Safari/iOS lifecycle behavior is part of the tested design, but direct WebRTC reachability still depends on the networks between peers.

API stability

The package starts at 0.x. Semver is used, but before 1.0 a minor release may contain a breaking public-API change when the change is documented in release notes. Patch releases are reserved for compatible fixes.

See RELEASE.md for the release policy and provenance/trusted-publishing process.

License

MIT © 2026 Aviara Tech LLC. See LICENSE.

Examples

See examples/headless.ts and examples/react.tsx.