The ultimate TOML parser for Java 8+.
Goals are feature-completeness and a robust, type-safe API.
JToml supports the latest version of the TOML spec (v1.0.0
).
TOML is a first-class citizen; no casts, no wonky date-time handling,
no dependencies.
The main reason for JToml's existence is that there were no other pure-Java TOML parsers which exposed an opaque API for TOML keys. JToml can parse TOML String keys like the other libraries, but also slice and join keys and perform shallow and deep enumeration of keys.
The strongly typed nature of JToml is both an extension of this goal and a personal preference.
dependencies {
implementation("io.github.wasabithumb:jtoml:0.5.0")
}
dependencies {
implementation 'io.github.wasabithumb:jtoml:0.5.0'
}
<dependencies>
<dependency>
<groupId>io.github.wasabithumb</groupId>
<artifactId>jtoml</artifactId>
<version>0.5.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
final String source = """
[a]
number = 0xCAFEBABE
[a.b]
string = "hello from jtoml \\U0001F60E"
""";
JToml toml = JToml.jToml();
TomlTable table = toml.readFromString(source);
String key1 = "a.number";
table.get(key1).asPrimitive().asLong(); // 3405691582
TomlKey key2 = TomlKey.join(TomlKey.parse("a.b"), TomlKey.literal("string"));
table.get(key2).asPrimitive().asString(); // hello from jtoml 😎
Files and streams are also supported. For streams, very minimal buffering is performed.
The JToml#serialize
and JToml#deserialize
methods can be used to
convert TomlTable
s into various formats. Here is the current list of
serializers:
Name | Dependency | Types |
---|---|---|
PlainTextTomlSerializer |
- included - | String |
GsonTomlSerializer |
jtoml-serializer-gson |
JsonObject |
ReflectTomlSerializer |
jtoml-serializer-reflect |
TomlSerializable , Map<String, ?> , List<?> , records, boxed and unboxed primitives |
toml.serialize(JsonObject.class, table);
// {"a":{"number":3405691582,"b":{"string":"hello from jtoml 😎"}}}
If you are shading this library, serializers will not work as intended unless you configure shadowJar to merge the service files. See instructions below.
tasks.shadowJar {
mergeServiceFiles()
}
Use the ServicesResourceTransformer.
JToml can now be used as a Configurate format/loader through the jtoml-configurate
artifact. Special thanks to jpenilla for this contribution.
ConfigurationFormat format = ConfigurationFormat.forExtension("toml");
ConfigurationNode node = format.create(this.getClass().getResource("foo.toml")).load();
TomlConfigurationLoader loader = TomlConfigurationLoader.builder()
.path(target)
.set(JTomlOption.LINE_SEPARATOR, LineSeparator.LF)
.build();
loader.save(node);
The jtoml-kotlin
artifact provides extensions for Kotlin. Notably adds KToml
, a
static instance of JToml. Also adds many extra functions for coercing values, performing primitive arithmetic, and
working with arrays/tables.
val table = TomlTable.create()
table["foo.bar"] = "baz"
table["meaning.of.life"] = 40.asTomlPrimitive + 2
val str = KToml.writeToString(table)
WasabiThumb/jtoml | tomlj/tomlj | mwanji/toml4j | asafh/jtoml | |
---|---|---|---|---|
Safe Key Join & Split | ✅ | ❌ | ❌ | ❌ |
v1.0.0 Compliance |
✅ | ✅ | ❌ | ❌ |
Positional Errors | ✅ | ✅ | ✅ | ✅ |
Error Recovery | ❌ | ✅ | ✅ | ❌ |
Configurable Read Rules | ✅ | ✅ | ❌ | ❌ |
Configurable Write Rules | ✅ | ❌ | ✅ | ❌ |
Enum-based type inspection | ✅ | ✅ | ❌ | ❌ |
Safe type coercion | ✅ | ❌ | ❌ | ❌ |
Reflect serialization | ✅ | ❌ | ✅ | ✅ |
JSON serialization | ✅ | ✅1 | ✅ | ❌ |
Zero Dependencies | ✅ | ❌ | ❌ | ✅ |
Passes test suite | ✅ | ❌2 | ❌ | ❌ |
- Deserialization is not supported; JSON is in string format
- Passes 6 arbitrary tests, full suite has ~700
Copyright 2025 Wasabi Codes
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.