> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ubiquex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Modules

> Reusable infrastructure components — local directories, git sources, and the Strata registry.

Modules are reusable infrastructure components. They accept inputs, create resources, and expose outputs — just like a stack, but callable from other stacks.

## Declaring a module

```xcl theme={"theme":"css-variables","languages":{"custom":["/languages/xcl.json"]}}
module "networking" {
  source  = "./modules/vpc"
  version = "1.0.0"

  // input values
  vpc_cidr = input.vpc_cidr
  env      = input.env
}
```

The `source` field determines where the module comes from.

## Source schemes

### Local directory

```xcl theme={"theme":"css-variables","languages":{"custom":["/languages/xcl.json"]}}
module "vpc" {
  source = "./modules/vpc"
}
```

Resolves relative to the stack file's directory.

### GitHub

```xcl theme={"theme":"css-variables","languages":{"custom":["/languages/xcl.json"]}}
module "vpc" {
  source  = "github://my-org/my-modules//vpc"
  version = "v1.2.0"
}
```

### Strata registry

```xcl theme={"theme":"css-variables","languages":{"custom":["/languages/xcl.json"]}}
module "eks" {
  source  = "strata://ubiquex/eks-platform"
  version = "2.1.0"
}
```

The Strata registry is at `strata.ubiquex.io`. Components published with `ubx publish` are available via the `strata://` scheme.

## Module directory structure

A module is a directory containing `.xcl` files with `input`, `output`, and resource declarations:

```
modules/vpc/
├── main.xcl
└── outputs.xcl
```

**`modules/vpc/main.xcl`:**

```xcl theme={"theme":"css-variables","languages":{"custom":["/languages/xcl.json"]}}
input "vpc" {
  vpc_cidr: string = "10.0.0.0/16"
  env:      string = "dev"
  az_count: int    = 2
}

stack "vpc" {
  vpc = aws.ec2.Vpc {
    cidr_block = input.vpc_cidr
    tags       = { Name = "${input.env}-vpc" }
  }

  public_subnets = aws.ec2.Subnet {
    for i in range(input.az_count)

    vpc_id     = vpc.id
    cidr_block = cidrsubnet(input.vpc_cidr, 8, i)
  }
}
```

**`modules/vpc/outputs.xcl`:**

```xcl theme={"theme":"css-variables","languages":{"custom":["/languages/xcl.json"]}}
output vpc_id {
  value = vpc.id
}

output subnet_ids {
  value = public_subnets.id
}
```

## Using module outputs

Reference module outputs with dot notation:

```xcl theme={"theme":"css-variables","languages":{"custom":["/languages/xcl.json"]}}
module "networking" {
  source   = "./modules/vpc"
  vpc_cidr = "10.0.0.0/16"
}

stack "platform" {
  eks = aws.eks.Cluster {
    vpc_config {
      vpc_id     = module.networking.vpc_id      // Pending<string>
      subnet_ids = module.networking.subnet_ids  // Pending<list<string>>
    }
  }
}
```

Module outputs are `Pending<T>` — they resolve at apply time like resource outputs.

## Publishing a module

Publish to the Strata registry:

```bash theme={"theme":"css-variables","languages":{"custom":["/languages/xcl.json"]}}
ubx publish ./modules/vpc \
  --name ubiquex/vpc \
  --version 1.0.0
```

Requires a `STRATA_TOKEN` environment variable or `--token` flag.

## Validation

The typechecker validates:

* Module source paths exist (for local sources)
* Input fields passed to the module match the module's declared inputs
* Output references are declared in the module's `output` blocks
