Helm’s library charts are a clever way to avoid repeating yourself, letting you define common configurations and templates in one place and reuse them across multiple Helm charts.

Let’s see it in action. Imagine you have a standard Kubernetes Service definition that you want to apply to several of your microservices. Instead of copying and pasting the YAML into each chart’s templates/ directory, you can extract it into a library chart.

First, create a new Helm chart specifically for your shared templates. Let’s call it common-templates.

helm create common-templates

Inside the common-templates chart, navigate to the templates/ directory. Here, you’ll create a new file, say _helpers.tpl, for your shared logic. Helm uses files starting with _ to indicate they contain partial templates and shouldn’t be rendered directly.

In common-templates/templates/_helpers.tpl, you might define a template for a common Service object:


{{/*

Create a common Service object.
*/}}

{{- define "mychart.service" -}}

apiVersion: v1
kind: Service
metadata:

  name: {{ include "mychart.fullname" . }}

  labels:

    {{- include "mychart.labels" . | nindent 4 }}

spec:

  type: {{ .Values.service.type }}

  ports:

    - port: {{ .Values.service.port }}

      targetPort: http
      protocol: TCP
      name: http
  selector:

    {{- include "mychart.selectorLabels" . | nindent 4 }}


{{- end -}}

This template uses standard Helm templating functions. include "mychart.fullname" . and include "mychart.labels" . are examples of common helper templates that Helm charts often generate by default. We’re assuming these will also be available or defined in the charts that use this library chart.

Now, in your application charts (e.g., my-app-1, my-app-2), you need to tell Helm to include your common-templates library. You do this by adding an entry to the requirements.yaml file of each application chart.

For my-app-1/requirements.yaml:

dependencies:
  - name: common-templates
    version: "0.1.0" # Use the version you published or linked
    repository: "file://../common-templates" # Or a Helm repository URL

The repository field can point to a local path (as shown above, assuming common-templates is in the parent directory) or to a Helm repository where you’ve published your library chart.

After updating requirements.yaml, run helm dependency update in the directory of your application chart (my-app-1/). This downloads the dependency.

Now, in my-app-1/templates/service.yaml, you can use the shared template:


{{ include "mychart.service" . }}

This single line tells Helm to render the mychart.service template defined in your common-templates library chart. You’ll also need to ensure that the values required by the mychart.service template (like service.type and service.port) are defined in my-app-1/values.yaml.

my-app-1/values.yaml:

service:
  type: ClusterIP
  port: 80

The mental model here is that Helm charts can have dependencies on other charts. When helm template or helm install is run, Helm first resolves all dependencies, effectively merging the templates and values from the dependent charts into the main chart’s rendering context. This allows for a hierarchical structure where core components can be defined once and consumed by many.

One subtle but powerful aspect is how values are merged. When you run helm install -f my-app-1/values.yaml --values my-app-1/common-templates/values.yaml, Helm merges these values. If a value is defined in both my-app-1/values.yaml and my-app-1/common-templates/values.yaml, the values from the chart being installed (my-app-1) take precedence. This allows you to override or customize the shared configurations for specific applications without altering the library chart itself.

The next step in mastering Helm’s reusable components is exploring how to manage complex dependencies and versioning across multiple library charts.

Want structured learning?

Take the full Helm course →