1---
2title: Helm charts
3description: Install Helm charts with Kubernetes.HelmChart. Covers repository, OCI, and local charts, values, release names, namespaces, CRDs, hooks, and how Alchemy owns the rendered objects instead of a Helm release.
4---
5
6[`Kubernetes.HelmChart`](/providers/kubernetes/helmchart) installs a
7Helm chart as one resource. Alchemy renders the chart with the local
8`helm` CLI (`helm template`) and applies the rendered objects with
9the same server-side apply machinery as a
10[Manifest](/kubernetes/objects/manifests).
11
12```typescript
13const metricsServer = yield* Kubernetes.HelmChart("MetricsServer", {
14 cluster,
15 chart: "metrics-server",
16 repo: "https://kubernetes-sigs.github.io/metrics-server/",
17 version: "3.14.0",
18 releaseName: "metrics-server",
19 namespace: "kube-system",
20 values: { replicas: 2 },
21});
22```
23
24## Requirements
25
26Install [`helm`](https://helm.sh/docs/intro/install/) on every
27machine that deploys, including CI runners. Set `HELM_BIN` to use a
28binary that isn't on `PATH`. Helm never connects to the cluster.
29Rendering is local, and Alchemy does the applying.
30
31## Chart sources
32
33- **Classic repository.** Set `chart` to the chart name, for example
34 `"metrics-server"`. Also set `repo` and `version`.
35- **OCI registry.** Set `chart` to an `oci://` reference, for
36 example `"oci://ghcr.io/stefanprodan/charts/podinfo"`. Also set
37 `version`.
38- **Local directory.** Set `chart` to a path such as
39 `"./charts/app"`.
40
41Pin `version` for repository and OCI charts. Without it, Helm
42renders the newest version on each deploy, and what's applied changes
43whenever the chart publishes. Local charts are hashed file by file,
44so editing a template triggers an update on the next deploy.
45
46## Values
47
48`values` is a literal object in the shape of the chart's
49`values.yaml`:
50
51```typescript
52const podinfo = yield* Kubernetes.HelmChart("Podinfo", {
53 cluster,
54 chart: "oci://ghcr.io/stefanprodan/charts/podinfo",
55 version: "6.15.0",
56 releaseName: "podinfo",
57 namespace: ns.name,
58 values: {
59 replicaCount: 2,
60 ui: { message: "rendered by Alchemy" },
61 redis: { enabled: true },
62 },
63});
64```
65
66Values can include Outputs from other resources. Any change to the
67values, chart, version, or release name re-renders the chart on the
68next deploy.
69
70## Release name and namespace
71
72The release name is what the chart's templates see as
73`.Release.Name`, and most charts name their objects after it. Without
74`releaseName`, Alchemy generates one from the stack, stage, and
75logical ID. The generated name is at most 53 characters, which is
76Helm's limit. Set it explicitly when you want predictable object
77names.
78
79`namespace` (default `default`) is `.Release.Namespace`, and Alchemy
80also sets it on any namespaced object the chart leaves without one.
81The namespace must exist, or set `createNamespace: true` to have the
82resource create and own the Namespace object.
83
84Changing `releaseName`, `namespace`, or `cluster` replaces the chart.
85Alchemy applies the new render, then deletes every object from the
86old one.
87
88:::caution[Objects with fixed names]
89Some charts give objects names that don't include the release name.
90Examples are metrics-server's `v1beta1.metrics.k8s.io` APIService,
91CRDs, and webhook configurations. When a replacement renders those
92same objects again, deleting the old render removes them. Choose
93`releaseName` and `namespace` before the first deploy. If you do
94change them, run `alchemy deploy --force` afterwards to apply the
95missing objects again.
96:::
97
98## CRDs
99
100Objects in the chart's `crds/` directory are rendered too
101(`includeCrds` defaults to `true`). Alchemy applies Namespaces first,
102then CRDs, then everything else, so a chart's own custom resources
103find their definitions. Set `includeCrds: false` when the CRDs are
104managed elsewhere.
105
106## Hooks aren't run
107
108The chart is rendered with `--no-hooks`. Objects annotated with
109`helm.sh/hook` are neither applied nor run. These include install
110and upgrade Jobs and test pods. Some charts depend on hooks to work
111correctly, for example to run database migrations or generate
112certificates. Install those charts with Helm itself.
113
114## No Helm release
115
116Alchemy doesn't create a Helm release. `helm list` won't show the
117chart, and `helm upgrade` or `helm rollback` don't apply. Alchemy
118records every object it applied and, on each update:
119
120- applies the new render,
121- deletes objects that were in the previous render but not in the
122 new one,
123- on destroy, deletes every object it applied.
124
125To move a chart that's currently installed with `helm install` under
126Alchemy, run `helm uninstall` first, then deploy the `HelmChart`.
127
128## Attributes
129
130- `releaseName` is the release name the chart rendered with.
131- `namespace` is the namespace the chart rendered into.
132- `chart` is the chart reference.
133- `version` is the pinned version, if any.
134- `objects` holds references to every applied object.
135- `connection` is the cluster connection.
136
137## Where next
138
139- **[Tutorial part 4](/kubernetes/tutorial/part-4).** Install
140 metrics-server on a kind cluster.
141- **[How objects are managed](/kubernetes/workloads/object-lifecycle).**
142 Apply order, pruning, and drift.
143- **[`HelmChart` reference](/providers/kubernetes/helmchart).** Every
144 prop and attribute.