zephyr_garages
zephyr_garages is a full-featured, multi-garage vehicle management resource for FiveM. It handles both personal vehicle storage and job-based vehicle spawners in a single unified system, with a React NUI interface, vehicle preview cameras, folder organisation, towing, and runtime-configurable garages.
| Version | 2.0.0 |
| Author | Zephyr Development |
| Framework | QBX / QBCore |
| UI | React + Vite (lation_ui) |
Features
| Feature | Description |
|---|---|
| Personal Garages | Players access their own owned vehicles, filtered by type (car, air, sea, or all). Vehicles track state: GARAGED, OUT, or IMPOUNDED. |
| Vehicle Spawner | Garages can be configured as spawners — a grade-gated list of job vehicles (e.g. police fleet). Spawned vehicles are not persisted; they are generated fresh each time with preset plate, livery, extras, and full mods. |
| Depot / Impound | Garages with type = 'depot' hold impounded vehicles. Players pay a release fee (configurable as a % of vehicle value) to retrieve them. |
| Vehicle Preview | Before spawning or pulling out a vehicle, players can enter a 3D preview mode with an orbiting camera. The camera supports zoom, pitch, and free rotation. The preview times out after a configurable duration. |
| Favourites | Players can mark vehicles as favourites. Favourited vehicles appear first in the list. |
| Player Folders | Players can create up to 20 custom folders to organise their vehicles. Folders are named, reordered, and persisted per character. |
| Division / Job Folders | Config-defined vehicle folders (e.g. SWAT, CID, HWY) are displayed only to officers assigned to that division via statebags. Division access is checked against zephyr_police or the zp_division statebag. |
| Towing | Players can tow a vehicle to a different garage from the UI. A cooldown (default 120 s) and optional fee (default $3,000) apply. Towed vehicles are locked during the cooldown period. |
| Vehicle Transfer | Players can transfer ownership of a vehicle to another nearby player (configurable radius). A blacklist prevents transfers of high-value/exotic vehicles. |
| Boot Contents | View the ox_inventory boot/trunk contents of a garaged vehicle directly from the garage UI without spawning it. |
| Access Control | Garages support job/group restrictions, grade requirements, and runtime-injectable allowedIdentifiers for fine-grained access. |
| Blips & Markers | Each access point can define a map blip and a ground marker drawn at the interaction zone. |
| Runtime Registration | Other resources can register or update garages at runtime via the RegisterGarage export without restarting. |
Dependencies
| Resource | Required | Notes |
|---|---|---|
ox_lib | ✅ Yes | Callbacks, locale, progress bars |
oxmysql | ✅ Yes | Vehicle and folder persistence |
qbx_core | ✅ Yes | Player data, vehicle records |
qbx_vehicles | ✅ Yes | Vehicle catalog (brand, name, price) |
lation_ui | ✅ Yes | NUI rendering layer |
Configuration
Shared (config/shared.lua)
| Option | Type | Description |
|---|---|---|
towCooldown | number | Seconds between tow actions per player (default: 120) |
towCost | number | Money deducted per tow action (default: 3000) |
transferSearchRadius | number | Max distance in metres to find a transfer target player (default: 50) |
vehicleFolders | table | Division/job-based folder definitions — see below |
vehicleFolderOtherLabel | string | Label for vehicles not matching any folder (default: "Other") |
transferBlacklist | table | Model names that cannot be transferred between players |
Vehicle folder definition:
vehicleFolders = {
{ id = 'swat', label = 'SWAT', jobs = { 'police' }, models = { 'bearcatrbstairs', 'pvalk' } },
{ id = 'hwy', label = 'HWY', jobs = { 'police' }, models = { 'c3bike', 'ppgjv' } },
}Client (config/client.lua)
| Option | Type | Description |
|---|---|---|
enableClient | boolean | Master switch — set to false to disable all client-side logic |
engineOn | boolean | Whether the engine starts when a vehicle is spawned |
previewDuration | number | Preview timeout in milliseconds (default: 30000) |
previewCam.radius | number | Initial camera orbit radius |
previewCam.rotateSpeed | number | Camera rotation speed (degrees/sec) |
Server (config/server.lua)
| Option | Type | Description |
|---|---|---|
autoRespawn | boolean | Automatically respawn vehicles that are still OUT when the server restarts |
warpInVehicle | boolean | Warp the player into the spawned vehicle |
doorsLocked | boolean | Lock vehicle doors on spawn |
distanceCheck | number | Distance in metres used to check for blocking vehicles at spawn points |
calculateImpoundFee | function | Returns the depot release fee for a given vehicle ID and model name |
garages | table | Garage definitions — see below |
Garage definition
garages = {
downtown = {
label = 'Downtown',
vehicleType = VehicleType.CAR, -- CAR | AIR | SEA | ALL
-- type = GarageType.DEPOT, -- omit for normal garage; set to DEPOT for impound
accessPoints = {
{
blip = { name = 'Public Parking', sprite = 357, color = 44 },
coords = vec4(216.23, -809.93, 30.73, 164.08),
spawn = vec4(228.87, -801.30, 30.65, 164.08),
-- spawn can also be a table of vec4 for multiple candidates
},
},
},
-- Job spawner example:
mrpd = {
label = 'MRPD',
vehicleType = VehicleType.CAR,
groups = 'police', -- job restriction
spawnerVehicles = { 'poracle', 'ps790', 'pzenith' },
spawnerVehicleConfigs = {
poracle = { minJobGrade = 1, livery = 1, extras = { 1, 2, 3 } },
},
accessPoints = { ... },
},
}