Self-hosted service
hairyhenderson/gomplate avatar
hairyhenderson/gomplate

gomplate: a Go template renderer that pulls data from files, HTTP, Vault and Consul

A flexible commandline tool for template rendering. Supports lots of local and remote datasources.

3,209 stars220 forksGoMIT

At a glance

What is it?
gomplate renders Go templates with datasources defined as URLs, so a config file, an HTTP endpoint or a Vault secret can feed the same template. Here is how it installs, how the datasource mechanism works, and where it stops being the right tool.
Who is it for?
gomplate fits teams that already render Go templates and need the same template to read from a file, an HTTP endpoint, Vault or Consul without writing glue code. It is the wrong tool when your templates are Jinja2 or Handlebars, or when you need a long-running service rather than a one-shot render.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The gap gomplate fills between a template file and its data

Go's text/template package renders a template against data you already hold in memory. In practice the data lives somewhere else: a YAML file, an HTTP API, a Vault secret path, Consul's key-value store. Wiring those into a Go program means writing the same loader code for every project. gomplate is that loader wrapped in a CLI. You point it at a template, describe each data source as a URL, and it resolves everything before rendering.

The README frames the tool as a template renderer supporting a growing list of datasources, naming JSON (including EJSON, encrypted JSON), YAML, AWS EC2 metadata, Hashicorp Consul and Hashicorp Vault secrets. The audience is sysadmins, DevOps and platform engineers who generate config files, and anyone who wants a shell-friendly way to format structured data without writing a program. The repository topics list confirms the same shape: boltdb, cli, cloud, config, consul, devops, docker, golang, sysadmin, sysops, template, templating, vault.

Datasources as URLs: the mechanism behind -d and ds

A datasource is declared with -d, or its long form --datasource, and given a name and a URL. Inside the template you read it with the ds function, or the longer datasource alias. The README example defines config as ./config.yaml and then reaches into it with (datasource "config").foo.bar.baz. The name is yours; the URL is what determines how the bytes are fetched and parsed.

Because the source is a URL, the same template can read from a local path, standard input, an environment variable or a remote endpoint. The README shows stdin:///in.json for piped JSON, env:///CITIES?type=application/yaml for an environment variable parsed as YAML, and a plain https:// URL for a remote service. The type query parameter tells gomplate how to parse content when the source does not make it obvious. HTTP headers are set with -H, demonstrated as -H 'weather=User-Agent: curl', which scopes the header to that named datasource rather than applying it globally.

Rendering itself is Go's templating syntax, so the built-in actions (range, if, eq, include) behave as they do in a Go program. On top of that gomplate adds its own function set: the README uses mul, seq, toUpper and add. The repository layout mirrors that split, with directories named math, strings, coll, conv, crypto, net, regexp, time and random, each holding a function namespace. The include function renders a named template, which is how the README's weather example loops over cities and calls a second template per city.

Installing gomplate and rendering a first template

The README does not carry install instructions; it links to docs.gomplate.ca/installing, and the badges reference a Chocolatey package named gomplate and a Docker Hub repository at hairyhenderson/gomplate. Those are the channels the project itself advertises, so start there for your platform rather than guessing at a package name.

Once the binary is on your PATH, the smallest useful invocation reads a template from a file. The README shows -f for the template file and -i for an inline template string. This one renders an inline expression and prints the result:

bash
gomplate -i 'the answer is: {{ mul 6 7 }}'

The output is a single line, the answer is: 42. No datasource is involved, which makes it a quick way to confirm the binary runs and the function set is available.

The next step is a real datasource. Given a config.yaml containing foo.bar.baz, declare it with -d and read it with datasource:

bash
gomplate -d config=./config.yaml -i 'the value we want is: {{ (datasource "config").foo.bar.baz }}'

The rendered line is the value we want is: qux. Note that the datasource name config is arbitrary; it is the key you use inside the template. A remote source follows the same pattern, as in -d ip=https://ipinfo.io with (ds "ip").country, and standard input works through the stdin:/// scheme, which is useful inside a pipeline where the JSON is produced by another command.

Where gomplate is the wrong tool

The template language is Go's, and that is not negotiable. If your existing templates are Jinja2, Handlebars or ERB, gomplate will not render them, and porting a large template tree to Go syntax is real work, not a configuration change. Teams that pick gomplate because of its datasource list sometimes discover this after the fact.

Error reporting is the other friction point. A datasource that fails to resolve, a URL with a typo in the scheme, or a template that references a key the data does not contain all surface as render failures. The README does not document retry behaviour, caching, or how a partial failure mid-render is reported, so for pipelines where a flaky HTTP datasource is expected, plan to handle the exit status yourself rather than assume gomplate will retry.

Finally, gomplate is a one-shot renderer, not a service. It reads, renders and exits. If you need a long-running process that watches a source and re-renders on change, gomplate alone does not do that; you would drive it from a supervisor, a cron job or an init container. The README and repository layout give no indication of a watch mode.

gomplate against plain Go templates and against confd

The closest comparison is the thing gomplate wraps: Go's own text/template. If your data already lives in memory inside a Go program, using text/template directly removes a process boundary and a binary dependency. gomplate earns its place when the data is external and the caller is a shell script, a Makefile or a container entrypoint, because it turns URL fetching and format detection into a command-line argument instead of code. The trade is that you inherit gomplate's function set and its datasource semantics rather than controlling parsing yourself.

The other comparison worth making is with confd-style tools that watch a backend and rewrite config files on change. Those are daemons; gomplate is not. If your requirement is "re-render when Consul changes," a daemon is the natural fit and gomplate is the piece you would call from it. If your requirement is "render once at container start from whatever the environment provides," gomplate is the smaller dependency. The repository's Dockerfile reflects that second use case: the image is built FROM scratch with only the CA certificates and the gomplate binary copied in, with ENTRYPOINT [ "/gomplate" ], so the container does exactly one thing.

Maintenance, licence and the cost of upgrading

The repository is not archived, and the last push was on 2026-09-23, one day before this writing. Releases have been regular through the 5.x line: v5.0.0 on 2026-01-21, v5.1.0 on 2026-05-02, v5.2.0 on 2026-07-12. The project uses release-please, visible as .release-please-manifest.json and release-please-config.json in the repository root, so version bumps and changelog entries follow an automated flow and CHANGELOG.md is the place to look before upgrading.

The build pins its toolchain in go.mod with go 1.26.0 and toolchain go1.27.1, and the Dockerfile builds on golang:1.27-alpine. That is a tight coupling: upgrading gomplate means accepting a specific Go toolchain for source builds, though prebuilt binaries and the published image avoid that entirely. The dependency list is broad, including the AWS SDK v2, the Vault API with AWS and Kubernetes auth, k8s.io/client-go and cuelang.org/go, which is the price of the datasource breadth and also the surface that security scanners will flag.

The licence is MIT, stated in the README and present as the LICENSE file. MIT is permissive and imposes no copyleft obligation on your templates or config output. That is a factual note about the licence text, not legal advice; if you redistribute a modified gomplate, read the LICENSE file and the copyright line yourself.

Editorial conclusion

gomplate fits teams that already render Go templates and need the same template to read from a file, an HTTP endpoint, Vault or Consul without writing glue code. It is the wrong tool when your templates are Jinja2 or Handlebars, or when you need a long-running service rather than a one-shot render. Before adopting it, check the install page at docs.gomplate.ca/installing for the package that matches your platform, and confirm that the datasource scheme you depend on is one the project documents, since the README only names JSON, EJSON, YAML, AWS EC2 metadata, Consul and Vault.

Frequently asked questions

What is a Go template?

It is the templating syntax built into the Go standard library, using actions such as range, if and eq inside double braces. gomplate renders that same syntax and adds its own functions on top, so the README can use mul, seq, toUpper and add alongside the standard actions.

How do you use gomplate to render a template with a datasource?

Declare the source with -d name=URL, then read it in the template with the ds or datasource function, as in (datasource "config").foo.bar.baz for a file named config.yaml. The template itself is passed with -f for a file or -i for an inline string.

How does gomplate differ from plain Go templates?

gomplate uses Go's templating syntax but adds a CLI, a large function set (mul, seq, toUpper, add and others) and datasources declared as URLs, so data can come from files, stdin, environment variables, HTTP, Consul or Vault without writing loader code. Plain text/template renders only against data your Go program already holds.

Is there a gomplate extension for VS Code?

The README does not mention a VS Code extension, and the repository layout shows no editor plugin directory. The project points readers to the documentation at docs.gomplate.ca and to the #gomplate channel on Gophers Slack for help.

Official sources

  1. hairyhenderson/gomplate on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hairyhenderson-gomplate.svg)](https://hysenlabs.com/projects/hairyhenderson-gomplate)