HCL and HOCON are two configuration languages you will encounter in infrastructure and application development — HCL in the HashiCorp ecosystem (Terraform, Packer, Vault) and HOCON in the JVM ecosystem (Akka, Play Framework, Lightbend tools). Both were created to solve the same problem — JSON is too verbose and unreadable for complex configuration — but they take different approaches and are not interchangeable. This guide explains both formats from the ground up: what they look like, where they are used, how they compare, and when to choose each one.
What is an HCL file?
HCL stands for HashiCorp Configuration Language. It is a domain-specific configuration language created by HashiCorp in 2014, initially to support Terraform. HCL files use the `.hcl` extension (or `.tf` for Terraform specifically) and are designed to be human-readable, machine-parseable, and compatible with JSON — every valid JSON document is also valid HCL.
HCL is not a programming language. It cannot perform computation, define functions, or control program flow in the way that Python or JavaScript can. It is a declarative configuration language: you describe the desired state of infrastructure, and the tool that reads the HCL (Terraform, Packer, Vault, Consul, Nomad) determines how to achieve it. This constraint is intentional — it makes HCL configs predictable and auditable.
HCL syntax fundamentals
HCL uses a block-based structure with attributes, nested blocks, and expressions. Attributes are key-value pairs; blocks group related attributes and can be nested. Comments use `#` or `//` for single-line and `/* */` for multi-line.
# Single-line comment
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "web-server"
Environment = "production"
}
# Nested block
root_block_device {
volume_size = 20
encrypted = true
}
}Where HCL is used
- Terraform — the primary HCL consumer; every `.tf` file is HCL describing cloud and on-premises infrastructure.
- Packer — HCL2 (the v2 of the language) is used to define machine image builds for AWS AMIs, GCP images, and others.
- Vault — HCL is used for policy files that define access control rules in HashiCorp Vault.
- Consul — service mesh configuration files, health checks, and service definitions use HCL.
- Nomad — workload orchestration job specifications are written in HCL.
Note
What is HOCON?
HOCON stands for Human-Optimized Config Object Notation. It was created by Typesafe (now Lightbend) in 2011 as the configuration format for the Typesafe Config library, which powers Akka, Play Framework, Lagom, and other JVM-based frameworks. HOCON files use the `.conf` extension and are a strict superset of JSON — every valid JSON file is valid HOCON.
HOCON is designed for application runtime configuration rather than infrastructure definition. Its standout feature is substitutions — the ability to reference other configuration values within the same file using the substitution syntax — referencing other config values or environment variables by path. This makes HOCON particularly well-suited for layered configuration: a base config file can define defaults, and an environment-specific file can override individual values, with substitutions pulling from environment variables or other config sources.
HOCON syntax fundamentals
# Application configuration
app {
name = "my-service"
version = "1.0.0"
server {
host = "0.0.0.0"
port = 8080
# Environment variable substitution
port = ${?APP_PORT}
}
database {
url = "jdbc:postgresql://localhost:5432/mydb"
# Substitute from another config value
connection-pool = ${app.server.port}
}
}
# Lists
allowed-origins = ["https://example.com", "https://api.example.com"]HOCON features beyond JSON
- Comments — `#` and `//` single-line comments; JSON does not support comments.
- Substitutions — ${'{'}path.to.value{'}' } references other keys; ${'{'}?ENV_VAR{'}' } falls back silently if undefined.
- Include directives — include "other.conf" merges external config files at parse time.
- Object merging — duplicate keys merge their values rather than overwriting; enables layered configuration.
- Key-value flexibility — supports key = value, key : value, and key value (space-separated) equivalently.
- Unquoted strings — simple string values do not need quotes unless they contain special characters.
Tip
HCL vs HOCON: key differences
HCL and HOCON solve similar problems from different angles. Both are more readable than JSON for complex configs, both support comments, and both have a JSON compatibility layer. But their design goals, primary use cases, and ecosystem integrations are distinct enough that you rarely choose between them — the tool you are using chooses for you.
HCL describes what infrastructure should exist. HOCON describes how an application should behave. The difference in purpose shapes every design decision in both languages.
| Attribute | HCL | HOCON |
|---|---|---|
| Created by | HashiCorp (2014) | Typesafe/Lightbend (2011) |
| File extension | .hcl, .tf, .pkr.hcl | .conf, .json (JSON subset) |
| Primary use | Infrastructure as code | Application runtime config |
| Ecosystem | Terraform, Packer, Vault | Akka, Play, Lagom, Spark |
| JSON compatible | ✓ JSON is valid HCL | ✓ JSON is valid HOCON |
| Comments | ✓ # and // and /* */ | ✓ # and // |
| Substitutions | ✗ Uses variables differently | ✓ ${path} and ${?ENV_VAR} |
| Include files | ✗ Uses modules instead | ✓ include "file.conf" |
| Object merging | ✗ Blocks are ordered | ✓ Duplicate keys merge |
| Expressions/logic | ✓ Expressions, for-loops | ✗ Declarative values only |
| Block structure | ✓ Named blocks (resource "") | ✗ Nested objects only |
The key conceptual difference
HCL is imperative about structure — blocks have types and labels (`resource "aws_instance" "web"`) that carry semantic meaning interpreted by the tool. You are declaring entities of a certain type with certain properties. HOCON is purely a data format — it defines a hierarchical key-value structure that applications read at startup. It has no concept of typed blocks; everything is a key pointing to a value, an object, or a list.
Note
Working with HCL files in practice
HCL files are most commonly edited as part of a Terraform project, though the same principles apply to Packer, Vault, and Nomad. Getting the formatting and structure right matters because HashiCorp tools validate HCL strictly at plan or validate time, and malformed HCL blocks produce errors that can be difficult to trace if the file is not consistently indented.
Format your HCL files for consistency
The HCL Formatter on Quasar Tools formats and beautifies HCL files with proper 2-space indentation, consistent attribute spacing, and clean block structure. Paste any `.hcl` or `.tf` file and get consistently formatted output ready to use with Terraform, Packer, Vault, Consul, or Nomad — entirely in your browser.
Convert HCL to YAML when needed
When a CI system, documentation tool, or pipeline processor needs HCL config in YAML format, the HCL to YAML Converter handles the structural translation. This is common when extracting Terraform variable definitions for use in Ansible playbooks or Kubernetes config maps.
Validate Terraform HCL resource naming
HCL resource names in Terraform must follow consistent naming conventions across a team to keep code reviewable. The Terraform Resource Naming Convention Checker at `/tools/data/validators/terraform-resource-naming-convention-checker` validates that your resource, variable, and module names follow the chosen naming style before you run `terraform plan`.
HCL Formatter
Format and beautify any HCL or Terraform file with proper 2-space indentation, consistent attribute spacing, and clean block structure — in your browser.
Working with HOCON files in practice
HOCON configuration files in JVM projects typically live at `src/main/resources/application.conf`. Akka applications use HOCON for actor system configuration, dispatcher settings, and extension configuration. Play Framework uses it for routes, database connections, and application settings. The format is forgiving — unquoted strings, flexible assignment operators, comments — but whitespace-sensitive formatting makes files easier to read and maintain.
Formatting HOCON files
The HOCON Formatter on Quasar Tools formats HOCON configuration files with consistent 4-space indentation, proper key-value spacing, clean substitution handling, and Typesafe Config conventions. This is particularly useful when editing large Akka or Play configuration files that have accumulated inconsistent formatting from multiple contributors.
Converting HOCON to YAML
When a tool in your pipeline expects YAML but your application config is HOCON, the HOCON to YAML Converter translates the HOCON key-value structure into a YAML equivalent. Note that HOCON-specific features — substitutions, include directives, and merged keys — are resolved before conversion, so the YAML output reflects the final merged configuration rather than the raw HOCON template syntax.
Warning
HOCON Formatter
Format HOCON config files with consistent 4-space indentation, proper substitution handling, and Typesafe Config conventions — entirely in your browser.
HCL and HOCON alongside other config formats
HCL and HOCON exist alongside a broader landscape of configuration formats. Choosing the right one is rarely a free decision — the tooling you use dictates the format. But understanding where each format fits helps you reason about configuration portability and tooling trade-offs.
How the major config formats compare
| Format | Human-readable | Comments | Best for |
|---|---|---|---|
| JSON | ✗ Verbose | ✗ None | APIs, data interchange |
| YAML | ✓ Very | ✓ # | K8s, CI/CD, general config |
| TOML | ✓ Good | ✓ # | App config, Rust, Python tools |
| INI | ✓ Simple | ✓ # ; | Simple key-value, legacy apps |
| HCL | ✓ Good | ✓ # // | Infrastructure as code |
| HOCON | ✓ Good | ✓ # // | JVM app config, Akka, Play |
HCL and YAML together in Terraform workflows
In practice, a Terraform project uses HCL for all infrastructure definitions while the CI/CD pipeline that runs Terraform is often configured in YAML (GitHub Actions, GitLab CI, CircleCI). These coexist without conflict — HCL is Terraform's input, YAML is the pipeline's input. If you work across both, the same formatting discipline applies to both. For YAML errors in your CI files, the workflow in How to Detect and Fix YAML Errors applies directly.
HOCON, TOML, and YAML for application config
For non-JVM applications, TOML and YAML are more common choices than HOCON. TOML is the standard for Rust (Cargo.toml), Python packaging (pyproject.toml), and Hugo static sites. YAML dominates Kubernetes, Ansible, Docker Compose, and most cloud-native tooling. HOCON is the right choice specifically when your runtime is a JVM framework that ships with Typesafe Config — you get HOCON's features for free, and fighting the framework to use a different format creates more problems than it solves.
Related format posts
If you are evaluating configuration formats for a new project, the companion posts in this series cover the closest alternatives. How to Create an INI File covers the simplest config format. How to Comment in YAML Properly covers YAML syntax specifics. And What Does Terraform Validate Actually Check? covers how HCL errors surface in a Terraform workflow specifically.
Tip
Key takeaways
- HCL (HashiCorp Configuration Language) is a declarative format for infrastructure-as-code — used by Terraform, Packer, Vault, Consul, and Nomad. HCL2 is the current version.
- HOCON (Human-Optimized Config Object Notation) is a JSON superset for JVM application runtime configuration — used by Akka, Play Framework, and Lightbend tools.
- Both formats support comments and are JSON-compatible, but they are not interchangeable — the tool you are using determines which format to use.
- HCL's key feature is typed, named blocks (`resource "aws_instance" "web"`); HOCON's key feature is variable substitutions (`${?ENV_VAR}`) and object merging.
- Use the HCL Formatter for consistent HCL formatting and the HOCON Formatter for HOCON — both run in your browser with no upload.
- For non-JVM and non-HashiCorp projects, TOML or YAML are usually better choices than HCL or HOCON due to broader parser support and no ecosystem coupling.