Development

How to Keep Old Script Exports for Your New Script

Learn how to maintain backward compatibility when replacing existing FiveM scripts. Keep all dependent scripts working while using your improved system.

Meteo2025-07-138 min read
How to Keep Old Script Exports for Your New Script

Have you ever wanted to create your own custom script but worried about breaking all your other scripts that depend on an existing one? This guide shows you exactly how to keep old script exports working in your new script.

This method works for keeping any old script exports in your new scripts!

The Common Problemlink

Many servers use popular scripts that other resources depend on. Your scripts probably use exports like this:

descriptionlua
-- Your garage script using a fuel system
local fuel = exports['LegacyFuel']:GetFuel(vehicle)
exports['LegacyFuel']:SetFuel(vehicle, 100)

-- Your banking script using a phone system
exports['qb-phone']:SendMail(player, 'Bank Alert', 'Transfer completed')

-- Your job script using a notification system
exports['mythic_notify']:SendAlert('success', 'Job completed!')

-- Your vehicle script using a key system
exports['qb-vehiclekeys']:GiveKeys(player, plate)

But what happens when you want to use your own new script? If you stop using the old script, all these dependent scripts break with errors like:

descriptionlog
SCRIPT ERROR: No such export GetFuel in resource LegacyFuel
SCRIPT ERROR: No such export SendMail in resource qb-phone
SCRIPT ERROR: No such export SendAlert in resource mythic_notify

Now you have to manually edit every script that uses those exports to work with your new script. That's a lot of work!

The Solution: Keep Old Exports in Your New Scriptlink

FiveM has a special system that lets you keep old script exports in your new script. You can make all your existing scripts work with your new system without changing anything.

The Magic Patternlink

Here's the secret pattern that makes it work:

descriptionlua
local function exportHandler(exportName, func)
    AddEventHandler(('__cfx_export_LegacyFuel_%s'):format(exportName), function(setCB)
        setCB(func)
    end)
end

How it works:

  1. FiveM looks for exports using the pattern __cfx_export_ResourceName_ExportName
  2. When another script calls exports['LegacyFuel']:GetFuel(), FiveM triggers the event __cfx_export_LegacyFuel_GetFuel
  3. Your handler receives a setCB callback function
  4. You call setCB(yourFunction) to provide the actual function
  5. The calling script gets your function and everything works perfectly!

Complete Working Examplelink

Let's say you want to replace LegacyFuel with your own custom fuel system. Here's how to maintain compatibility:

descriptionlua
-- Put this in your new fuel resource (server.lua or client.lua)

-- Your new fuel functions
local function GetFuel(vehicle)
    -- Your custom fuel logic here
    return Entity(vehicle).state.fuel or 100
end

local function SetFuel(vehicle, amount)
    -- Your custom fuel logic here  
    Entity(vehicle).state.fuel = amount
    TriggerClientEvent('fuel:updateHUD', -1, vehicle, amount)
end

-- Legacy export handler for LegacyFuel compatibility
local function exportHandler(exportName, func)
    AddEventHandler(('__cfx_export_LegacyFuel_%s'):format(exportName), function(setCB)
        setCB(func)
    end)
end

-- Register the LegacyFuel exports that other scripts expect
exportHandler('GetFuel', GetFuel)
exportHandler('SetFuel', SetFuel)

-- Optional: Support alternative export names some scripts might use
exportHandler('GetVehicleFuelLevel', GetFuel)
exportHandler('SetVehicleFuelLevel', SetFuel)

-- You can also provide modern exports for new scripts
exports('GetFuel', GetFuel)
exports('SetFuel', SetFuel)

Supporting Multiple Scripts at Oncelink

You can also create one new script that replaces multiple old scripts. Here's an example for replacing both qb-management and qb-banking with your own system:

descriptionlua
-- Your new banking/management functions
local function AddMoney(source, account, amount)
    -- Your custom banking logic here
    print('Adding money:', source, account, amount)
end

local function RemoveMoney(source, account, amount)
    -- Your custom banking logic here
    print('Removing money:', source, account, amount)
end

local function GetAccount(source, account)
    -- Your custom account logic here
    return {balance = 5000, name = account}
end

local function GetAccountBalance(source, account)
    -- Your custom balance logic here
    return 5000
end

-- Export handler that supports multiple script names
local function exportHandler(exportName, func)
    for _, scriptName in ipairs({'qb-management', 'qb-banking'}) do
        AddEventHandler(('__cfx_export_%s_%s'):format(scriptName, exportName), function(setCB)
            setCB(func)
        end)
    end
end

-- Register exports for both old scripts
exportHandler('AddMoney', AddMoney)
exportHandler('AddGangMoney', AddMoney)
exportHandler('RemoveMoney', RemoveMoney)
exportHandler('RemoveGangMoney', RemoveMoney)
exportHandler('GetAccount', GetAccount)
exportHandler('GetGangAccount', GetAccount)
exportHandler('GetAccountBalance', GetAccountBalance)

Now your single script handles exports from both qb-management and qb-banking!

Real-World LegacyFuel Replacementlink

Based on the actual LegacyFuel exports, here's a complete replacement that maintains 100% compatibility:

descriptionlua
-- client.lua in your new fuel resource

-- Your improved fuel system
local vehicleFuel = {}

function GetFuel(vehicle)
    if not DoesEntityExist(vehicle) then return 0 end
    
    local plate = GetVehicleNumberPlateText(vehicle)
    if vehicleFuel[plate] then
        return vehicleFuel[plate]
    end
    
    -- Get from entity state or default
    return Entity(vehicle).state.fuel or 65
end

function SetFuel(vehicle, amount)
    if not DoesEntityExist(vehicle) then return end
    
    local plate = GetVehicleNumberPlateText(vehicle)
    amount = math.max(0, math.min(100, amount)) -- Clamp between 0-100
    
    vehicleFuel[plate] = amount
    Entity(vehicle).state.fuel = amount
    
    -- Update your custom HUD here
    TriggerEvent('yourfuel:updateDisplay', vehicle, amount)
end

-- Legacy export compatibility for LegacyFuel
local function legacyExportHandler(exportName, func)
    AddEventHandler(('__cfx_export_LegacyFuel_%s'):format(exportName), function(setCB)
        setCB(func)
    end)
end

-- Register LegacyFuel exports for backward compatibility
legacyExportHandler('GetFuel', GetFuel)
legacyExportHandler('SetFuel', SetFuel)

-- Modern exports for new scripts
exports('GetFuel', GetFuel)
exports('SetFuel', SetFuel)

Testing Your Legacy Exportslink

After setting up legacy exports, test them with this simple script:

descriptionlua
-- Test script to verify legacy exports work
RegisterCommand('testfuel', function()
    local ped = PlayerPedId()
    local vehicle = GetVehiclePedIsIn(ped, false)
    
    if vehicle == 0 then
        print('Get in a vehicle first')
        return
    end
    
    -- Test getting fuel (works even though you replaced LegacyFuel)
    local fuel = exports['LegacyFuel']:GetFuel(vehicle)
    print('Current fuel:', fuel)
    
    -- Test setting fuel
    exports['LegacyFuel']:SetFuel(vehicle, 75)
    print('Set fuel to 75')
    
    -- Verify it worked
    local newFuel = exports['LegacyFuel']:GetFuel(vehicle)
    print('New fuel level:', newFuel)
end)

Common Issues and Solutionslink

"No such export" errors still happening:

  • Make sure your legacy export resource starts before other resources
  • Check the export names match exactly (case-sensitive)
  • Verify you're using the correct resource name in the event pattern

Scripts not finding the exports:

  • Ensure dependencies in your fxmanifest.lua are correct
  • Start your legacy export resource early in server.cfg
  • Check that other resources start after your compatibility resource

Performance concerns:

  • Legacy exports have minimal performance impact
  • They only trigger when actually called
  • Much better than running the original heavy script

Why This Method is Superiorlink

Compared to editing every script:

  • No need to modify existing scripts
  • Scripts continue working exactly as before
  • Easy to maintain and update
  • Can support multiple naming conventions

Compared to keeping the old script:

  • Better performance with your optimized code
  • Modern features and security
  • Easier to customize and maintain
  • Backward compatibility without the bloat

Best Practiceslink

  1. Start early in server.cfg - Put your compatibility resource before other resources
  2. Document your exports - List what legacy exports you support
  3. Test thoroughly - Verify all dependent scripts still work
  4. Keep it simple - Don't overcomplicate the compatibility layer
  5. Plan for deprecation - Eventually migrate scripts to use modern exports

Conclusionlink

Using the __cfx_export_ pattern lets you have the best of both worlds: modern, optimized scripts with full backward compatibility. You can replace LegacyFuel (or any script) with a better system while keeping all your existing scripts working perfectly.

This method saves hours of manual script editing and prevents frustrating compatibility issues. It's a professional solution that many successful FiveM servers use.

Remember: The key is the exact pattern __cfx_export_ResourceName_ExportName - get this right and everything else is easy!

Sourceslink

FiveMScriptingExportsCompatibilityDevelopmentTutorial
Share

Have questions about this post?

Ask on Discord