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

@browsonic/svelte

v1.2.0

Published

Svelte / SvelteKit adapter for @browsonic/sdk — handleError hook factory, user store subscriber, capture helpers. Apache-2.0.

Readme

@browsonic/svelte

Svelte / SvelteKit adapter for @browsonic/sdk — SvelteKit handleError hook factory, Svelte-store user-context bridge, ergonomic capture wrappers, navigation breadcrumb instrumentation, SvelteKit form-action wrapper, and a +error.svelte integration helper.

Status: 0.3 surface — pure-TypeScript helpers, no compiled .svelte files. Boundary capture relies on Svelte 5's native <svelte:boundary>. Load-bearing surfaces: SvelteKit handleError hook (generic over App.Error), Svelte store user-context bridge, navigation breadcrumb instrumentation (instrumentNavigation + trackNavigation Svelte action), SvelteKit form-action wrapper (withBrowsonicAction), and a +error.svelte page helper (reportErrorPage).

Why this adapter

Two things differentiate Svelte from the React / Vue adapters:

  1. Svelte 5 has a native <svelte:boundary>. We don't ship a competing boundary — use the framework primitive. The adapter's job is to give your onerror handler a one-liner SDK forwarder.
  2. SvelteKit's error handling is hook-driven. src/hooks.client.ts exports a handleError function that the framework calls for every render-time crash. This package gives you the factory.

Install

npm install @browsonic/sdk @browsonic/svelte

@browsonic/sdk is a peer dependency. svelte (4.x or 5.x) is a peer dependency, but the recommended target is Svelte 5 — only Svelte 5 has <svelte:boundary>.

Quickstart — SvelteKit

// src/hooks.client.ts
import { handleErrorWithBrowsonic } from '@browsonic/svelte';
import { getBrowsonic } from '@browsonic/sdk';

const sdk = getBrowsonic();
sdk.init({ apiEndpoint: 'https://your-ingest-endpoint.test/v1/events' });

export const handleError = handleErrorWithBrowsonic();

For the server-side companion (hooks.server.ts), the SDK is a browser library — server capture is out of scope. Wire your server-side telemetry through the appropriate runtime adapter.

Quickstart — Svelte 5 boundary

<script lang="ts">
  import { captureError } from '@browsonic/svelte';
</script>

<svelte:boundary onerror={(err, reset) => {
  captureError(err instanceof Error ? err : new Error(String(err)));
}}>
  <RiskySubtree />
  {#snippet failed(error)}
    <p>Crashed: {error.message}</p>
  {/snippet}
</svelte:boundary>

Quickstart — User identity from a Svelte store

<script lang="ts">
  import { writable } from 'svelte/store';
  import { onDestroy } from 'svelte';
  import { subscribeUser } from '@browsonic/svelte';

  export const user = writable<UserContext | null>(null);

  const off = subscribeUser(user);
  onDestroy(off);
</script>

Every store change is mirrored as sdk.setUser(value); setting the store to null clears the user.

API

handleErrorWithBrowsonic(options?)

import { handleErrorWithBrowsonic } from '@browsonic/svelte';

export const handleError = handleErrorWithBrowsonic({
  sdk, // optional; default = window.Browsonic.getBrowsonic()
  chain: (input) => ({ message: '…' }), // optional; runs after the SDK has been notified
});

Returns a SvelteKit-compatible handleError hook. Forwards the thrown value (coerced to Error) to sdk.captureError, records the URL pathname under sveltekitPath metadata, and chains into your own handler if you pass one.

subscribeUser(store, options?)

Subscribe a Svelte readable store to the SDK user context. Accepts any object with a subscribe(fn) => unsubscribe shape — Readable, Writable, custom stores. Returns the unsubscribe handle.

captureError / captureMessage / addBreadcrumb

Ergonomic standalone wrappers that resolve the SDK from window. Use these when you don't already have a reference to the SDK in scope. All three are no-ops when the SDK is unreachable.

import { captureError, captureMessage, addBreadcrumb } from '@browsonic/svelte';

captureError(new Error('purchase failed'));
captureMessage('checkout step 2', 'info');
addBreadcrumb({ category: 'navigation', message: '/checkout' });

instrumentNavigation(options?) / trackNavigation Svelte action

Subscribe to SvelteKit / SPA navigation and emit a category: 'navigation' breadcrumb on every URL change. Two surfaces over one engine:

// Programmatic — call once at app init
import { instrumentNavigation } from '@browsonic/svelte';
const off = instrumentNavigation();
// optional: off() on app teardown
<!-- Action form — drop on a layout root -->
<script lang="ts">
  import { trackNavigation } from '@browsonic/svelte';
</script>

<div use:trackNavigation>
  <slot />
</div>

History API patches (pushState / replaceState) are ref-counted so multiple callers share one set of patches and the last unsubscribe restores the originals. Programmatic goto() calls fire via the synthetic browsonic:locationchange event; back/forward fire via popstate. Works without a @sveltejs/kit peer dep.

withBrowsonicAction(handler, options?)

Wraps a SvelteKit actions: {} handler so unhandled throws are reported (with sveltekit.action.name / sveltekit.action.method tags + sveltekitPath metadata) and then re-thrown so SvelteKit returns the action's failure to the client unchanged.

// src/routes/login/+page.server.ts
import { withBrowsonicAction } from '@browsonic/svelte';

export const actions = {
  default: withBrowsonicAction(
    async ({ request }) => {
      const data = await request.formData();
      // ... business logic that may throw
    },
    { actionName: 'login.default' },
  ),
};

Re-throw order matters — consuming the error here would mask every reported failure as a successful 200 response.

reportErrorPage(error, options?)

One-shot, idempotent capture for +error.svelte's <script> block. Reference-keyed de-dupe via module-scope WeakSet so a reactive $: binding doesn't re-report on every store tick.

<!-- src/routes/+error.svelte -->
<script lang="ts">
  import { page } from '$app/stores';
  import { reportErrorPage } from '@browsonic/svelte';

  $: reportErrorPage($page.error, {
    status: $page.status,
    pathname: $page.url.pathname,
  });
</script>

<h1>{$page.status}: {$page.error?.message ?? 'Something went wrong'}</h1>

Browser-only — SSR (typeof window === 'undefined') and "no SDK reachable" cases short-circuit to false so the helper is safe to call unconditionally.

resolveSdk(explicit?)

Lower-level helper for when you need explicit SDK access. Returns the explicit instance, or window.Browsonic.getBrowsonic(), or null.

Defensive contract

Every public surface follows the same rule:

  • The host app must never crash because reporting failed.
  • SDK calls are wrapped in try { ... } catch {}. If the wrapper, factory, or store subscriber can't reach the SDK, it stays silent.
  • subscribeUser returns a no-op unsubscribe when the input is not a store, instead of throwing.

What this package does NOT do

  • No <BrowsonicErrorBoundary> component. Use Svelte 5's native <svelte:boundary> and forward the thrown error from onerror via captureError. Svelte 4 has no clean boundary primitive — the SvelteKit handleError hook is the next-best mitigation.
  • Server-side capture. SvelteKit's hooks.server.ts runs in Node. The SDK is browser-only. withBrowsonicAction runs on the server too — it captures if a browser SDK is reachable (rare in pure server contexts) and otherwise re-throws cleanly.
  • Svelte 3 / pre-Composition Svelte. Svelte 3 is end-of-life; no back-port.

License

Apache-2.0. See the repo root LICENSE and the package NOTICE.