
Each `.vary` file is a module and directories are packages. You use imports to pull in functions, classes, and other definitions. The compiler resolves the full dependency graph at compile time.

## The prelude

A small set of types and functions is available in every file without imports. Everything else requires an explicit `import` statement.

**Prelude types** (always available):

| Category | Types |
|----------|-------|
| Primitives | `Int`, `Float`, `Bool`, `Str`, `None` |
| Collections | `List`, `Dict`, `Set` |
| Results | `Result`, `Ok`, `Err` |
| Special | `Never` |

**Prelude functions** (always available): `print`, `input`, `len`, `str`, `int`, `float`, `bool`, `range`, `abs`, `min`, `max`, `sorted`, `map`, `filter`, `reduce`, `any`, `all`, `sum`, and others.

**Non-prelude types require imports.** If you use `Json`, `Path`, `Clock`, `Rng`, `Decimal`, or any other stdlib type, you must import the owning module. The compiler tells you which module to import:

```text
error: Type 'Json' requires 'import json'
```

Common imports:

| Type | Required import |
|------|-----------------|
| `Json`, `JsonValue`, `JsonError` | `import json` |
| `Decoder`, `DecodeError` | `import json` |
| `Path` | `import path` |
| `ReadPath`, `WritePath`, `DirPath` | `import fs` |
| `Clock`, `Duration`, `Date`, `Instant` | `import time` |
| `Rng` | `import random` |
| `TemplateEngine`, `TemplateError` | `import template` |
| `HttpResponse`, `HttpError` | `import http` |
| `Decimal` | `import decimal` |
| `Money` | `import money` |
| `Url` | `import url` |
| `CryptoHash` | `import crypto` |
| `Command`, `ProcessResult` | `import process` |

This makes dependencies visible: you can tell which modules a file uses by reading its import block.

## Imports

```vary-snippet
import math_utils
import math_utils as m
from math_utils import square, cube
from math_utils import square as sq
```

Modules are files. A file `math_utils.vary` defines module `math_utils`.

## Access control

Names starting with `_` are private and not exported:

```vary
def public_func() -> Int {
    return _helper()
}

def _helper() -> Int {
    return 42
}
```

## Controlling exports

By default, all non-underscore names are exported. Use `__all__` to restrict:

```vary
let __all__ = ["public_func", "CONSTANT"]

def public_func() -> Int {
    return 42
}

def internal_func() -> Int {
    return 0
}

let CONSTANT: Int = 100
```

Only `public_func` and `CONSTANT` are importable from this module.

## Relative imports

Use dots to import relative to the current file's directory:

```vary-snippet
from .sibling import helper          # same directory
from ..parent_module import Config   # parent directory
from .subpkg.util import format      # subdirectory
```

One dot (`.`) means the current directory, two dots (`..`) means the parent, and so on. Relative imports only resolve within the project - they cannot escape the module root.

## Module root discovery

The compiler finds the module root by walking up from the entry file until it finds a `vary.toml` file or the filesystem root. All absolute imports (e.g., `import utils`) resolve relative to this root. If no `vary.toml` exists, the entry file's directory is the root.
