
A lightweight framework for building WoW Classic addons.
Embeddable LibStub library with an addon container, dependency injection, client detection for all Classic clients, logging, locales, timers and a complete UI toolkit in a purple and gold style. Register models, services and views and build features instead of boilerplate.
The library is embedded in the addons using it, players never need to install it. The newest copy always wins when several addons ship it.
Features
| Area | What you get |
|---|---|
| Addon container | Lib:CreateAddon({...}): name, version, chat prefix, SavedVariables prefix, event frame and lifecycle hooks (OnLoaded, OnCombatStart, OnCombatEnd). |
| Dependency injection | CreateModel, CreateService and CreateView register types, GetService, GetModel and NewView resolve them. Services start lazily, every service, view and model gets self.addon, self:GetService() and self:GetModel(). |
| Client detection | isVanilla, isSod, isBcc, isWrath, isCata, isMop, is*AtLeast and expansionId. |
| Log service | addon:Log(class, method, format, ...) writes to a SavedVariable per day, old days are purged, GetLogText() renders it. |
| Locale service | Full locale first (zhCN), then short (de), then English. Get(key, ...) formats only with arguments. |
| Timer service | Named countdowns, Wait and FormatTime ("5m", "1d 2h 10m", "Ready"). |
| UI service | Movable and resizable windows with gradient border, ElvUI scale awareness, saved position and size, panels, buttons, tabs, scroll frames, edit boxes, dropdowns, tooltips and a minimap button. |
Supported clients
Classic Era, Season of Discovery, Anniversary, TBC, Wrath, Cataclysm and Mists of Pandaria Classic.
Quick start
Embed the library and load it after LibStub, LibDataBroker and LibDBIcon:
## OptionalDeps: LibMasterAddons
## X-Embeds: LibMasterAddons
libs\LibStub.lua
libs\CallbackHandler-1.0.lua
libs\LibDataBroker-1.1.lua
libs\LibDBIcon-1.0.lua
libs\LibMasterAddons\LibMasterAddons.xml
MyAddon.lua
Create the addon:
local Lib = LibStub("LibMasterAddons-1.0");
local addon = Lib:CreateAddon({
id = "MyAddon", -- folder and TOC name
name = "My Addon",
shortcut = "|cffDA8CFF[MA]|r ", -- prefix of window titles and chat output
storagePrefix = "MA", -- MA_Logs, MA_Frames, MA_Settings
});
addon:OnLoaded(function()
addon:GetService("startup");
end);
_G.myAddon = addon;
Add a service and a view:
local StartupService = _G.myAddon:CreateService("startup");
function StartupService:Initialize()
self:HandleEvent("PLAYER_LOGIN", function()
self.addon.mainView = self.addon:NewView("main");
self:GetService("ui"):CreateMinimapIcon({
icon = "Interface\\Icons\\INV_Misc_Book_09",
onClick = function() self.addon.mainView:Toggle(); end,
onTooltip = { "My Addon", "Left click: toggle window" },
});
end);
end
local MainView = _G.myAddon:CreateView("main");
function MainView:Toggle()
if (not self.frame) then
local ui = self:GetService("ui");
self.frame = ui:CreateView("main", 600, 400, "My Addon", true, true);
ui:CreateFlatCloseButton(self.frame, function() self.frame:Hide(); end);
end
self.frame:SetShown(not self.frame:IsShown());
end
The services log, locale, timer and ui are resolved by name and can be replaced by an own service with the same name.
Compatibility
LibMasterAddons-1.0 is the API contract: members are only added, never removed or changed. Breaking changes ship as a new major that can be embedded side by side.
Feedback
Comments on the CurseForge project page are welcome.

