Two product pages, same screenshots, same feature list, same script, two different prices and a suffix at the end of each name telling you which framework it is for. A reasonable person looks at that and assumes somebody is being lazy, or worse, charging twice for one piece of work.
Neither, usually. The two versions really are two products, they diverge in more places than the feature list suggests, and the reason they are not one product with a toggle is a maintenance decision rather than a pricing trick. Understanding what actually differs between them is also the fastest way to stop buying the wrong one, which is a mistake with no refund at the end of it.
What is actually different inside
Frameworks disagree about four things, and a script touches all four constantly.
Getting the player. One fetches an object and calls methods on it, the other fetches a record and reaches through a functions table. Every server side handler in the resource starts with this line, so it appears everywhere.
Moving money. Account names differ, function signatures differ, and one of them wants a reason string that the other does not have.
Checking jobs. Both have jobs and grades, the shape of the object is different, and duty status exists natively in one and not the other.
Storing things. Different tables, different keys, different JSON shapes. A resource that saves its own data usually has to key it on whatever the framework calls a player, and those are not the same value.
Here is one payout function in both dialects, which is the entire article in ten lines:
-- one framework
local xPlayer = ESX.GetPlayerFromId(src)
if xPlayer.job.name ~= 'mechanic' then return end
xPlayer.addAccountMoney('money', 250)
-- the other
local Player = QBCore.Functions.GetPlayer(src)
if Player.PlayerData.job.name ~= 'mechanic' then return end
Player.Functions.AddMoney('cash', 250, 'repair-job')
Same logic, same intent, and not one line in common. Multiply that by every handler in a two thousand line resource and you can see why the two builds drift apart within a couple of releases.
Why not one product with a config toggle
Plenty of sellers do exactly that, and the good ones make it work. The reasons others do not:
The test matrix doubles. Every release has to be tested on both, on more than one version of each, which realistically means four or five test servers rather than one.
Bug reports stop being comparable. A report that says the payout fires twice is one investigation on one framework and two on a combined build, because the first question is always which side it came from.
Support cost is the real price. A seller supporting one build answers half the questions. That shows up in response times, which buyers notice long before they notice which architecture the product uses.
Escrow builds are per package. When code is protected, a combined build means shipping the whole thing to everyone regardless of which half they use.
None of that is charity towards buyers, it is just the economics. A seller who splits the product is usually optimising for being able to keep supporting it in a year.
Bridges, and what they cost
The third option is writing for one framework and shipping a compatibility layer for the other. Bridges genuinely work, and they move the failure into a new place: the edges where the two frameworks do not map cleanly.
Job grades that are a number on one side and an object on the other. Metadata with no equivalent. An inventory call that means subtly different things. Duty status that has to be invented. When a bridged script misbehaves, the bug is usually in the translation, which means neither framework's documentation helps and you are debugging someone's adapter.
Worth buying when the alternative is nothing. Worth knowing about before you buy, rather than at eleven at night when the payout fires twice.
What "universal" actually means on a product page
Three things, and it is worth asking which:
The resource keeps its own player data and only touches the framework at a couple of hooks. Often excellent, and it means one more table to back up.
The resource ships both code paths behind a config flag. Fine, if both paths are actually maintained. Check the changelog for entries mentioning each framework.
The resource was written for one framework and lightly patched for the other by a third party. This is the one that produces mystery bugs, and the changelog usually gives it away by going quiet on one side.
What buying the wrong one costs
Not a refund, in most cases, because digital delivery usually ends that conversation. So the cost is your time: either converting a script you cannot always read, or running it alongside a bridge you did not plan for, or shelving it and buying the right one.
The check takes two minutes before purchase. Know which framework you run, and know which version, because a build targeting a recent release can fail on an older install of the same framework. If you are not certain, identifying your framework version is a two minute job and it prevents the entire category of mistake.
Reading the page properly
Skip the badges, read these instead.
- The dependency list. A script requiring a specific inventory, target or menu library has chosen your stack for you, whatever framework name is on the title.
- The changelog dates. Two versions maintained means two streams of entries. One stream that stopped a year ago means one of these products is a fossil.
- The config file, if it is published. It tells you the item names, job names and table names the script expects.
- The SQL, if there is any. The table it creates tells you how it keys players, which tells you which framework it was really written for.
- The support channel. Ask which framework versions the current build is tested against. The answer, and the speed of it, is the most useful data point available.
What happens if you change framework later
The question nobody asks before buying, and everybody asks eventually: if the server migrates, does the licence move with it?
There is no single answer, because it is a seller policy rather than a platform rule. Some sellers will swap you to the other build on request, some offer it at a discount, some treat them as entirely separate products because they were entirely separate work. All three are defensible. None of them are guessable from the product page.
So ask before you buy if a migration is even slightly on your horizon, and keep the answer. A one line reply in a support channel is worth having when you come back to it eight months later.
Two related things worth knowing:
Your licence is usually tied to an account, not a server. Moving to new hardware is normally fine. Handing the server to somebody else is a different question, and it is one of the most common reasons a bought resource stops working after an ownership change.
Configs do not migrate. Even when a seller swaps your licence, the config you spent a weekend tuning is written in the other framework's vocabulary: job names, item names, account names. Budget an evening for re-tuning rather than assuming a copy and paste.
The broader point for anyone planning a framework change: the resources you cannot edit are the ones that decide whether the migration is feasible. Count those first, before the data mapping, because a server with forty escrowed resources is making a much bigger decision than one with forty open ones.
If you are the one selling
Same coin, other side. Splitting the product is fine and common, and what separates a good split from an annoying one is consistency: the same feature set on both, a changelog that shows both being maintained, a shared config layout so your docs work for both, and one support channel rather than two half staffed ones.
And say plainly which versions each build targets. The sellers who do that get fewer refund requests, fewer angry threads, and a noticeably easier support life. Buyers browsing the ESX build listings can spot the pages that do it within about five seconds, which is exactly how long they spend deciding.
Practical takeaway
The two versions are two products because the code genuinely diverges in every handler that touches a player, money, a job or storage. Know your framework and version before checkout, read the dependency list before the feature list, and ask the seller what the current build is tested against.
Two product pages with the same screenshots is not someone charging twice. It is usually someone who has decided to keep supporting both properly, which is the thing you actually want from a seller a year from now.