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

@laot/nuix

v2.0.12

Published

Framework-agnostic FiveM NUI helpers — fetchNui, messages and more.

Readme

@laot/nuix

Small, framework-agnostic helpers for FiveM NUI — callbacks, message listeners, and LTBridge CreateState sync on the web.

  • Zero runtime dependencies
  • ESM + CJS + TypeScript declarations
  • Works with Vue, React, Svelte, or plain JS

npm version license


Install

npm install @laot/nuix

What it does

| Problem | nuix API | |--------|----------| | Call Lua from the UI | fetchNui | | Dev in the browser without FiveM | setResourceName, setNuiMocks, per-call mockData | | Listen to SendNUIMessage | onNuiMessage, onNuiAction | | Apply LTBridge batched state | applyLtBatch | | Full state replace (_sync / _set) | replaceLtState |


1. fetchNui

Posts JSON to https://<resource>/<event> (same as RegisterNUICallback on the Lua side).

import { fetchNui, isEnvBrowser, setResourceName, setNuiMocks } from "@laot/nuix";

if (isEnvBrowser()) {
  setResourceName("myresource");
  setNuiMocks({
    getPlayer: { name: "Dev", level: 99 },
  });
}

const player = await fetchNui<{ name: string; level: number }>("getPlayer", { id: 1 });

// Or pass a one-off mock as the third argument
const mocked = await fetchNui("getPlayer", {}, { name: "Local", level: 1 });

In the browser, if there is no mock, fetchNui throws with a clear error so you do not hit a dead URL silently.

Lua:

RegisterNUICallback("getPlayer", function(data, cb)
  cb({ name = "John", level = 42 })
end)

2. Messages from Lua

import { onNuiMessage, onNuiAction } from "@laot/nuix";

const unsub = onNuiMessage((data) => {
  console.log(data.action, data.namespace);
});

const unsubLocale = onNuiAction("UpdateLocale", (data) => {
  console.log(data.locale, data.translations);
});

unsub();

Extend NuiMessageData in your project for custom actions:

import type { NuiMessageData } from "@laot/nuix";

interface MyMessage extends NuiMessageData {
  items?: string[];
}

3. LTBridge CreateState (batch + sync)

When using LT.NUI.CreateState on Lua, the UI receives:

| Lua | action | Fields | |-----|----------|--------| | Batched edits (same tick) | UpdatePlayer (your action name) | batch, deletes?, namespace | | :sync() | UpdatePlayer_sync | state, namespace | | :set() | UpdatePlayer_set | state, namespace |

Array paths are 1-based (Lua style), e.g. "inventory.items.1.name" → JS array index 0.

applyLtBatch merges nested batch objects and applies partial array index patches without replacing the whole array (see LTBridge bridge-nui behaviour).

Vue + Pinia

import { onNuiMessage, applyLtBatch, replaceLtState } from "@laot/nuix";
import { useMainStore, useLocaleStore } from "@/stores";

onNuiMessage((data) => {
  const main = useMainStore();
  const locale = useLocaleStore();

  switch (data.action) {
    case "UpdatePlayer":
      main.$patch((s) =>
        applyLtBatch(s.player, {
          batch: data.batch,
          deletes: data.deletes,
        }),
      );
      break;
    case "UpdatePlayer_sync":
    case "UpdatePlayer_set":
      main.$patch((s) => replaceLtState(s.player, data.state ?? {}));
      break;
    case "UpdateLocale":
      if (data.locale) locale.updateLocale(data.locale);
      if (data.translations) locale.updateTranslations(data.translations);
      break;
  }
});

React

applyLtBatch and replaceLtState mutate in place. With useState, clone first so React sees a new reference:

setPlayer((prev) => {
  const next = structuredClone(prev);
  applyLtBatch(next, { batch: data.batch, deletes: data.deletes });
  return next;
});

// sync / set
setPlayer(structuredClone(data.state ?? {}));

API reference

| Export | Description | |--------|-------------| | isEnvBrowser() | true when not running inside FiveM | | getResourceName() | Host segment for NUI fetch URLs | | setResourceName(name) | Override resource name (browser dev) | | fetchNui(event, data?, mockData?) | NUI callback POST | | setNuiMocks(mocks) | Register browser mocks by event name | | clearNuiMocks() | Clear mocks | | onNuiMessage(handler) | Subscribe to all messages; returns unsubscribe | | onNuiAction(action, handler) | Subscribe to one action | | applyLtBatch(target, message) | Apply batch + deletes | | replaceLtState(target, state) | Full in-place replace for _sync / _set | | LtBatchMessage | { batch?, deletes? } | | NuiMessageData | Flat message shape |


Migrating from 1.x

Removed in v2:

  • createFetchNui — use fetchNui + setNuiMocks
  • onNuiMessage nested { action, data } — flat payload only
  • Locale helpers (_U, registerLocales, …) — keep locale in your app (e.g. Pinia)
  • NuiEventMap — optional types in your own codebase

Build

npm run build
npm run typecheck

Requires Node.js 18+.


MIT © LAOT