Maid
Lifecycle cleanup utility. Track connections, threads, instances, and teardown functions — then clean them all up at once. Works with any object that has a natural teardown.
local maid = RoExpress("Maid")
Each call to RoExpress("Maid") returns a fresh Maid instance. The Maid module itself is also accessible as RoExpress.Maid if you need the factory directly.
Add
local conn = maid:Add(item) -- returns item unchanged
Track an item for cleanup. Returns its argument unchanged so you can store and track in one expression:
local conn = maid:Add(Bridge.On("kill", handler))
-- conn is still typed as BridgeConnection
conn:Disconnect() -- or let maid:Destroy() handle it
Maid handles the following item types automatically:
| Type | What Maid calls |
|---|---|
RBXScriptConnection | :Disconnect() |
Any table with Disconnect | :Disconnect() — covers BridgeConnection |
Any table with Destroy | :Destroy() — covers Instance, nested Maid |
thread (coroutine) | task.cancel() |
function | Called with no arguments — arbitrary teardown |
Remove
maid:Remove(item)
Immediately clean and stop tracking a specific item. Useful when an item's lifetime ends before the Maid is destroyed.
Clear
maid:Clear()
Clean all tracked items and reset the Maid to empty. The Maid itself remains usable — you can continue adding items after a Clear. Useful at the end of a round or phase when you want to reuse the same Maid.
Destroy
maid:Destroy()
Clean all tracked items and make the Maid inert. Do not use the Maid after calling Destroy. For module shutdown or when the owning object is destroyed.
Nesting
Maids can be nested. A child Maid added to a parent Maid will have its own :Destroy() called when the parent is destroyed — useful for per-player or per-round sub-lifecycles.
local gameMaid = RoExpress("Maid")
local roundMaid = gameMaid:Add(RoExpress("Maid"))
roundMaid:Add(Bridge.On("round.tick", onTick))
roundMaid:Add(Bridge.On("round.end", onEnd))
-- end of round: clean round events, keep game events
roundMaid:Destroy()
-- full shutdown: cleans everything including gameMaid children
gameMaid:Destroy()
Gun equip / unequip
A common pattern — create a Maid when a tool is equipped and destroy it when unequipped so all connections are always cleaned up, even with anonymous handlers.
local maid: RoExpress.Maid
tool.Equipped:Connect(function()
maid = RoExpress("Maid")
maid:Add(Bridge.On("ammo.refill", function(data)
ammo = data.amount
end))
maid:Add(UserInputService.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
shoot()
end
end))
maid:Add(function() print("gun unequipped") end)
end)
tool.Unequipped:Connect(function()
if maid then maid:Destroy() end
end)
See also
Bridge | BridgeConnection returned by Bridge.On / Bridge.Once ·
Hook | Roblox signal subscriptions also return connections ·
Debounce | cooldown wrappers