# lightbend/config: HOCON configuration for JVM applications

> A plain-Java configuration library that merges properties, JSON and HOCON files into one immutable Config object. It suits libraries and services that need layered defaults, substitutions and type coercion, and it stops at files.

**lightbend/config** — configuration library for JVM languages using HOCON files

- Repository: https://github.com/lightbend/config
- Website: https://lightbend.github.io/config/
- Stars: 6,313 · Forks: 982
- Language: Java
- License: not declared
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/lightbend-config

## What lightbend/config solves for JVM services and libraries

Most JVM applications end up with configuration spread across a properties file, some JSON, and a pile of -D flags. lightbend/config exists to collapse that into one object. The README describes it as a configuration library for JVM languages implemented in plain Java with no dependencies, supporting Java properties, JSON, and a human-friendly JSON superset called HOCON. It merges multiple files across all formats and can load from files, URLs, or the classpath.

The intended split is between libraries and applications. The README says libraries should use a Config instance provided by the app if one is given, fall back to ConfigFactory.load() otherwise, and put their defaults in a reference.conf on the classpath. Applications create the Config however they like, then hand it to their libraries. That is the design bet: a framework and the libraries inside it can all be configured from a single file such as application.conf, without each library inventing its own settings mechanism.

Who is this for? People building or maintaining JVM services, especially ones assembled from multiple libraries that each need defaults. It is less useful for a small script with two settings, where a properties file and System.getProperty already suffice.

## How HOCON merging and substitutions actually work

The mechanism is a merge tree. ConfigFactory.load() reads reference.conf files from the classpath, then application.conf, then system properties, and merges them in that order so later sources override earlier ones. The result is an immutable Config instance, which the README presents as the basis for thread safety and for reasoning about transformations. Nesting is first-class: any subtree can be treated as a whole config, which is why the README example calls conf.getConfig("foo") and then reads foo.getInt("bar").

HOCON itself is a superset of JSON with comments, includes, substitutions and properties-like notation such as a.b=c. Substitutions come in two shapes in the README: "foo" : ${bar} and "foo" : Hello ${who}. Environment variables are substituted the same way, with the README giving logdir=${HOME}/logs as the example. Concatenation and optional overrides are documented as separate uses of substitutions, which is how a project factors out a common value once and references it in several places.

Type coercion sits on top of parsing. If you ask for a boolean and the value is the string "yes", or ask for a float and the value is an int, the library converts it. Durations and sizes are parsed from strings like "512k" or "10 seconds". That leniency is convenient, and it is also the part most likely to surprise you: a value that looks wrong in the file can still be accepted at read time.

## Installing lightbend/config and loading a first config file

The README points to Maven Central for published releases and states the library is compatible with Java 8 and above. Add the dependency with your build tool. The README shows the Maven coordinates as com.typesafe, config, with a version line; check Maven Central for the current release rather than copying an old version number.

```xml
<dependency>
    <groupId>com.typesafe</groupId>
    <artifactId>config</artifactId>
    <version>1.4.4</version>
</dependency>
```

For sbt, the README gives the equivalent one-liner.

```scala
libraryDependencies += "com.typesafe" % "config" % "1.4.4"
```

If you do not use a dependency manager, the README links to the Maven repository directory for direct download. Once the jar is on the classpath, put an application.conf in your resources and load it. The README's API example is the shortest complete use:

```java
import com.typesafe.config.ConfigFactory;

Config conf = ConfigFactory.load();
int bar1 = conf.getInt("foo.bar");
Config foo = conf.getConfig("foo");
int bar2 = foo.getInt("bar");
```

What you should see is a Config built from whatever reference.conf and application.conf files are on the classpath, with system properties applied last. The README notes that examples live in the examples/ directory and can be run from the sbt console with project config-simple-app-java followed by run. That is the fastest way to watch merging happen without writing your own project first.

## Where lightbend/config stops: files only, and the resolution caveat

The README is explicit that the library limits itself to config files. If you want to load configuration from a database or another service, you write custom code. There is a consolation: the merging support is good enough that a Config built from a custom source can be merged into the rest, but the fetching is yours.

There is a second, subtler boundary around substitutions. The README carries a dedicated note titled "Note about resolving substitutions in reference.conf and application.conf". The existence of that note is the signal: substitution resolution depends on which file a value came from, so a ${...} reference that resolves in one file may not behave the same way when the value is defined elsewhere or overridden later. If your configuration leans heavily on substitutions across layers, read that section before you design the file layout.

A third limitation is the contributor path rather than the runtime. The README asks contributors to read the Maintained-by note before spending time suggesting changes, and pull requests require agreeing to the Akka Contributor License Agreement. The build uses sbt and tests are written in Scala, though the published jar is plain Java with no Scala dependency. For a team that wants to patch a behaviour quickly, that process is friction worth knowing about in advance.

## How lightbend/config compares with Spring Boot configuration

The obvious alternative in the JVM world is Spring Boot's configuration system, which reads application.properties or application.yml, binds values to typed @ConfigurationProperties classes, and layers profile-specific files on top. The difference in approach is where the layering logic lives. Spring Boot builds configuration around the application context: profiles, property sources and environment are framework concepts, and the binding is generated for you.

lightbend/config has no framework. It is a library you call, ConfigFactory.load() is a static entry point, and merging is defined by file precedence rather than by profiles. That makes it usable from a plain Java main, a library that cannot assume Spring, or an application assembled from components that each ship a reference.conf. It also means you do not get profile switching, relaxed binding of environment variable names, or annotation-driven binding out of the box. If your project is already a Spring Boot application, adding lightbend/config on top gives you two configuration systems to reason about. If your project is a library or a non-Spring service, the reverse is true.

The README also lists wrappers and ports for other languages and ecosystems, including Guice integration, Scala, Clojure, Kotlin and Java wrappers, plus ports to other languages and a linting tool. Those are separate projects, not part of this jar.

## Maintenance, releases and licence position

The repository is not archived, and the last push was on 2026-07-01. Releases are frequent and small: v1.4.9 on 2026-06-03, v1.4.8 on 2026-05-05, and v1.4.7 on 2026-04-28. Patch releases at that cadence suggest maintenance work rather than a frozen artifact, and the README points to NEWS.md for release notes and RELEASING.md for the release process.

The licence is the part to check yourself. The repository contains a top-level LICENSE-2.0.txt file, which is the Apache License 2.0 text, and the README's table of contents has a License section. The metadata supplied for this repository does not state a licence identifier, so treat the file in the repository as the source of truth and read it before you redistribute the jar. Nothing here is legal advice; the point is simply that the licence is discoverable in the tree and not in the project description.

Upgrade cost is low by design. The published jar is plain Java with no dependencies, so a version bump does not drag a transitive tree along with it. The risk sits in behaviour changes to parsing or substitution resolution between patch releases, which NEWS.md is the place to check before upgrading a service that relies on either.

## Conclusion

Adopt lightbend/config if your JVM service or library needs layered defaults, HOCON substitutions and typed getters, and you are willing to keep configuration in files on the classpath. Do not adopt it if you need configuration stored in a database or a remote service; the README states the library limits itself to config files and that such sources require custom code. Before committing, verify the artifact version you intend to use against the releases on Maven Central, read HOCON.md for the format rules, and check the Maintained-by note in the README, since the repository asks contributors to read it before proposing changes.

## FAQ

### What does lightbend/config mean by config?

In this project, config means the immutable Config object produced by parsing and merging files. The README describes the library as supporting Java properties, JSON and HOCON, loading from files, URLs or the classpath, and merging multiple files across all formats.

### How do I install lightbend/config in a Maven or sbt project?

Add the com.typesafe:config artifact from Maven Central using your build tool. The README shows the Maven dependency block and the sbt equivalent, libraryDependencies += "com.typesafe" % "config" % "1.4.4", and notes the library is compatible with Java 8 and above.

### How do I use lightbend/config to read a value from a file?

Call ConfigFactory.load() to build a Config from the classpath, then read values with typed getters such as getInt or getConfig for a subtree. The README's API example shows conf.getInt("foo.bar") followed by conf.getConfig("foo").getInt("bar").

### How do I set up lightbend/config for an application and its libraries?

Libraries put defaults in a reference.conf on the classpath and accept a Config from the application, falling back to ConfigFactory.load() if none is given. Applications create the Config and pass it down, which the README describes as configuring an app, its framework and libraries from a single file such as application.conf.

## Sources

- [Issues](https://github.com/lightbend/config/issues)
- [lightbend/config on GitHub](https://github.com/lightbend/config)
- [Project website](https://lightbend.github.io/config/)
- [README](https://github.com/lightbend/config/blob/main/README.md)
- [Releases](https://github.com/lightbend/config/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lightbend-config
