ScriptsAboutBlogToolsKnowledge BaseReviewsFAQBasketDocsSupport
Comparisons

ox_target vs qb-target: Should You Switch?

Targeting systems โ€” the "look at something and interact" mechanic โ€” are core to modern FiveM roleplay. The two main options are ox_target and qb-target. This guide covers how they differ in practice, what the API migration actually looks like, and when switching is and isn't worth it.

What a target system does

A target system gives players an interaction cursor they aim at objects, entities, or zones to interact โ€” open a door, access a trunk, talk to an NPC, open a shop. It replaces the older "walk to an invisible marker and press E" approach with something more precise and much easier to discover.

Both scripts solve the same problem. The differences are in the API, the performance profile, and which one the rest of your resources expect.

The API difference, in code

This is the part that decides how much a migration costs, so it's worth seeing side by side.

qb-target โ€” adding a box zone:

exports['qb-target']:AddBoxZone("bank_teller", vector3(150.2, -1040.5, 29.4), 1.5, 2.0, {
    name = "bank_teller",
    heading = 340.0,
    debugPoly = false,
    minZ = 28.4,
    maxZ = 30.4,
}, {
    options = {
        {
            type = "client",
            event = "myscript:openBank",
            icon = "fas fa-university",
            label = "Access Bank",
            job = "banker",
        },
    },
    distance = 2.0,
})

ox_target โ€” the same zone:

exports.ox_target:addBoxZone({
    coords = vec3(150.2, -1040.5, 29.4),
    size = vec3(2.0, 1.5, 2.0),
    rotation = 340.0,
    debug = false,
    options = {
        {
            name = 'bank_teller',
            icon = 'fas fa-university',
            label = 'Access Bank',
            groups = 'banker',
            distance = 2.0,
            onSelect = function()
                TriggerEvent('myscript:openBank')
            end,
        },
    },
})

Same outcome, different shape. The practical differences:

  • One options table, not two. qb-target splits configuration between a zone table and a target-options table. ox_target uses a single flat table.
  • `onSelect` instead of `event`. ox_target prefers a callback, which means you can keep the logic inline rather than round-tripping through an event. It still accepts event and serverEvent when you want them.
  • `groups` instead of `job`. ox_target's groups handles jobs and gangs through one field, and accepts a table with minimum grades.
  • `size` as a vec3 instead of length/width/minZ/maxZ. Height is part of the size vector rather than two separate Z bounds.
  • Zone IDs are returned. addBoxZone returns an ID you pass to removeZone, instead of removing by string name.

Rough API mapping

If you are converting a resource, this covers most of what you will hit:

| qb-target | ox_target | |---|---| | AddBoxZone | addBoxZone | | AddCircleZone | addSphereZone | | AddTargetModel | addModel | | AddTargetEntity | addLocalEntity | | AddGlobalVehicle | addGlobalVehicle | | AddGlobalPed | addGlobalPed | | RemoveZone(name) | removeZone(id) | | options.job | options.groups | | options.event | options.onSelect / options.event | | canInteract(entity, distance, data) | canInteract(entity, distance, coords, name, bone) |

Check canInteract carefully โ€” the signatures differ, and a callback that silently receives the wrong arguments produces an option that never shows up, with no error in the console.

The compatibility layer

ox_target ships with an optional qb-target compatibility shim that registers the old export names and forwards them. That means a resource written for qb-target can often run without edits.

Treat this as a migration aid, not a destination. It gets an established server moving without a weekend of rewrites, but you are running a translation layer on every call, and edge cases โ€” particularly around canInteract and job checks โ€” do not always survive the trip. Convert resources properly as you touch them. Verify the current shim behaviour against the ox_target docs for the version you install, since this has changed across releases.

Performance

Target systems are a common hidden performance cost because they run checks every frame while the player is aiming.

Do not take anyone's word for it, including this page. Measure on your own server:

resmon 1

Watch the target resource while a player is aiming at a busy area โ€” a bank, a vehicle spawn, a crowded market. What matters is the cost when the system is actively resolving options, not the idle number.

What you are looking for:

  • Idle cost should be near zero for both.
  • Active cost rises with how many zones and models are registered.
  • The real killer is registration count, not which script you chose. A server with 400 box zones registered at startup will be slow on either system.

If your target resource is expensive, the fix is usually fewer registered zones โ€” use models and global types instead of hundreds of individual box zones โ€” before it is a change of script. Our FiveM optimization checklist covers the wider pattern.

Compatibility with your existing resources

This is the deciding factor for most established servers.

Modern scripts increasingly expect ox_target. Anything built on the ox stack in the last couple of years assumes it, and many releases now ship ox_target support first with qb-target as an afterthought or not at all.

Older QBCore resources expect qb-target. If your server runs a large set of established QB resources โ€” older job scripts, legacy robbery systems, inherited MLO interiors โ€” those were written against qb-target's API.

Count before you decide. Grep your resources folder:

grep -rl "qb-target" resources/

The number that comes back is your migration scope. Ten resources is an afternoon. Sixty is a project.

Should you switch?

Switch to ox_target if:

  • You are building a new server. Start here and never have this decision.
  • You are already standardising on the ox stack โ€” ox_lib and ox_inventory alongside it.
  • Most of the scripts you want to buy or install assume it.
  • Your qb-target usage is small enough to convert in one sitting.

Stay on qb-target for now if:

  • You have a large established server where the grep above returns dozens of resources.
  • Your server is stable and you have no pressing reason to touch a working interaction layer.
  • You are mid-way through another migration. Do not run two at once.

Do not switch because of performance alone. Unless you have measured a real problem with resmon, the win is compatibility and API quality, not frames.

If you do migrate

  1. Install ox_target alongside qb-target first. They can coexist while you convert.
  2. Enable the compatibility shim so nothing breaks on day one.
  3. Convert resource by resource, starting with the ones you edit most often.
  4. Test job-gated options specifically. The job to groups change is where most silent breakage lives โ€” the interaction simply does not appear, and nothing logs.
  5. Remove qb-target and the shim last, once the grep returns nothing.

Doing it in that order means you are never more than one restart away from a working server. If something does break, finding the script conflict is far easier when only one resource changed.

The trend is clear

Community momentum is firmly behind ox_target, and building on the ox stack gives you the cleanest, most compatible modern setup. For new servers it is the obvious choice. For established ones, it is a migration to plan rather than a decision to agonise over โ€” and the compatibility shim means you can start today and finish gradually.

Built for the modern stack

At Viper Development, our scripts are built for the modern ox ecosystem including ox_target, so they integrate cleanly on contemporary servers without a compatibility layer in between. Browse our scripts โ†’.

Premium FiveM scripts for QBCore & ESX

Viper Development builds escrow-protected, dual-framework scripts that install clean and run without dragging your server down.

Keep reading

Related guides