Contributions are welcome, especially around new bridges, bug fixes and quality-of-life improvements.
What kind of contributions make sense?
-
New bridges
- Support for another framework or a fork (
qbcorefork, custom ESX build, etc.). - Support for another garage system.
- Support for another keys system.
- Support for another framework or a fork (
-
Improvements to existing bridges
- More robust error handling and input validation.
- Better logging when a dependency is missing or misconfigured.
- Small performance or DB optimizations that don’t change behavior.
-
Core utilities
- Additional, generic helpers that are clearly reusable across several scripts.
- Documentation improvements and example code.
Design principles
-
Single responsibility
- TS-Lib should stay small and focused. It is not a framework and it does not try to replace your existing utility libraries.
-
Bridges first
- Framework-specific logic should live inside:
Bridge.Framework.*Bridge.Garages.*Bridge.VehicleKeys.*
- Framework-specific logic should live inside:
-
Configuration driven
- New integrations should be made configurable via
ts-lib/config.lua:- Add a new key in
Config.Data.Framework,Config.Data.GaragesorConfig.Data.VehicleKeys. - Do not hardcode resource names outside of this config.
- Add a new key in
- New integrations should be made configurable via
-
Safe failure
- If a target resource is not started or misconfigured:
- Log clearly with
TS.ErrorPrint. - Fail gracefully instead of crashing other scripts.
- Log clearly with
- If a target resource is not started or misconfigured:
Adding a new bridge (high level)
-
Extend the config
Edit
ts-lib/config.luaand add your new option:Or for frameworks / keys, useConfig.Data.Framework/Config.Data.VehicleKeys. -
Create the bridge files
Follow the existing structure:
- Frameworks:
shared/bridge/framework/<name>/shared.lua|client.lua|server.lua - Garages:
shared/bridge/garages/<name>/shared.lua|client.lua|server.lua - Keys:
shared/bridge/vehiclekeys/<name>/shared.lua|client.lua|server.lua
- Frameworks:
-
Implement the required functions
-
For a garage:
Bridge.Garages.Server.Functions.IsVehicleOwned(plate, netId?)Bridge.Garages.Server.Functions.SetVehicleOutsideState(plate, state)
-
For vehicle keys:
Bridge.VehicleKeys.Client.Functions.SetDoorStatus(entity, lockStatus)
-
For frameworks:
- See Framework Bridge for the expected surface.
-
For a garage:
-
Guard against missing resources
- Use
TS.Utils.IsRessourceLoaded(or FiveM native checks) before calling into other resources. - Log helpful messages if something is not started or misconfigured.
- Use
-
Update the docs
- Add your bridge to the relevant “Supported systems” section.
- Update the “Status & testing” table with its initial state (likely
Experimental) and, if relevant, your nickname.
Workflow for pull requests
- Fork the TS-Lib repository on GitHub.
- Create a feature branch with a clear name (for example
feat/my-garage-bridgeorfix/esx-owner-query). - Implement your changes:
- Keep them focused and reasonably small.
- Avoid unrelated refactors in the same PR.
- Test on at least one real framework / garage / keys combination.
- Open a pull request:
- Describe the problem you’re solving and the approach.
- List the external resources involved (names + versions if possible).
- Link to any relevant logs or screenshots.
Reporting bugs & requesting features
-
Bugs
- Include:
- OS (Windows / Linux), framework and main scripts used.
- Exact console / F8 errors.
- Steps to reproduce and, if possible, a small reproduction.
- Include:
-
Feature requests
- Focus on the use case (for example, “I want to support X garage system”) rather than a specific function name.
- Often the best solution is a small, generic helper that works for several scripts.