Imports and Exports
Lux modules are private by default. Top-level declarations create bindings that are visible to all parts of the same module, but other modules only see names that are explicitly exported.
export is a mapping from an internal binding to a public API name. It is not a
general "make this file public" switch.
Import Forms
Named imports bind selected public names from another module into the current part. Import aliases rename only the local binding.
Namespace imports keep the imported module table under one local binding.
Side-effect imports load the module without binding its exports. Use these for registration modules, not for normal API sharing.
Macro imports are compile-time imports. They do not become runtime locals.
Top-level imports are part-local. If two part files need the same external module, each part imports it explicitly.
Path Resolution
Relative-looking paths without a package prefix resolve inside the current Lux
project. Package paths use package ids such as @lux/std.
Do not import another part file from the same module. All part files in one module already share the same logical module scope.
Imported Bindings Are Immutable
An imported name is a local binding owned by the importing part. Reassigning it would make later use-sites ambiguous, so Lux rejects it.
If a mutable wrapper is needed, create a new local variable.
Exports Are Public Name Mappings
The simplest export maps a binding to the same public name.
Other modules import the public name, not the source filename or internal file layout.
The Lua-style alias form maps public_name = local_binding.
After this export, external users can only import p_inv; the original internal
name remains private.
Lux also accepts the JS-style export alias for readability in mixed teams.
The spec always defines the result as exported_name -> binding_id; both alias
spells produce the same export entry.
Exported Declarations
You can export while declaring a module-scope binding.
Method path declarations are not module-scope bindings and cannot be exported directly.
Use a private method path for GMod hooks and export a separate named helper when other modules need an API.
Realm Exports
An export may have an explicit realm. The export realm controls which generated artifact exposes the public name.
Exported declarations can combine visibility and realm in one declaration.
The supported declaration order is:
client export fn ... is intentionally not part of the style.
Exports Can Narrow, Not Expand
An export cannot make a binding available in a realm where the binding itself is not available.
A shared binding may be exported as shared, client-only, or server-only. This is narrowing the public API surface, not changing the binding's safety.
Formally, exported_realms must be a subset of binding_available_realms.
Export Restrictions
MVP 0.1 keeps export rules strict:
- Only module-scope bindings may be exported.
- Imported bindings from another module cannot be re-exported directly.
- The public exported name participates in duplicate export checks.
- Exporting with an alias does not expose the original internal name.
- Export realms cannot expand the binding's available realms.
Wrap intentionally forwarded APIs so diagnostics and source maps point at your module.
public all
public all is an escape hatch for modules that intentionally expose every
module-scope binding in the current effective realm.
Prefer explicit export { ... } in application code. public all is best for
small compatibility modules, generated modules, or packages whose entire file is
already a public API surface.