# Modules and Imports Deft's module system is file-path based. A module is a `.dft` file loaded by path; declarations at the top level become the module's public surface (with `def` introducing module-scoped bindings). The `implements` declaration adds module-level conformance checks at import time. ## `import` — Load a Module `import "path" as alias` loads a module and binds its public surface to a namespace alias:
 import "deft/stdext/async" as async

set results [async/await-all $futures] 
Import paths take several forms: - **Relative** — `"./helpers"` / `"../lib/util"` resolve against the importing file's directory. - **Package-qualified** — `"owner/name/sub/path"` (e.g. `deft/ui/components/button`) resolves through the package mounts auto-registered from the `:pkgs` roots. Append `@version` to the name to pin (`deft/ui@0.1.0/...`); `@latest` is an explicit alias for the unpinned resolution. - **Mount-named** — any other leading segment that matches a prelude `:mounts` entry or a `[pkg/mount ...]` registration. Longest mount prefix wins, so qualified package names are never shadowed by a single-segment mount. - **CWD-relative** — a plain `"foo/bar"` whose file exists under the working directory resolves locally before mounts are consulted. Drop the `.dft` extension in the path. A failed package-qualified import reports available versions (`no matching version; available: ...`); a bare package prefix suggests the qualified spelling (`did you mean "deft/ui/..."?`). ### Resolving without importing `[import/resolve "path"]` answers "which file would `import` load?" without loading it — same resolver, same precedence (relative, CWD-relative, mounts with version pins, stdext fallback):
 [import/resolve "deft/ui/components/button"]
# => ".deft/packages/deft/ui/0.1.0/src/components/button.dft"
[import/resolve "deft/ui@0.1.0/components/button"]   # explicit pin
[import/resolve "./helpers"]                          # relative to caller 
Returns the literal file path (with the `.dft` suffix loadFile would use — `.../markdown.syntax` resolves to `.../markdown.syntax.dft`), or nil when the import would not resolve. Useful for tooling: jump-to-source, file watchers, dependency graphs, diagnostics. Package **asset** paths resolve too — directories and package-root files that `import` itself wouldn't load. A qualified reference probes the subpath as a directory under the package's code dir, then under the package root; a bare `"owner/name"` yields the package root itself:
 [import/resolve "deft/help/manual"]   # → "packages/help/manual" (directory)
[import/resolve "deft/help/help.md"]  # → "packages/help/help.md" (root file)
[import/resolve "deft/help"]          # → "packages/help" (package root) 
So apps that need a package's data directory (doc trees, themes, assets) can derive it from the same `owner/name` identity the code imports use — no hand-rolled path probing per install layout. ### `from ... import` `from "path" import @{ name1 name2 }` pulls individual names into the current scope without an alias:
 from "deft/stdext/async" import @{ await-all map-concurrently }

set xs [await-all $futures] 
The names list is a Deft list literal — `@{...}` for many names, single symbols also work. ## Namespaces Every runtime has a `current-ns` — the namespace into which top-level `def`s go. The default namespace is `"user"`.
 [current-ns]                                  # => "user"
[in-ns "my-app"]                              # switch namespace 
`in-ns` is rarely used in scripts; it's primarily for REPL sessions and runtime/tooling code that manages namespaces dynamically. ### Module namespace When you `import "foo/bar" as bar`, the loaded module's namespace becomes accessible as `bar/name`:
 # In stdext/async.dft:
def await-all {|futures| ... }

# In your script:
import "deft/stdext/async" as async
[async/await-all $futures]                    # ← name resolved through alias 
## `implements` — Module Conformance A module may declare that it conforms to an interface. At import time, Deft verifies that all functions required by the interface are exported:
 # my-app/storage.dft
implements StorageInterface

def get {|key| ... }
def put {|key val| ... }
def delete {|key| ... } 
If a required function is missing, the import fails with an error naming the missing function, and the script never reaches code after the failed import: ``` module my-app/storage impls StorageInterface but missing export: delete ``` A module without an `implements` declaration has no conformance requirements. A conforming module may export additional functions beyond what the interface requires. > `implements` is a **module-level** conformance check (does this > file export the required names?). It's distinct from > `defprotocol`/`defimpl`, which are **type-level** protocols > governing method dispatch on values. See [Types and > Protocols](types-and-protocols). ## Defining an Interface An interface is a module that declares a list of required exports. The simplest form is a module that documents the expected names; Deft's checker walks the imports and looks them up.
 # stdext/storage_iface.dft
#
# Modules implementing StorageInterface must export: get, put, delete.

def required-names ^{:get :put :delete} 
A real interface module typically also defines the types or documentation that implementers need. See `test/test_impls.dft` for the canonical example. ## Packages A **package** is a directory of Deft modules with a `package.dft` manifest. Packages are the unit of distribution: install via `pkg/install`, mount into a runtime, and import from any module.
 def manifest %Package{
    :owner "alice"
    :name "math-lib"
    :version "1.0.0"
    :description "Personal math helpers"
} 
See [Packages](../07-Tooling/packages) for the package manifest format, `pkg/*` stdlib functions, and `.dfs` distribution files. ## Search Paths Unqualified paths resolve in this order: 1. CWD-relative (`/foo/bar.dft` or its directory-index form), only when the file exists. 2. Mount names (longest prefix first): package-qualified `owner/name[@version]` mounts from the `:pkgs` auto-scan, then single-segment prelude `[pkg/mount]` mounts. 3. The stdext subpath fallback for `syntax/*` modules. See [Packages](../07-Tooling/packages) for the `:pkgs` roots and package reference syntax. ## Circular Imports Deft does not support circular imports. If module A imports B and B imports A, the loader detects the cycle and raises an error at load time. Refactor to break the cycle, or use `pub/*` to communicate between the modules at runtime. ## Reload `[reload "path"]` reloads a module that has changed on disk. Useful during development (especially in the REPL or a long-running TUI app). Existing references to old definitions are not updated; only future lookups resolve to the new version.
 [reload "my-app/foo"] 
## Information About Loaded Modules The `info/*` namespace exposes the module table:
 [info/modules]                                # list of loaded module names
[info/defs]                                   # defs in the current namespace
[info/vars]                                   # vars in the current namespace
[info/resolve "name"]                         # resolve a name to its source 
See [Metaprogramming](metaprogramming) for the full `info/*` API. ## Quick Reference | Form | Purpose | |---|---| | `import "path" as alias` | Load module, bind to alias | | `from "path" import @{ names }` | Pull in specific names | | `[in-ns "name"]` | Switch current namespace | | `[current-ns]` | Get current namespace name | | `implements InterfaceName` | Declare module conformance (checked at load) | | `[info/modules]` | List loaded modules | | `[reload "path"]` | Reload a module |