spearmint
A CLI tool that syncs Roblox developer products and game passes from a local TOML config to the Roblox Open Cloud API.
Define your products in spearmint.toml, run spearmint sync, and spearmint handles creating/updating them on Roblox while generating Lua and TypeScript files for your game.
Install
Setup
-
Create a Roblox Open Cloud API key at create.roblox.com/dashboard/credentials with Developer Product and Game Pass write permissions for your experience.
-
In your project directory, create a
.envfile:
ROBLOX_PRODUCTS_API_KEY=your_api_key_here
- Initialize the config:
- Edit the generated
spearmint.tomlwith your universe ID and products.
Config
= 123456789
[]
= "src/shared/modules/Products.luau"
= true
[]
= "dev_product"
= "100 Coins"
= 99
= "Get 100 coins"
= "assets/products/coins.png"
[]
= "gamepass"
= "VIP"
= 499
= "VIP access"
= "assets/products/vip.png"
Each product entry supports:
| Field | Required | Description |
|---|---|---|
type |
Yes | dev_product or gamepass |
name |
Yes | Display name on Roblox |
price |
Yes | Price in Robux |
description |
No | Product description |
image |
No | Path to thumbnail image |
product_id |
No | Existing Roblox ID (skips creation, used for updates) |
Commands
spearmint sync
Syncs all products to Roblox. Creates new products and updates existing ones when the config has changed. Generates Lua/TypeScript output after syncing.
spearmint generate
Generates Lua and TypeScript output files from the current mapping without making any API calls.
spearmint list
Lists all products and their sync status.
spearmint init
Creates a default spearmint.toml template.
How It Works
spearmint uses a lock file (spearmint.lock.toml) to track the mapping between local product keys and Roblox IDs, along with cached metadata. On each sync, it compares the current config against the lock file to determine what's changed:
- New products (no lock file entry) are created via the API
- Changed products (name, price, description, or image contents differ) are updated
- Unchanged products are skipped
Image changes are detected by SHA-256 hashing the file contents, so replacing an image file without renaming it will trigger an update.
Generated Output
After syncing, spearmint generates a Lua module and optionally a TypeScript declaration file:
Products.luau
-- This file is auto-generated by spearmint. Do not edit manually.
local Products =
return Products
Products.d.ts
// This file is auto-generated by spearmint. Do not edit manually.
interface Products {
DevProducts: {
readonly "coins_100": 123456;
};
Gamepasses: {
readonly "vip": 789012;
};
}
declare const Products: Products;
export = Products;
License
MIT