Skip to content

Contributing

Josh Bowden edited this page Mar 25, 2026 · 4 revisions

Thanks for your interest in contributing to FXCommands. This guide covers the development setup, project structure, and contribution workflow.


Prerequisites

  • Node.js 20+
  • Stream Deck 6.9+
  • A physical Stream Deck (or the Stream Deck emulator) for testing

Setup

git clone https://github.com/josh-tf/fxcommands.git
cd fxcommands
npm install

Project Structure

src/
  plugin.ts                 # Entry point - registers the action
  connection-manager.ts     # TCP/CMND protocol handler
  actions/
    fx-command.ts           # Main action logic (state machine, delays)

tf.josh.fxcommands.sdPlugin/
  manifest.json             # Plugin metadata and configuration
  ui/
    PluginActionPI.html     # Property Inspector UI
    PluginActionPI.js       # Settings persistence
    sdpi.css                # Elgato styling
  imgs/                     # Button icons (various states/DPI)

tools/
  fivem-emulator.cjs        # Local testing emulator

Building

npm run build

This runs the full build pipeline:

  1. Cleans dist/
  2. Copies the plugin assets
  3. Bundles TypeScript via Rollup into bin/plugin.js
  4. Packages the .streamDeckPlugin installer file

Output:

  • dist/tf.josh.fxcommands.sdPlugin/ - unpacked plugin
  • dist/tf.josh.fxcommands.streamDeckPlugin - installable package

Watch mode

For development, use watch mode to auto-rebuild on changes:

npm run watch

Code Quality

Run all checks at once:

npm run check

Or individually:

Command What it does
npm run typecheck TypeScript type checking
npm run lint ESLint
npm run format Prettier formatting
npm run spell cspell spell checking
npm run circular Circular dependency detection (madge)
npm run unused Unused dependency/export detection (knip)

All checks must pass before submitting a PR. The CI pipeline runs npm run check && npm run build on every push.


Testing with the FiveM Emulator

Since you likely don't want to run FiveM every time you test, the project includes a local emulator that mimics the FiveM console server.

node tools/fivem-emulator.cjs

This starts a TCP server on localhost:29200 that:

  • Accepts CMND protocol connections
  • Decodes incoming command frames
  • Prints received commands with colour-coded output

Use this alongside Stream Deck to test your changes without needing the game running.


Making Changes

Branching

  • Create a feature branch from main
  • Use descriptive branch names: fix/connection-timeout, feat/custom-port

Code style

  • TypeScript with strict mode
  • Tabs for indentation
  • 120 character line width
  • Follow existing patterns in the codebase

Commit messages

Use conventional commits:

feat: add custom port configuration
fix: handle connection timeout on slow networks
docs: update delay syntax examples
chore: bump dependencies

Pull Requests

  1. Ensure all checks pass: npm run check && npm run build
  2. Test your changes with the FiveM emulator or a live game
  3. Open a PR against main
  4. Describe what changed and why

Releases

Releases are automated via CI. When a version change in package.json is pushed to main:

  1. CI detects the version bump
  2. Creates a git tag
  3. Builds the plugin
  4. Creates a draft GitHub Release with the .streamDeckPlugin file attached

Use the release script for version bumps:

npm run release

See Also

Clone this wiki locally