FiveM NUI resource scaffold with Svelte 5 + Vite + TypeScript.
├── bridge/ # Multi-framework support (qbx/qb/esx/standalone)
├── client/ # Client Lua scripts
├── server/ # Server Lua scripts
├── shared/ # Shared config
├── lib/ # Lua utilities
├── locales/ # i18n locale files
└── web/ # Svelte 5 + Vite + TypeScript UI
cd web
bun install
bun run buildTrigger a NUI callback to the game client.
const result = await fetchNui("getPlayerData", { id: 1 });Simulate NUI messages in browser dev mode.
import.meta.env.DEV && isEnvBrowser() && debugData([
{ action: "setVisible", data: { show: true } },
]);Send a message from the game client to the web UI.
SendNUIMessage({
action = "setVisible",
data = { show = true }
})Handle NUI callbacks from the web UI.
RegisterNUICallback("getPlayerData", function(data, cb)
local playerData = { id = data.id, name = "John" }
cb(playerData)
end)web/src/lib/handler.ts listens for messages sent via SendNUIMessage from Lua. Messages are dispatched by action:
export function handler() {
function Event(event) {
switch (event.data.action) {
case "setVisible":
// handle visibility
break;
}
}
onMount(() => window.addEventListener("message", Event));
onDestroy(() => window.removeEventListener("message", Event));
}The bridge/ layer provides multi-framework support. Framework is auto-detected in bridge/init.lua:
-- Detects: qbx, qb, esx, standalone
local framework = require 'bridge'Add framework-specific logic in:
bridge/client/qbx.lua,bridge/client/qb.lua,bridge/client/esx.lua,bridge/client/standalone.luabridge/server/qbx.lua,bridge/server/qb.lua,bridge/server/esx.lua,bridge/server/standalone.lua- Access via
require 'bridge.client.bridge'orrequire 'bridge.server.bridge'
Svelte stores in web/src/stores/ manage shared UI state:
import { writable } from "svelte/store";
export const shows = writable(false);Use in components:
<script lang="ts">
import { shows } from "@store/app";
</script>
{#if $shows}
<div>Visible</div>
{/if}| Alias | Path |
|---|---|
@lib |
./src/lib |
@store |
./src/stores |
@components |
./src/components |
@types |
./src/types |
import { nui } from "@lib/nui";
import { shows } from "@store/app";
import Button from "@components/atoms/Button.svelte";