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

@webgui/client

v1.8.0

Published

One library for the WebGUI Minecraft mod: framework-agnostic core plus React, Vue and Svelte bindings.

Readme

@webgui/client

One library for the WebGUI Minecraft mod. A framework-agnostic core, plus React, Vue and Svelte bindings that are thin wrappers over it.

Replaces @webgui/react, @webgui/vue and @webgui/svelte, which were three parallel implementations of the same logic and had to be updated in lockstep every time the mod gained an event. Those packages still work and now re-export this one.

npm install @webgui/client

React, Vue and Svelte are optional peer dependencies — importing the core pulls in none of them.

Plain JavaScript

import { clientStore, deathStore, runCommand, respawn, isInMod } from '@webgui/client';

if (isInMod()) {
  clientStore.subscribe(() => {
    const c = clientStore.get();
    document.querySelector('#hp').textContent = `${c.health} / ${c.maxHealth}`;
  });
}

Every store has the same three members:

| Member | Purpose | |---|---| | subscribe(listener) | Registers a no-argument listener; returns the unsubscribe function. | | get() | The current value, or null before the mod has sent anything. | | getServerSnapshot() | Always null — there is no mod during server rendering. |

React

import { useWebGUIClient, useWebGUIDeath, useRespawn } from '@webgui/client/react';

function DeathScreen() {
  const death = useWebGUIDeath();
  const respawn = useRespawn();
  if (!death) return null;

  return (
    <div>
      <h1>You died</h1>
      <p>{death.deathMessage}</p>
      {death.canRespawn && <button onClick={respawn}>Respawn</button>}
    </div>
  );
}

Vue

<script setup lang="ts">
import { useWebGUIDeath, respawn } from '@webgui/client/vue';
const death = useWebGUIDeath();
</script>

<template>
  <div v-if="death">
    <h1>You died</h1>
    <p>{{ death.deathMessage }}</p>
    <button v-if="death.canRespawn" @click="respawn">Respawn</button>
  </div>
</template>

Svelte

<script lang="ts">
  import { webguiDeath, respawn } from '@webgui/client/svelte';
</script>

{#if $webguiDeath}
  <h1>You died</h1>
  <p>{$webguiDeath.deathMessage}</p>
  {#if $webguiDeath.canRespawn}
    <button on:click={respawn}>Respawn</button>
  {/if}
{/if}

API

State

| Core | React | Vue | Svelte | |---|---|---|---| | clientStore | useWebGUIClient() | useWebGUIClient() | webguiClient | | entityStore | useWebGUIEntity() | useWebGUIEntity() | webguiEntity | | deathStore | useWebGUIDeath() | useWebGUIDeath() | webguiDeath | | selectorStore(fn) | useWebGUISelector(fn) | useWebGUISelector(fn) | webguiSelector(fn) |

Use a selector when a component needs one field. The mod pushes client updates several times a second, so a component reading only health should not re-render every time the player walks.

Actions

postToGame, closeGui, runCommand, respawn — plain functions in every entry point. React also exports usePostToGame, useCloseGui, useRunCommand and useRespawn, which return the same functions with stable identity for dependency arrays.

All four are no-ops outside the mod, so a page can run in a normal browser tab without guards at every call site.

Helpers

| Core | React | Vue | Svelte | |---|---|---|---| | isInMod() | — | — | — | | isReady(value) | — | — | — | | getToken(param?) | useWebGUIToken(param?) | useWebGUIToken(param?) | webguiToken(param?) | | onWebGUIEvent(name, fn) | useWebGUIEvent(name, fn) | useWebGUIEvent(name, fn) | onWebGUIEvent(name, fn) |

Events that fire before your code runs

The mod sends webgui:death once, immediately after the document loads, and sets window.webgui.client / .entity / .death before that. Every store reads those snapshots at import time, so a component that mounts a tick late still sees the value — a bare addEventListener in a component would miss it.

Migrating

The hook and store names are unchanged, so the import path is usually the only edit:

- import { useWebGUIClient } from '@webgui/react'
+ import { useWebGUIClient } from '@webgui/client/react'
- import { webguiClient } from '@webgui/svelte'
+ import { webguiClient } from '@webgui/client/svelte'

One rename: Svelte's onWebGUIEvent and webguiToken now also exist under those names in the core, and the React/Vue entries expose them as useWebGUIEvent / useWebGUIToken as before.

License

MIT