Install
$ agentstack add skill-luumenlabs-luau-skills-luau-types ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
luau-types
When to Use
Use this skill when the task is primarily about Luau's type system:
- Choosing between
--!strict,--!nonstrict, and other file type-checking modes. - Adding or correcting type annotations on variables, functions, tables, and modules.
- Designing APIs that preserve inference instead of collapsing to
any. - Modeling data with generics, unions, intersections, optionals, and tagged unions.
- Typing object-like tables, metatable-backed modules, and exported module surfaces.
- Writing or reviewing type functions and other advanced type-level utilities.
- Using Roblox class, datatype, enum, or
IsAknowledge only to improve static typing.
Do not use this skill when the task is mainly about:
- General Luau syntax, control flow, metatables, or standard-library usage outside typing concerns.
- Runtime performance, profiling, hot-path tuning, or allocation strategy.
- Roblox networking, replication, data storage, cloud APIs, or gameplay architecture.
Decision Rules
- Use this skill if the core question is "what should this type be?" or "how should this code type-check over time?"
- Prefer
--!strictguidance for new or actively maintained code unless the task explicitly targets transitional or legacy code. - Prefer inference-preserving designs over annotation-heavy designs when the inferred shape stays precise and readable.
- Prefer explicit exported aliases at module boundaries when consumers should share a stable contract.
- Use generics when the relationship between inputs and outputs matters; do not replace that relationship with
any. - Use tagged unions plus refinements when a value can be one of several structured cases.
- If the task shifts into pure language syntax, hand off to
luau-core. - If the task shifts into optimization or runtime cost tradeoffs, hand off to
luau-performance. - If the task requires Roblox runtime architecture beyond type names and type refinement, use the appropriate
roblox/*skill instead. - If unsure, exclude anything that is not directly needed to improve typing correctness, maintainability, or analyzer behavior.
Instructions
- Start by identifying the file mode expectation:
--!strictfor strong inference and early error detection.--!nonstrictfor transitional code where unresolved values would otherwise become noisy.--!nocheckonly when the task explicitly requires disabled analysis.
- Preserve useful inference before adding annotations everywhere. Add annotations where they clarify intent, stabilize module contracts, constrain
self, or prevent unwanted widening toany. - Prefer concrete aliases for shared shapes:
- records for structured data,
- indexers for dictionaries,
{T}for arrays,- exported aliases for module-facing contracts.
- Use optionals, unions, and intersections deliberately:
T?forT | nil,- tagged unions for state machines or result-like values,
- intersections to combine compatible table capabilities or function signatures.
- Treat casts with
::as a precision tool, not a bypass. Use them to narrow overly generic inference, not to hide unrelated-type errors. - Design generics around relationships:
- preserve element type through transforms,
- carry key/value relationships through containers,
- avoid defaulting to
anywhen a type parameter can express intent.
- Model tables according to how Luau analyzes them:
- unsealed tables can accumulate fields locally,
- annotated or returned tables become sealed,
- width subtyping applies to sealed records.
- For object-like modules, separate instance data from class behavior, derive the instance type from
setmetatable, and annotateselfexplicitly when methods need the shared class type. - Keep module API surfaces type-safe:
- export named aliases for consumer-facing data,
- keep implementation details internal,
- choose signatures that infer caller types cleanly.
- Use Roblox type knowledge only for annotations and refinements, such as
Instance,Part,Enum.Material, datatypes, andIsA-driven narrowing.
Using References
- Open
references/type-system-overview.mdfor file modes, structural typing, annotations, casts, and module-boundary guidance. - Open
references/basic-types-and-table-typing.mdfor builtin types, special types likeanyandunknown, function signatures, table states, and indexers. - Open
references/generics.mdfor generic aliases, generic functions, defaults on aliases, and inference-preserving container patterns. - Open
references/unions-and-intersections.mdfor result shapes, tagged unions, discriminants, and safe intersection usage. - Open
references/refinements.mdfor truthy checks,type(...)guards, equality narrowing, compound conditions, andassert-based narrowing. - Open
references/object-oriented-typing.mdfor metatable-backed class typing,selfannotations, constructor return types, and exported instance aliases. - Open
references/type-functions.mdfor analysis-time type computation, available libraries, and when advanced type-level transforms are justified. - Open
references/roblox-types-in-luau.mdfor Roblox class, datatype, enum, constructor, service, andIsAtyping behavior. - Do not open other skill references unless the request clearly crosses skill boundaries.
Checklist
- The chosen type-checking mode matches the maintenance goal of the file.
- Public module contracts are explicit where reuse matters.
- Inference is preserved where it remains precise.
anyis avoided unless intentionally opting out.- Tables are typed according to their actual shape and sealing behavior.
- Unions, intersections, and optionals reflect real states instead of vague catch-all types.
- Generic parameters encode input/output relationships that callers rely on.
- Method
selftyping is explicit where Luau cannot safely infer the shared class type. - Roblox types are used only to improve typing, not to drift into unrelated Roblox architecture.
- No general syntax tutorial, performance advice, or networking/data/cloud guidance is included.
Common Mistakes
- Leaving a variable unannotated in
--!nonstrictand unintentionally turning it intoany. - Replacing a useful generic relationship with
anyor an overly broad union. - Sealing a table too early with an annotation, then expecting to add fields later.
- Expecting method definitions with
:to automatically share a preciseselftype across the whole class. - Using
::to force unrelated conversions instead of fixing the underlying type design. - Building unions without a discriminant, then making downstream refinement difficult.
- Using intersections between incompatible primitives such as
string & number. - Mixing runtime Roblox architecture guidance into a type-only task.
Examples
Export a stable module contract
--!strict
export type User = {
id: number,
name: string,
nickname: string?,
}
local M = {}
function M.makeUser(id: number, name: string): User
return {
id = id,
name = name,
nickname = nil,
}
end
return M
Preserve relationships with a generic function
--!strict
local function first(items: {T}): T?
return items[1]
end
local a = first({1, 2, 3}) -- number?
local b = first({"x", "y"}) -- string?
Refine a tagged union
--!strict
type Loading = { kind: "loading" }
type Ready = { kind: "ready", value: T }
type Failed = { kind: "failed", message: string }
type State = Loading | Ready | Failed
local function readValue(state: State): number?
if state.kind == "ready" then
return state.value
end
return nil
end
Type an object-like module with explicit self
--!strict
local Counter = {}
Counter.__index = Counter
type CounterData = {
value: number,
}
export type Counter = typeof(setmetatable({} :: CounterData, Counter))
function Counter.new(initialValue: number): Counter
return setmetatable({
value = initialValue,
}, Counter)
end
function Counter.increment(self: Counter, amount: number): number
self.value += amount
return self.value
end
return Counter
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: luumenlabs
- Source: luumenlabs/luau-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.