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

@broxium/runtime

v1.10.0

Published

Broxium Web Runtime

Readme

@broxium/runtime

Version: 1.5.3

Developer-facing runtime for Brodox components. Provides components and hooks that work correctly in both server-side rendering (SSR) and browser hydration contexts.


Installation

This package is pre-installed in the Brodox component build environment. You do not install it manually in component code — just import from it directly.

import { BrodoxImage, BrodoxLink, useRouter } from '@broxium/runtime'

Components

<BrodoxImage>

Renders an optimised <img> tag. By default, routes the image through the web engine's /api/image proxy (sharp resize + WebP conversion + disk cache). Use direct to bypass the proxy entirely.

// Proxied — resized, converted to WebP, cached on server disk
<BrodoxImage
  src="/uploads/hero.jpg"
  alt="Hero"
  width={1200}
  quality={80}
  priority
/>

// Direct — browser fetches S3/CDN URL directly, zero server involvement
<BrodoxImage
  src="https://cdn.example.com/hero.jpg"
  alt="Hero"
  width={1200}
  direct
/>

Props

| Prop | Type | Default | Description | |---|---|---|---| | src | string | required | Image URL or local path under UPLOAD_PATH | | alt | string | required | Alt text | | width | number | 1920 | Max pixel width; srcset stops here | | height | number | — | Height hint for layout | | fill | boolean | false | position:absolute; inset:0; width/height:100%; objectFit:cover | | priority | boolean | false | loading="eager" for above-the-fold images | | quality | number | 75 | Sharp quality 1–100 (ignored when direct) | | sizes | string | — | Standard sizes attribute | | className | string | — | CSS class | | style | CSSProperties | — | Inline styles | | onLoad | () => void | — | Load callback | | onError | () => void | — | Error callback | | direct | boolean | false | Bypass /api/image proxy; serve src URL directly |

Image proxy (/api/image) — default mode

Generates a responsive srcset at standard breakpoints: 320w, 640w, 768w, 1024w, 1280w, 1920w (up to width). Server caches processed images at {UPLOAD_PATH}/image-cache/{md5}.webp permanently. Browser caches with max-age=31536000, immutable.

When to use direct

  • Source is already on S3, Cloudflare, or another CDN — no benefit from proxying
  • You want to avoid adding load to the web engine server
  • Image is already the right size and format

Note: direct skips all resizing and format conversion. The browser receives the raw src URL.


<BrodoxLink>

SPA-aware internal navigation link. Renders an <a> tag with data-brodox-link attribute so the shell can intercept the click and perform client-side navigation with a progress bar instead of a full page reload.

<BrodoxLink href="/about-us">About</BrodoxLink>

// With search params — visible in browser URL, sent to server in POST body
<BrodoxLink href="/pricing?period=9&plan=starter">View Pricing</BrodoxLink>

// Replace history entry (no back button)
<BrodoxLink href="/step-2" replace>Next</BrodoxLink>

Props

| Prop | Type | Default | Description | |---|---|---|---| | href | string | required | Target path (absolute), may include ?search and #hash | | children | ReactNode | required | Link content | | replace | boolean | false | history.replaceState instead of pushState | | scroll | boolean | true | Scroll to top after navigation | | className | string | — | CSS class | | style | CSSProperties | — | Inline styles | | onClick | (e) => void | — | Called before navigation logic |

How navigation works

  1. Shell intercepts click (capture phase) via data-brodox-link attribute
  2. pushState updates browser URL immediately (search params visible)
  3. POST /api/render sent with body { path, tid, ...searchParams }
  4. Progress bar animates while waiting
  5. On success: new HTML injected, page bundle loaded, islands hydrated
  6. On error or timeout (12s): falls back to window.location.href (full reload)

External links: Use a plain <a href> tag. The shell only intercepts data-brodox-link elements.


<BrodoxRouter>

Wraps a subtree that needs access to the router context. Provides useRouter() with the current pathname and navigate function.

<BrodoxRouter>
  <Nav />
  <main>{children}</main>
</BrodoxRouter>

<Client>

Island boundary — marks a component for client-side hydration. During SSR emits an empty placeholder div + sibling <script type="application/json"> with props. The shell activates the component after page load (hydration mode: load).

export default function App() {
  return (
    <div>
      <h1>Static heading (server rendered)</h1>
      <Client>
        <Counter initialCount={0} />
      </Client>
    </div>
  )
}

Sub-islands created inside a server component with <Client> are looked up via __registry__ in the parent's page bundle.

Important: <Client> does not accept a hydration prop. All islands currently hydrate on page load. The hydration modes documented in the web engine architecture (idle, visible, none, only) are reserved for a future release.

Alternative: If the entire component is interactive (uses useState, event handlers, etc.), use 'use client' on the entry file instead of wrapping everything in <Client>. That compiles the whole component as client-only with zero SSR overhead.


<Server>

Semantic marker — transparent passthrough. Wraps server-only content for clarity.

<Server>
  <PriceTable prices={serverPrices} />
</Server>

<BrodoxHead>, <BrodoxFont>

Server-side no-ops in the current implementation. Reserved for future SEO and font injection support.


Hooks

useRouter()

Returns the current router instance.

const { pathname, navigate, back, forward } = useRouter()

// Navigate programmatically
navigate('/about-us?tab=team')

// Navigate without adding to history
navigate('/checkout', { replace: true })

| Property | Type | Description | |---|---|---| | pathname | string | Current pathname (no search, no hash) | | params | Record<string, string> | Route params (future) | | navigate(href, opts?) | function | SPA navigation; same as BrodoxLink | | back() | function | history.back() | | forward() | function | history.forward() | | prefetch(href) | function | No-op (reserved) |

useParams()

Returns route params. Currently returns {} (reserved for future dynamic routes).


How SSR stubs work

When your component is compiled for SSR, @broxium/runtime imports are replaced by the runtimeServerStubPlugin inside @broxium/compiler with inline server-safe implementations. This means:

  • No external module resolution needed inside the server bundle
  • BrodoxLink renders <a data-brodox-link> (not an interactive React component)
  • BrodoxImage renders an <img> pointing to /api/image (or src directly if direct)
  • Client renders a placeholder div for the shell to hydrate
  • Hooks return static defaults

The client bundle (.client.esm.js) uses the real @broxium/runtime from the browser's import map (/static/broxium-runtime.js).


Changelog

| Version | Change | |---|---| | 1.5.3 | BrodoxImage: added direct prop to bypass /api/image proxy | | 1.5.2 | BrodoxLink: added data-brodox-link attribute (required for shell interception) | | 1.5.1 | BrodoxRouter.navigate(): pushes full URL including search params | | 1.5.0 | SPA navigation rewrite: POST body, search params in URL | | 1.4.0 | Initial island hydration directives |