Violet

Marketplace Libraries

On this page

The marketplace lets you publish scripts and libraries other people can install. This page explains the one thing that trips everyone up: the difference between a public library and a private one, and how to import each with require().

Two kinds of "library"

Developers use the word "library" for two different things. Violet keeps them clearly separate:

  • Public library — a standalone marketplace product. Other developers require() it inside their own scripts. It can be free or paid, and it's reviewed before it's listed.
  • Private library — module files you bundle inside your own script's package. They're not sold, not listed, and only your script uses them. They simply ship to your script's buyers as part of the package.

The simple test: "Do I want other people to require() this?" Yes → publish a public library. No, it's only for my own script → bundle it as a private library.

Your handle owns libs/<handle>/

Before publishing anything, you claim a unique publisher handle (e.g. acme) once. It's your author identity and the root of your namespace: the folder libs/<handle>/ belongs entirely to you. Because the handle is unique, nothing you put there can ever collide with another developer's modules.

Both kinds of library live under that folder:

libs/
└── acme/
    ├── combat.lua          -- a PUBLIC library  → require("@acme.combat")
    ├── combat/
    │   └── http.lua       -- its submodule     → require("@acme.combat.targeting")
    └── myfarmer/
        └── helpers.lua    -- a PRIVATE module bundled in the "myfarmer" script

A public library is a published subtree of libs/<handle>/; a private library is module files under the same root that ride inside a script. Same folder, different destiny.

Importing a marketplace library: the @ convention

When you pull in a marketplace (public) library, write it with an @ in front — like a scoped package:

lua
local combat = require("@acme.combat")        -- a marketplace library
local helpers = require("acme.myfarmer.helpers")  -- your own bundled module

The @ marks code that came from the marketplace, so third-party imports are obvious at a glance.

Optional alias

The @ is optional — require("@acme.combat") and require("acme.combat") resolve to the exact same file. Use the @ form for marketplace libraries so they stand out from your own modules.

Publishing a public library

A public library is a product whose files are only modules under libs/<handle>/<lib>/, with one required entry file:

LibraryEntry fileConsumers write
acme + name combatlibs/acme/combat.luarequire("@acme.combat")

The entry filename and the require path mirror each other: libs/acme/combat.lua@acme.combat. A submodule at libs/acme/combat/targeting.lua is require("@acme.combat.targeting").

A library module returns a table and has no plugin table (that's only for runnable scripts):

lua
-- libs/acme/combat.lua  (entry module for require("@acme.combat"))
local M = {}

function M.distance(a, b)
    return math.sqrt((a.x - b.x) ^ 2 + (a.y - b.y) ^ 2)
end

return M
Names

A handle and a library name use only lowercase letters, numbers, and underscores — no dashes or dots inside a single name segment.

Bundling a private library

A private library needs no separate product. Just put helper modules under your handle inside your script's package:

myfarmer.lua                       -- the runnable script
libs/acme/myfarmer/helpers.lua     -- a private module, bundled with it

Your script requires them by path, and they install automatically for everyone who buys the script:

lua
plugin = {
    name = "My Farmer",
    version = "1.0.0",
    author = "acme",
    description = "Auto-farms the current map",
}

local helpers = require("acme.myfarmer.helpers")

function on_tick()
    local player = core.object_manager.get_local_player()
    if not player or not player:is_valid() then return end
    helpers.log("hp " .. player:get_health())
end

Depending on a public library

To use someone else's public library in your script, declare it as a dependency (don't copy its files into your package). The platform installs it for your buyers automatically, including everything it depends on in turn.

lua
local combat = require("@acme.combat")
Free libraries only

Only free public libraries can be auto-installed as dependencies. Paid libraries are bought directly — you never redistribute someone else's source.

See also