# XSplit JS Framework
> **Package rename:** maintained releases now publish as
> `@splitmedialabs/xjs`. The old `xjs-framework` npm package is kept for
> historical releases; `2.10.2` remains its final published release.
The XSplit JS Framework is the JavaScript/TypeScript library used to build
extensions and plugins for XSplit Broadcaster. This repository contains the
runtime API wrappers, browser bundles, generated type declarations, examples,
XSplit CEF regression harnesses, and the documentation site for the package.
The package keeps the existing public API stable while the project moves away
from Bower, Gulp, Browserify, and the legacy Angular/Dgeni docs stack.
## Repository Contents
- `src/` contains the TypeScript source for the stable XJS runtime API.
- `dist/` contains generated package output. Modern bundles are ignored and
regenerated by `npm run build`; the deprecated `xjs-es2015` compatibility
bundles remain tracked during the transition.
- `examples/` contains the local examples server and the XSplit regression
extension served on port `3999`.
- `docs/` contains the new Astro/Starlight documentation site.
- `docs-old/` preserves the legacy Angular/Dgeni docs stack as migration
reference.
- `test/smoke/` contains modern smoke and migration guard tests.
- `scripts/` contains build, docs, CDP, and maintenance automation.
- `artifacts/` is generated locally for CDP runs and is intentionally ignored.
## Development Requirements
- Node.js `22.20.0` is the expected runtime. The package requires
`node >=22.12.0`.
- npm is used for dependency installation and scripts.
- XSplit Broadcaster on Windows is required for host integration testing.
- XSplit's CEF remote debugging endpoint is expected at
`http://127.0.0.1:9222`.
- Git and OpenSSH are needed for cross-machine testing from macOS/Linux to a
Windows XSplit client.
Volta is the easiest way to pin Node consistently because this repository
declares the desired version in `package.json`.
```sh
volta install node@22.20.0
npm ci
npm run build
```
If you do not use Volta, install a compatible Node 22 runtime with your
platform's normal version manager.
## Platform Setup
### Windows
Install these tools:
- Git for Windows, including Git Bash or another shell with OpenSSH.
- Node.js 22.20.0, preferably through Volta for Windows.
- XSplit Broadcaster for CEF/host regression testing.
Then initialize the repository:
```powershell
git clone https://github.com/SplitmediaLabsLimited/xjs.git
cd xjs
volta install node@22.20.0
npm ci
npm run build
```
Run the examples server locally when testing inside XSplit:
```powershell
npm run examples
```
The extension URL is:
```text
http://localhost:3999/xsplit-extension/index.html
```
### macOS
Install Git, Volta or another Node 22 version manager, and npm. XSplit
Broadcaster itself is Windows-only, so macOS can run package/docs tests locally
and use SSH forwarding to test against a remote Windows host.
```sh
git clone https://github.com/SplitmediaLabsLimited/xjs.git
cd xjs
volta install node@22.20.0
npm ci
npm run build
```
### Linux
Install Git, OpenSSH, Volta or another Node 22 version manager, and npm. Linux
can run package/docs tests locally and use SSH forwarding to test against a
remote Windows XSplit host.
```sh
git clone https://github.com/SplitmediaLabsLimited/xjs.git
cd xjs
volta install node@22.20.0
npm ci
npm run build
```
## Cross-OS XSplit Testing
The examples server always listens on port `3999`:
```sh
npm run examples
```
When the repo is on macOS/Linux and XSplit Broadcaster is on a Windows machine,
make the local examples server available to Windows through a reverse SSH
tunnel. This keeps the extension URL as `localhost:3999` from XSplit's
perspective:
```sh
ssh -N \
-R '127.0.0.1:3999:127.0.0.1:3999' \
ensu-win
```
Then attach XSplit Broadcaster to:
```text
http://localhost:3999/xsplit-extension/index.html
```
If `localhost:3999` is not suitable, pass an explicit URL that the Windows CEF
process can reach:
```sh
XJS_EXTENSION_NAVIGATE_URL=http://<reachable-host>:3999/xsplit-extension/index.html npm run test:xsplit:cdp:attached
```
The CDP runners connect to `http://127.0.0.1:9222` by default. Override that
when the remote debugging endpoint is forwarded differently:
```sh
XJS_CDP_BASE=http://127.0.0.1:9222 npm run test:xsplit:cdp
```
## Common Workflows
Build the package:
```sh
npm run build
```
Serve examples and the XSplit regression extension:
```sh
npm run examples
```
Run the default smoke suite:
```sh
npm test
```
Run the modern smoke suite plus the focused CEF compatibility contract:
```sh
npm run test:full
```
Validate the package tarball before publishing:
```sh
npm run pack:check
```
## XSplit CEF Regression
Use the raw CDP runner when the XSplit extension page is already open:
```sh
npm run test:xsplit:cdp
```
Use the attached runner when CDP is reachable but the active CEF target needs
to be navigated to the local extension:
```sh
npm run test:xsplit:cdp:attached
```
Each run writes timestamped artifacts under `artifacts/xsplit-cdp/` and updates
`artifacts/xsplit-cdp/latest-summary.json` with pass/fail state, browser
metadata, console diagnostics, network failures, and screenshot metadata.
The CEF path is intentionally raw-CDP first because the XSplit host currently
targets CEF 103. Playwright remains useful for normal browser checks, but the
host regression path should not depend on Playwright compatibility with that
CEF version.
## Component Fixture Screenshots
The docs component pages use the same fixture metadata as the XSplit extension
and regression runner.
Capture component fixtures through the XSplit/CEF CDP target:
```sh
npm run docs:components:capture
```
This writes local artifacts under `artifacts/component-fixtures/`.
Update the documentation screenshots from a fresh CEF capture:
```sh
npm run docs:components:update
```
That command:
1. Captures each fixture through `component-capture.html`.
2. Copies screenshots into `docs/public/component-fixtures/`.
3. Updates `docs/src/assets/component-fixtures.json`.
4. Runs `npm run docs:check`.
The generated screenshots and manifest are committed because they are part of
the rendered documentation site. The timestamped `artifacts/` source captures
are local only.
## Documentation
Run the new Starlight docs site locally:
```sh
npm run docs:dev
```
Build the new static documentation site into `dist/docs`:
```sh
npm run docs:build
```
Validate docs fixture links, Biome errors for active docs source, and Markdown
formatting:
```sh
npm run docs:check
```
Build the preserved legacy docs output when needed:
```sh
npm run docs:legacy:build
```
The legacy docs stack is kept under `docs-old/` for reference while Starlight
reaches parity. Do not restore Bower, Dgeni, Broccoli, Traceur, or the old
generator workflow as active dependencies.
## Tooling Reference
- Vite builds the ESM, CommonJS, and browser bundles.
- TypeScript 6 generates type declarations and keeps the source ready for the
future TS-go migration path.
- Astro/Starlight builds the new docs site.
- `starlight-typedoc`, TypeDoc, and `typedoc-plugin-markdown` generate API and
contributor reference pages.
- Biome is used for active source/docs checks, currently with an error-focused
gate.
- rumdl checks and formats Markdown/MDX docs content.
- Web Test Runner covers modern component tests.
- The old Karma/Jasmine unit-test files and config remain in the tree as
historical reference, but the runner tooling is no longer installed. Prefer
the modern smoke, component, and CDP tests for active maintenance.
- Raw CDP over `localhost:9222` is used for XSplit-hosted CEF regression.
## Release build notes
The modern package name is `@splitmedialabs/xjs`. The historical npm package,
`xjs-framework`, remains the compatibility package for already-published
versions such as `2.10.2`. New modernization releases should be published under
`@splitmedialabs/xjs`.
The intended registry transition is:
1. Keep `xjs-framework@2.10.2` as the final published old-package release.
2. Publish `@splitmedialabs/xjs@2.14.1` from the modernized branch.
3. Add an npm deprecation notice to `xjs-framework@<=2.10.2` pointing users to
`@splitmedialabs/xjs`.
Keep the browser bundle loader name `require('xjs')` unchanged for XSplit-hosted
script usage; that name is a bundle shim, not the npm package name.
Generated modern package artifacts are intentionally ignored by git. Run
`npm run build` before any local package validation or publish flow. The build
regenerates:
- `dist/xjs.mjs`
- `dist/xjs.cjs`
- `dist/xjs.js`
- `dist/xjs.min.js`
- `dist/index.d.ts`
- declaration files under `dist/`
Use `npm run pack:check` before publishing. The package `prepare` lifecycle
runs the build first, then `npm pack --dry-run` verifies the package tarball.
The same `prepare` hook runs for `npm publish` and npm git dependencies, so the
ignored modern `dist/` output is regenerated before the tarball is assembled.
Only the deprecated compatibility bundles `dist/xjs-es2015.js` and
`dist/xjs-es2015.min.js` remain tracked during the transition.
## Migration Notes
See [MIGRATION.md](MIGRATION.md) for the active modernization migration plan.
[BACKLOG.md](BACKLOG.md) tracks deferred follow-up work.
The main constraint for this branch is API stability. Tooling, docs, tests, and
build output can modernize, but existing public runtime APIs and package export
names should not change during this migration.
## Contributing
If you wish to contribute, check the
[issue list](https://github.com/xjsframework/xjs/issues). Drop a comment if you
need more information before you start working on a pull request. Information
on the deliverable roadmap is posted on the
[wiki](https://github.com/xjsframework/xjs/wiki).