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

xray16

v2.0.3

Published

TypeScript declarations, mocks, helpers, and TypeScriptToLua plugins for XRF X-Ray 16 scripts.

Readme

XRF X-Ray 16 SDK

npm version sdk book Node.js CI

xray16 provides TypeScript declarations, test helpers, and TypeScriptToLua plugins for Lua-visible X-Ray 16 APIs. Use it when compiling XRF game scripts from TypeScript, including with stalker-xrf-engine.

X-Ray 16 engine API documents game globals, luabind classes, UI and GOAP classes, and script objects.

Quick start

Install the SDK and its required TypeScriptToLua peer dependency:

npm install xray16 typescript-to-lua

typescript-to-lua is the only required peer dependency. jest, ts-jest, and typescript are optional peers for xray16/testing. The fengari and ini dependencies required by xray16/mocks install automatically.

Add the base declarations to compilerOptions.types. Include only the ambient typedef packages your project uses.

{
  "compilerOptions": {
    "types": [
      "@typescript-to-lua/language-extensions",
      "xray16",
      "xray16/typedefs/extensions",
      "xray16/typedefs/luajit",
    ],
  },
}

For an unreleased build, install xray16@experimental from npm, or use the rolling nightly GitHub release:

npm install https://github.com/xray-forge/stalker-xrf-xray16-sdk/releases/download/nightly/xray16-nightly.tgz

Entry points

| Import | Use it for | | ------------------- | ------------------------------------------------------------------------- | | xray16 | Engine globals, luabind classes, UI and GOAP classes, and script objects. | | xray16/alias | Readable aliases for engine declaration names and virtual engine enums. | | xray16/macros | Compile-time helpers with a Node/Jest fallback. | | xray16/lib | Shared aliases, constants, and small runtime helpers. | | xray16/testing | Jest configuration and setup helpers. | | xray16/mocks | Lua-like runtime helpers for Node-based tests. | | xray16/typedefs/* | Opt-in ambient declarations for X-Ray and bundled Lua libraries. | | xray16/plugins/* | TypeScriptToLua build plugins. |

Engine types and aliases

Import from xray16 when you want names that match the Lua binding dump.

import { game_object, level } from "xray16";

export function isActorVisible(object: game_object): boolean {
  return object.see(level.get_target_obj());
}

Use xray16/alias when application code benefits from shorter more Typescript-friendly names.

import type { GameObject, ServerObject, Vector } from "xray16/alias";

export interface SpawnPoint {
  object: ServerObject;
  position: Vector;
  owner: GameObject;
}

Aliases erase at build time. Virtual enums are folded by the inline plugin in game builds; Jest and Node can import their runtime objects from alias.js.

Macros and shared helpers

Use macros for code that should fold during compilation but still run under Jest or Node.

import { $filename, $fromObject, $isNil } from "xray16/macros";

export function readConfig(value: unknown): LuaTable<string, string> {
  if ($isNil(value)) {
    return $fromObject({ source: $filename });
  }

  return $fromObject(value as Record<string, string>);
}

The macros plugin removes the import and folds helper usage in game builds. The shipped runtime module supports the same imports under Jest and Node.

xray16/lib provides shared aliases, constants, and utility helpers:

import { MAX_U16, clamp, type TSection } from "xray16/lib";

export function normalizeSection(section: TSection, value: number): string {
  return `${section}:${clamp(value, 0, MAX_U16)}`;
}

Type aliases erase at build time, and @inline constants can be folded by the inline plugin. Runtime helpers such as round and range need a Lua module in game builds; enable libcompile when compiling gamedata from xray16/lib source.

Test X-Ray code under Node

createJestConfig() returns a ts-jest configuration that maps bare xray16 imports to the SDK runtime stand-in.

// jest.config.js
const { createJestConfig } = require("xray16/testing");

module.exports = createJestConfig({
  roots: ["<rootDir>/src"],
  moduleNameMapper: { "^@/(.*)": "<rootDir>/src/$1" },
});

It installs Lua-like globals and the xray16 module mock before each test file, then registers Jest matchers such as toBeNil, toEqualLuaTables, and toEqualLuaArrays. Add xray16/typedefs/jest to compilerOptions.types to type-check those matchers.

Consumer moduleNameMapper entries override SDK entries. Consumer setupFiles and setupFilesAfterEnv entries run after the SDK setup; other top-level options replace their defaults.

For a custom setup, call setupLuaGlobals() from xray16/testing. Import setupXrayRuntime() only from a Jest setup file or test setup module because it eagerly loads the mock runtime and calls jest.mock.

import { setupLuaGlobals } from "xray16/testing";
import { setupXrayRuntime } from "xray16/testing/setup-xray-runtime";

setupLuaGlobals();
setupXrayRuntime({
  editor: jest.fn(() => true),
});

Jest mock helpers are available from xray16/testing/utils:

import { replaceFunctionMock, resetFunctionMock } from "xray16/testing/utils";

Ambient typedefs

Ambient typedefs describe X-Ray globals and bundled Lua libraries. They are not modules to import; add them to compilerOptions.types or reference them with /// <reference types="..." />.

| Typedef | Provides | | ---------------------------- | ------------------------------------------------------------------------------------------------------------- | | xray16/typedefs/extensions | OpenXRay table and string extensions, including table.random, table.size, and string.trim variants. | | xray16/typedefs/luajit | LuaJIT globals and methods missing from the default TSTL typings. | | xray16/typedefs/lfs | LuaFileSystem (lfs). | | xray16/typedefs/marshal | marshal serialization helpers. | | xray16/typedefs/jest | Types for the custom Jest matchers. |

TypeScriptToLua plugins

Plugins are opt-in. An XRF build that needs every SDK transformation enables them in this order:

{
  "tstl": {
    "luaPlugins": [
      { "name": "xray16/plugins/luabind" },
      { "name": "xray16/plugins/strip" },
      { "name": "xray16/plugins/macros" },
      { "name": "xray16/plugins/optimize" },
      { "name": "xray16/plugins/inline" },
      { "name": "xray16/plugins/libcompile" },
      { "name": "xray16/plugins/tracy" },
    ],
  },
}

| Plugin | Purpose | | ------------------------------------------ | ----------------------------------------------------------------------------- | | luabind | Emits class("Name") declarations for @LuabindClass() classes. | | strip | Removes Lua logger calls and runtime imports for engine-only typedef modules. | | macros | Folds filename, dirname, nil-check, cast, and build-header helpers. | | optimize | Rewrites returned ternaries into direct Lua if / else returns. | | inline | Inlines tagged constants, functions, and $inline / $noInline hints. | | libcompile | Emits xray16/lib source as a flat xray_bundle module. | | tracy | Injects Tracy profiler zones when enabled. |

When their config fields are unset, strip.luaLogger falls back to XR_NO_LUA_LOGS=true or --no-lua-logs, and tracy.enabled falls back to XR_INJECT_TRACY_ZONES=true or --inject-tracy-zones.

Classes that extend C++ objects need luabind registration rather than default TypeScriptToLua prototype output:

import { LuabindClass, object_binder } from "xray16";

@LuabindClass()
export class ActorBinder extends object_binder {
  public override net_spawn(object: unknown): boolean {
    return super.net_spawn(object);
  }
}

See the luabind plugin README for constructor and inheritance rules.

API documentation and development

The documentation website is available at xray-forge.github.io/stalker-xrf-xray16-sdk — guides, plugin pages, and a generated API reference per package surface. Declarations describe the TypeScript-visible API shape; C++ engine bindings define runtime behavior. Check the engine source when declaration syntax is ambiguous.

To refresh local binding dumps, run the game engine with -dump_bindings, open the generated scriptbindings_*.txt files in the user data directory, and compare them with this package's declarations.

Useful package scripts:

npm run typecheck
npm run lint
npm run test
npm run build
npm run docs

npm run build stages the publishable package in target/pkg/xray16; npm run docs builds the VitePress website (with TypeDoc API sections) into target/docs, and npm run docs:dev serves it locally. Website content lives in docs/, build and tooling configuration in cli/, and the published manifest is src/package.json.