CurseForge · Minecraft mod
Q Shop
A flexible Forge 1.20.1 and NeoForge 1.21.1 server shop with buy, sell, barter and command trades, custom currencies, limits, in-game editing and a Builder-first KubeJS API.
Quick answer
Which Q Shop release should I use?
Q Shop qshop-forge-1.20.1-1.3.0 targets 1.20.1 with Forge. The project page does not say whether this file belongs on the client, dedicated server, or both. No extra mods listed for this file.
Where it goes
Is Q Shop required on the client, server, or both?
The project page does not say whether this file belongs on the client, dedicated server, or both.
The source does not explicitly classify this release as client-only or server-only.
What else does Q Shop qshop-forge-1.20.1-1.3.0 need?
qshop-forge-1.20.1-1.3.0. Change the file and its required mods may change too.
This file does not list any required mods. Do not add a library just because a different file uses it.
2 extra mods were pulled in by other dependencies. Indented rows show who needs each one. We only count dependency files that match this setup. A file for another loader does not fill the gap.
Before you install it
Add Q Shop without breaking your instance.
Built for Q Shop qshop-forge-1.20.1-1.3.0. Pick another file and the loader, install side or required mods may change.
- 01
Stick to this file
Use qshop-forge-1.20.1-1.3.0. It targets 1.20.1 with Forge; another release may have different loader, side or dependency requirements.
- 02
Bring the mods it needs
This file does not list any required mods. Do not add a library just because a different file uses it.
- 03
Put it on the correct side
The project page does not say whether this file belongs on the client, dedicated server, or both.
- 04
Pick the file you checked
Use the “Get this file” button beside qshop-forge-1.20.1-1.3.0. It opens that exact file at the source.
About this project
What does Q Shop add?
Q Shop
QShop 1.2.4
QShop is a configurable shop mod for Minecraft Forge 1.20.1 and NeoForge 1.21.1. Choose the loader-specific QShop file for your instance, then create multiple shops and sub-shops, edit them in game, use custom non-item currencies, and let players buy, sell, barter or trigger server commands.
QShop has no mandatory gameplay integration dependencies. KubeJS and FTB Quests are optional and only needed for their respective features. Stage requirements use KubeJS stages when KubeJS is installed.





Features
Trade GUI
- Buy, sell, item-for-item barter and command entries in one interface.
- Barter entries can optionally charge an additional currency fee.
- Command entries execute configured server commands after a successful purchase.
- Custom display names, descriptions, display items and item NBT are supported.
- Quantity controls use a slider and input box with live limit, inventory and balance checks.
- Smooth scrolling for entry grids and sub-shop tabs.
- Optional F8 component-coordinate debugging for the shop, trade settings, and item browser GUIs, with offsets persisted in
config/qshop_layout.json. - Individual entries can optionally remain visible when their quest or stage requirements are not met.
- A visible locked FTB Quests entry opens its matching quest screen when clicked, and QShop closes first.
- FTB Quests tooltips show quest names when available and include a click-to-open hint.
- Trade entry editing supports stage descriptions. Descriptions follow the order of
requiredStages; blank descriptions fall back to the stage ID.
Shops and sub-shops
- Multiple shops identified by a stable ID or UUID.
- Every shop has one or more sub-shops with an icon, description and independent entries.
- Sub-shop icons support item data and NBT; descriptions are shown as hover tooltips.
- Creative-mode editing supports adding, removing, copying, reordering and editing entries.
- Shop and sub-shop changes are saved and synchronized to open clients.
Custom currencies
- Create any number of non-item currencies such as coins, points or tokens.
- Balances are stored per player and synchronized to the client.
- Manage currencies with commands or KubeJS.
Purchase limits
- Global server-wide and per-player limits for each entry.
- Limits are counted in trade units/purchase counts, not item quantities. One completed trade unit consumes one limit even when it contains multiple items.
- Reset periods:
NEVER,DAILY,WEEKLYandMONTHLY.
Requirements
- Gate complete sub-shops or individual entries behind FTB Quests tasks.
- Stage requirements use KubeJS PlayerStages.
- If a configured requirement has no matching provider installed, it is treated as unmet and the content stays hidden from normal players.
- Enable an entry's Show when requirements are not met option to keep it visible in normal mode. Clicking a visible unmet FTB Quests entry opens the first matching quest and closes QShop.
Stage descriptions are configured in the trade entry editor or the entry JSON. Each description matches the stage at the same position in requiredStages; an empty or missing description displays the stage ID instead:
"requiredStages": ["vip", "nether"],
"requiredStageDescriptions": ["VIP access", ""]
Commands
/qshop open <shop> [player]
/qshop list
/qshop balance
/qshop reload
/qshop currency list
/qshop currency create <id> <name> [color]
/qshop currency give|take|set <player> <currency> <amount> [true|false]
/qshop shop create <id> [displayName] [currency]
/qshop edit <shop> add <type> [price] [currency]
/qshop edit <shop> remove <index>
/qshop edit <shop> setitem <index>
/qshop edit <shop> set <index> <field> <value>
/qshop item
Shop editing requires permission level 2 and Creative mode. The final sub-shop cannot be removed.
Configuration
Supported loaders
- Minecraft Forge 1.20.1 (Forge 47.x)
- Minecraft NeoForge 1.21.1 (NeoForge 21.1.x)
Release files use the format modid-modloader-modloaderVersion-modVersion.jar:
qshop-forge-1.20.1-1.2.4.jarqshop-neoforge-1.21.1-1.2.4.jar
<world>/serverconfig/qshop/currencies.json
<world>/serverconfig/qshop/shops/<shop-id>.json
Items accept an ID, an item object with count and nbt, a KubeJS ItemStack, or the Base64 format written by QShop.
Pack authors can place currencies.json and a shops/ directory under the server root at defaultconfigs/qshop/. QShop imports this directory into a new world's serverconfig/qshop/ on first load and never overwrites existing world configuration. If the directory contains any shop JSON other than the example starter.json, QShop skips starter.json so the pack's own shops are imported without the example shop. If starter.json is the only shop, it is imported normally.
The common config config/qshop-common.toml can optionally reduce currencies on death. Set death.loseCurrencyOnDeath=true, then use entries such as currencyRetention=["coins=0.2"] to keep 20% of coins after death.
KubeJS integration
Install KubeJS on the server to enable the global QShop binding. The public 1.1.0 KubeJS API is Builder-first. JSON CRUD methods and direct JsonIO writes are not part of the public global API.
Create or update data
QShop.createShop('vip', 'VIP Shop', 'coins')
QShop.tab('vip')
.name('Daily Offers')
.icon({
item: 'minecraft:paper',
count: 1,
nbt: '{display:{Name:"Daily Card"}}'
})
.description('Refreshes every day')
.uuid('daily-offers')
.stage('vip_unlocked')
.add()
QShop.entry('vip', 'daily-offers')
.buy({ item: 'minecraft:oak_log', count: 8 })
.price(2, 'coins')
.playerLimit(20, 'DAILY')
.uuid('oak-bundle')
.add()
Calling add() with an existing entry UUID replaces that entry in place. Calling add() with an existing tab UUID updates tab metadata while preserving its entries.
Read objects
const shop = QShop.getShop('vip')
const tab = QShop.getTab('vip', 'daily-offers')
const entry = QShop.getEntry('vip', 'daily-offers', 'oak-bundle')
console.log(shop.id, tab.uuid, entry.uuid)
console.log(entry.type.name(), entry.count, entry.getCount())
getShop, getTab and getEntry return complete Java objects. Read fields directly from the returned object: entry.type, entry.item, entry.give, entry.receive, entry.price, entry.currencyId, entry.commands, entry.requiredQuests, entry.requiredStages, entry.requiredStageDescriptions and entry.showWhenRequirementsNotMet.
entry.count and entry.getCount() are equivalent. count is the item quantity represented by one entry unit, not the number of clicks. entry.type is an enum; compare it with entry.type.name(), for example entry.type.name() === 'BUY'.
Reference rules
| Reference | Accepted values |
|---|---|
shopRef |
Shop ID or shop UUID |
tabRef |
Zero-based index, tab UUID or null for the first tab |
entryRef |
Zero-based index or entry UUID |
Use UUIDs for long-lived scripts because indexes change when content is reordered or refreshed.
QShop.getEntryCount('vip') // entries in tab 0
QShop.getEntryCount('vip', 1) // entries in tab 1
QShop.removeEntry('vip', 'daily-offers', 'oak-bundle')
QShop.removeTab('vip', 'daily-offers')
Currencies and refresh
QShop.createCurrency('tokens', 'Tokens', '#55ff55')
QShop.giveCurrency(player, 'tokens', 100)
QShop.takeCurrency(player, 'tokens', 10)
QShop.setCurrency(player, 'tokens', 50)
QShop.refreshTab('vip', 'daily-offers', 10, [
{ item: 'minecraft:iron_ingot', price: 2, weight: 50 },
{ item: 'minecraft:gold_ingot', price: 5, weight: 10 }
])
The second argument is a zero-based tab index or the tab UUID (daily-offers in this example), not the tab display name. Every generated entry receives a new UUID and starts with empty limit counters. The limit-clearing methods accept tab/entry indexes or UUIDs (not names); the shop reference can be a shop ID or shop UUID. They clear the global counter and personal counters for both online and offline players; offline counters are edited directly in world/playerdata/<uuid>.dat.
Trade events
QShopEvents.beforeTrade(event => {
const entry = event.getEntry()
if (entry && entry.type.name() === 'COMMAND') {
event.cancel()
event.player.tell('This entry is temporarily unavailable.')
}
})
QShopEvents.afterTrade(event => {
const shop = event.getShop()
const tab = event.getTab()
const entry = event.getEntry()
console.log(`${shop.id}/${tab.uuid}/${entry.uuid}`)
console.log(`${entry.type.name()} x${event.tradedUnits}`)
if (event.isPartial()) {
event.player.tell(`Completed ${event.tradedUnits} unit(s).`)
}
})
QShopEvents.currencyChanged(event => {
console.log(`${event.getCurrency()}: ${event.getOldValue()} -> ${event.getNewValue()}`)
})
Read shop, tab and entry fields through getShop(), getTab() and getEntry(). Event-only data includes units for beforeTrade, and tradedUnits, totalItems, paidPrice and partial for afterTrade. currencyChanged provides getPlayer(), getCurrency(), getOldValue(), getNewValue(), getDelta(), getSource() and getSourcePos(). It fires for all effective currency changes, including trades, FTB money rewards/tasks, commands, KubeJS currency methods, configured death retention, and Java addon services. Append false to a command to suppress it.
NeoForge addon mods can use the official com.qshop.api.QShopAddonApi facade. Its currency() service centralizes wallet mutations, and its buy/sell methods accept NeoForge IItemHandler inventories for server-side container integrations. Java addons can listen for com.qshop.api.CurrencyChangedEvent on the NeoForge event bus.
Documentation
License
QShop and its assets are All Rights Reserved (ARR). See LICENSE for the full terms.
Project description from CurseForge.
Pick your setup
Q Shop by Minecraft version and loader
Choose the version and loader you play, then open the matching release.
1.21.1
1 loader build1.20.1
1 loader buildCheck the dependencies, then try the file in a copied instance before changing a world you care about.
Recent files
Q Shop versions and loaders
qshop-forge-1.20.1-1.3.0
qshop-forge-1.20.1-1.3.0.jar
1 Sept 2026
QShop 1.2.4 Forge 1.20.1
qshop-forge-1.20.1-1.2.4.jar
31 Aug 2026
qshop-neoforge-1.21.1-1.2.3.jar
28 Aug 2026
qshop-neoforge-1.21.1-1.2.3.jar
28 Aug 2026
qshop-forge-1.20.1-1.2.3.jar
qshop-1.2.3.jar
28 Aug 2026
qshop-1.2.2.jar
26 Aug 2026
qshop-1.2.1.jar
26 Aug 2026
qshop-1.2.0.jar
25 Aug 2026
qshop-1.1.2.jar
24 Aug 2026
qshop-1.1.1.jar
23 Aug 2026
qshop-1.1.0.jar
22 Aug 2026
qshop-1.0.7.jar
20 Aug 2026
Looking for an older file? The official CurseForge project page is in Resources.