mrkeyoor.com_
Fri 02 Oct 14:58 UTC
Dev Toolsevaluationupdated 02 Oct 2026

hcl review

HCL is a Go toolkit for designing configuration languages with named attributes, nested blocks, expressions, variables, and functions chosen by the application. It gives people a readable native syntax while preserving a JSON form for machine-generated configuration.

Verdict

Our HCL run passed all 36 tests after a 93-second install and 32-second build, so the library clears the basic engineering check cleanly. Use it when your product needs its own configuration vocabulary, expressions, and diagnostics. Choose a plain decoder when configuration is merely data, because HCL makes your team responsible for language design as well as parsing.

We ran it

Lab card: what happened when we ran hclScreenshot of hcl (github.com/hashicorp/hcl)
Install✓ · 93s22 packages
Build✓ · 32s
Tests✓ · 23s36 passed · 0 failed of 36 (go test)
Repo379 files~66,546 lines of source · 2.2 MB · 2 CI workflows

Answers from our run

Does hcl build from source?

Dependencies installed in 93 seconds (22 packages), and the build succeeded in 32 seconds. We cloned commit 4c31772 into a clean Debian container with 3 CPUs and no project-specific setup.

Do hcl's tests pass?

Yes: 36 of 36 passed when we ran the project's own test command (go test). Some failures need services or credentials a bare container does not have.

Who should not use hcl?

Applications that only need ordinary settings loaded into a struct: TOML, YAML, or JSON carries less language-design work.

What are the alternatives to hcl?

CUE, BurntSushi TOML, Koanf. Our HCL run passed all 36 tests after a 93-second install and 32-second build, so the library clears the basic engineering check cleanly.

Setup5/522 packages, clean build, and 36 of 36 tests passed
Docs4/5Clear concepts and specs, though API choices require GoDoc reading
Community5/55,811 stars with September issues and an October push
Maturity5/5Version 2.25.0, a stable Go module, and a clean lab run

Discussed on

  1. hnHCL: Toolkit for Structured Configuration Languages27 points
  2. hnHashiCorp Configuration Language3 points

Who it’s for

Go developers building a configuration language for a command-line tool, server, or infrastructure product.
Teams that need application-defined blocks and expressions instead of plain key-value decoding.
Tool authors who want native HCL and JSON inputs to share one information model.
Products that need source ranges and useful diagnostics from partially valid configuration.

Who it’s NOT for

Applications that only need ordinary settings loaded into a struct: TOML, YAML, or JSON carries less language-design work.
Non-Go projects seeking a first-party parser in their own runtime: this repository's public implementation and examples are Go modules.
HCL 1 users expecting a direct upgrade: the README says HCL 2 has a new parser and incompatible Go API with no direct migration path.
Services parsing hostile, unbounded input without an outer limit: open issue 809 reports that deeply nested parentheses can cause an unrecoverable Go stack overflow.
Rewriters that assume every hclwrite traversal edit is settled: issue 840 reports missed variables and renames inside object values.

Setup reality

Our run installed commit 4c31772 in 93 seconds and fetched 22 packages. The build succeeded in 32 seconds. Tests finished in 23 seconds with 36 passed and 0 failed, giving HCL a clean result in our fresh container.

HCL is a Go module, not a service. The caller must define valid attributes and blocks, supply any variables or functions used by expressions, and decide whether to decode into structs or use the lower-level APIs. HCL 2 requires Go Modules and cannot be dropped into an HCL 1 import unchanged.

The checkout was 2.2 MB with 379 files and about 66,546 source lines. We found 2 CI workflows, no Dockerfile, and no tests directory. Release v2.25.0 sets Go 1.25 in go.mod; our measured sandbox used the golang:1.24-bookworm image.

HCL is for designing a language, not loading a settings file

HCL starts to make sense when a product needs its own vocabulary. The application declares which attributes and nested blocks are valid, then HCL parses the file against that structure and returns values plus diagnostics. A server might accept a service block with protocol labels and nested process blocks. That is more expressive than decoding a generic map, and more work than reading a TOML file into a struct.

The choice should follow the product, not Terraform's familiarity. If users only set a port, log level, and database URL, HCL adds syntax decisions they do not need. If they describe resources, policies, jobs, or relationships, named blocks and labels can make the file match the problem. Your team still owns the resulting language: allowed names, evaluation context, error messages, compatibility, and documentation.

One model accepts native HCL and JSON

HCL has a native syntax for people and a JSON representation for software that generates files. Both forms map into the same attributes-and-blocks model. That gives a tool a hand-edited format without forcing an automation system to print native syntax. JSON strings can also contain interpolation expressions, so generated input can reach the same evaluator when the application permits it.

Expressions are not an unrestricted program hidden inside the file. HCL supplies parsing and evaluation machinery, while the calling application decides which variables and functions exist. This boundary is useful for a domain-specific language because the host can expose upper() or a resource reference without embedding a general-purpose runtime. It also creates an API-design duty: an expression valid in one HCL-based product may be meaningless in another.

What happened when we ran it

Our sandbox installed commit 4c31772 in 93 seconds and fetched 22 packages. The build completed in 32 seconds. Testing took another 23 seconds, with 36 passed and 0 failed out of 36. The fresh Debian container had 3 CPUs, 8 GB of RAM, Go 1.24, no credentials, and no elevated privileges.

The checkout contained 379 files, about 66,546 lines of source, and occupied 2.2 MB. Our scan found 2 CI workflow files, no Dockerfile, and no tests directory. A Dockerfile is unnecessary for a Go library, and the passing test command matters more than a directory name. The result is a small checkout with a modest dependency count and a clean build-and-test path.

These numbers cover repository mechanics. They do not measure parser throughput, memory use on large files, diagnostic quality for your schema, or the cost of evaluating expressions. We did not invent a sample language and benchmark it. HCL passed the supplied 36-test run; a buyer still needs fixtures drawn from the configuration its own users will write.

The simple decoder and lower-level APIs serve different jobs

The README's short example uses hclsimple.DecodeFile and Go struct tags. That route works when the file shape is known and the program wants typed values. HCL also exposes lower-level parsing, content selection, decoding, and evaluation for editors, partial configuration, or tools that need to keep working after a user makes a syntax mistake. Start with the simple path unless a concrete feature requires more control.

Writing and refactoring deserve separate tests. Release v2.25.0 added comment accessors and setters for attribute and block changes in hclwrite. Open issue 840 reports that variable discovery and prefix renaming miss traversals inside certain object values after a recent change. Issue 844 reports an error from JustAttributes after PartialContent hides a nested block. If your product edits users' files, round-trip fixtures should cover every expression shape it rewrites.

HCL 2 is a separate Go API, not an HCL 1 upgrade

The module path is github.com/hashicorp/hcl/v2, and the README says version 2 cannot be imported by a Go project that does not use Go Modules. Its parser and Go API are incompatible with version 1, with no direct migration path. Both major versions can exist in one module through semantic import versioning, which helps a staged migration but does not perform one.

Release v2.25.0 moved the module's compatibility target from Go 1.24 to Go 1.25. Our October 1 sandbox used a Go 1.24 image and completed its measured commands, while the current go.mod declares Go 1.25. New adopters should follow the module declaration rather than treating our container label as a support promise. Pin HCL and the Go toolchain together in CI.

Deeply nested input needs an outer limit

Issue 809 reports that enough nested parentheses can overflow the Go stack in the recursive-descent parser. The report says this ends the process with a fatal error that recover() cannot catch. That is a specific concern for a service accepting configuration from untrusted users. Limit upload size and nesting before parsing, then run adversarial fixtures against the exact HCL version you ship.

This warning does not cancel the clean result from our 36 tests. It defines where those tests stop. HCL's parser gives product teams a strong base for a human-facing language, but the host remains responsible for resource limits and accepted semantics. A local CLI reading files from its operator faces a different risk than a multi-tenant API parsing anonymous submissions.

The September release and October push show active maintenance

GitHub showed 5,811 stars and 233 combined issues and pull requests on October 2, 2026. A search of the tracker returned 176 open issues, including reports updated in late September. The repository was pushed on October 1. Release v2.25.0 shipped on September 15 with Go 1.25 compatibility, hclwrite additions, parser recovery fixes, and a dependency update.

HCL is the practical choice for a Go product whose configuration needs blocks, labels, expressions, and source-aware diagnostics. The 93-second install and 55 seconds of build plus tests were uneventful in our run. The expensive part comes later: once users write this language, its syntax and behavior become an interface your product must preserve.

Alternatives

ProjectWhat it isPick it when
CUEA configuration language and toolchain that combines values, schemas, constraints, and generation.pick this instead when validation and schema constraints should live in the configuration language itself.
BurntSushi TOMLA Go TOML parser and encoder for straightforward typed configuration files.pick this instead when users need readable settings, not a custom block and expression language.
KoanfA Go configuration library that merges files, environment variables, flags, and other providers.pick this instead when the hard problem is combining configuration sources rather than inventing syntax.

What people are saying

  1. [github-trending] hashicorp/hcl

Sources

  1. HCL repository and README
  2. HCL v2 package documentation
  3. HCL v2.25.0 release notes
  4. HCL issue 809: deeply nested parser stack overflow
  5. HCL issue 840: hclwrite traversal regression

More dev tools reviews

touchHLE · effect · SwitchHosts · Duo-animation · DuoLikeAnimation · team-Omzo · the whole board →