> ## Documentation Index
> Fetch the complete documentation index at: https://akua-1dce587a.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Typed resources

> Type every resource a Package emits against a pinned Kubernetes version and the CRDs it depends on

Every Package that `akua pkg init` scaffolds is typed against one Kubernetes version, and every CustomResourceDefinition you add as a dependency becomes a typed schema. A misspelled field, a wrong type, a value outside an enum or an API your Kubernetes version does not serve fails the render with the file and line, before anything reaches a cluster.

This guide assumes the `akua` CLI is installed (`brew install akua-dev/tap/akua`). Every command also works with the standalone `akuapkg` binary.

**1. Scaffold a typed Package**

`init` declares the Kubernetes 1.35 schemas in `akua.toml`, pins them by digest in `akua.lock`, and writes a `package.k` that uses them:

```bash theme={null}
akua pkg init hello
cd hello
```

**2. Add a CRD dependency**

`add` downloads the CRDs, pins their `sha256` and generates KCL schemas into `.akua/crds/`:

```bash theme={null}
akua pkg add cert-manager --url https://github.com/cert-manager/cert-manager/releases/download/v1.16.0/cert-manager.crds.yaml
```

The output names the modules to import, for example `import crds.cert_manager.cert_manager_io.v1 (Certificate, CertificateRequest, ClusterIssuer, Issuer)`.

**3. Use the typed schemas**

Replace `package.k` with a typed ConfigMap and a typed Certificate:

```python theme={null}
import akua.ctx
import k8s.api.core.v1 as corev1
import crds.cert_manager.cert_manager_io.v1 as certmanager

schema Input:
    appName: str
    replicas: int = 2
    host: str = "hello.example.com"

input: Input = ctx.input()

resources = [
    corev1.ConfigMap {
        metadata.name = input.appName
        data.replicas = str(input.replicas)
    }
    certmanager.Certificate {
        metadata.name = input.appName
        spec = {
            secretName = "${input.appName}-tls"
            dnsNames = [input.host]
            issuerRef = {name = "letsencrypt", kind = "ClusterIssuer"}
            privateKey.algorithm = "ECDSA"
        }
    }
]
```

**4. Render**

```bash theme={null}
akua pkg render --inputs inputs.example.yaml
```

The render writes two manifests to `./deploy`. Commit `akua.toml`, `akua.lock` and `.akua/crds/`.

## What a mistake looks like

Change `"ECDSA"` to `"ECDSB"` and render again:

```text theme={null}
error[E2G22]: TypeError
---> File package.k:23:24: expected str(RSA) | str(ECDSA) | str(Ed25519), got str(ECDSB)
```

Misspelled fields fail with a suggestion (`Cannot add member 'secretname' to schema 'CertificateSpec', did you mean ...`), and a number where Kubernetes expects a string fails with `expected str, got int`. Every one of these exits with code 1 and error code [`E_RENDER_KCL`](https://akua-1dce587a.mintlify.site/akua/errors/E_RENDER_KCL).

## Kubernetes versions

The default is the oldest Kubernetes minor version still supported upstream, 1.35, so what renders applies to every supported cluster.

| To | Run |
| - | - |
| Scaffold against another version | `akua pkg init my-app --k8s 1.33`, then `akua pkg lock` |
| Switch an existing Package | `akua pkg add k8s --k8s 1.36 --force` |
| Check the lock in CI | `akua pkg lock --check` |

A version switch type-checks the whole Package against the new release: an API it no longer serves, such as `flowcontrol.apiserver.k8s.io/v1beta3` from Kubernetes 1.32 on, fails the render.

## CRD sources

Any dependency source works, with `crds = true` for the whole source or a path inside it:

```bash theme={null}
# A release asset (implies crds = true)
akua pkg add cert-manager --url https://github.com/cert-manager/cert-manager/releases/download/v1.16.0/cert-manager.crds.yaml
# A git tag, narrowed to a directory
akua pkg add prometheus --git https://github.com/prometheus-operator/prometheus-operator --tag v0.80.0 --crds example/prometheus-operator-crd
# A Helm chart in an OCI registry
akua pkg add cnpg-crds --oci oci://ghcr.io/cloudnative-pg/charts/cloudnative-pg --version 0.22.1 --crds .
# A Helm chart in an HTTPS repository
akua pkg add jetstack --repo https://charts.jetstack.io --chart cert-manager --version v1.16.0 --crds templates
# A local directory
akua pkg add widgets --path ./widgets --crds .
```

Imports follow `crds.<dependency>.<group>.<version>`, with `-` and `.` turned into `_`. The generated `.akua/crds/` directory is committed; a render that finds it out of date with `akua.toml` or `akua.lock` fails with [`E_CRDS_STALE`](https://akua-1dce587a.mintlify.site/akua/errors/E_CRDS_STALE) until you run `akua pkg lock`.

The conversion rules, naming details and known limits are in the upstream [typed resources guide](https://github.com/akua-dev/akua/blob/main/docs/typed-resources.md).

## Related topics

> **[Why typed and sandboxed](https://akua-1dce587a.mintlify.site/akua/why.md)**
>
> The problems with untyped templates and unsandboxed renderers.

> **[Package format](https://akua-1dce587a.mintlify.site/akua/package-format.md)**
>
> The `Input` schema, `@ui` annotations and composition.

> **[akua pkg add](https://akua-1dce587a.mintlify.site/akua/cli/add.md)**
>
> Every flag of the command that adds dependencies.

> **[Example: typed CRDs](https://github.com/akua-dev/akua/tree/main/examples/16-typed-crds)**
>
> A runnable Package with Kubernetes types and a CRD from a git tag.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.