What does the YAML Merge Tool do?
The YAML Merge Tool on blueutils.com performs recursive deep-merging of multiple YAML configuration files, Kubernetes manifests, and environment overrides into a single unified document. It preserves nested dictionary hierarchies, provides selectable strategies for list and array conflicts (replace, concat, and union), and supports optional null-value skipping.
Core Concepts
Understanding deep-merge semantics prevents configuration bugs in multi-environment deployments:
- Recursive Map Merging: Unlike shallow merges that replace entire parent objects, deep merging merges individual sibling keys so that specific sub-properties can be patched without wiping unmentioned fields.
- Array Resolution Strategies:
replace: Default behavior where override lists replace base lists entirely.concat: Appends override list items to the end of the base sequence.union: Appends elements while eliminating duplicate scalar and object values.
- Null Value Handling (
skipNull): When enabled,nullvalues in override files do not overwrite or delete existing non-null properties from base files.
How to use the tool?
- Input Base & Override Documents: Paste or upload your base YAML configuration into the left editor and your override patch into the right editor, or click Sample.
- Configure Merge Options:
- Select your Array Strategy (
Replace,Concat, orUnion). - Toggle Skip Null Properties if patch files contain placeholder null keys.
- Choose desired output indentation spacing (
2 Spaces,4 Spaces,Tab, orCustom...).
- Select your Array Strategy (
- Instant Live Merging & Export: Documents merge in real time as you edit or adjust options. Click Copy or Download to save your unified YAML configuration.
Related Developer Utilities
If you work with YAML configurations, Kubernetes manifests, or infrastructure files, explore these related tools:
- Kubernetes Manifest Validator: Validate Kubernetes resource configurations against official API schemas.
- YAML Diff Tool: Compare two YAML files side-by-side to highlight key and value diffs.
- YAML Formatter: Clean and format indentation for large YAML documents.
- YAML to JSON Converter: Convert raw YAML data into clean, structured JSON payloads.
REST API Integration
blueutils.com provides a free REST API endpoint (POST https://blueutils.com/api/yaml/merge) to programmatically deep-merge multiple YAML configuration documents with configurable precedence and conflict resolution rules.
API Request Parameters
| Name | Type | Description | Example |
|---|---|---|---|
yamlSources / sources / yamlLeft+yamlRight |
Array / String | Array of raw YAML strings or parsed objects to merge sequentially. | ["a: 1", "b: 2"] |
arrayStrategy |
String | Array merge preference: "replace" (default), "concat", or "union". |
"concat" |
skipNull |
Boolean | Whether to ignore null values in override documents. Defaults to false. |
false |
indent |
Number/String | Indentation spaces for output YAML. Defaults to 2. |
2 |
API Request Payload Examples
cURL (Using Array of YAML Sources)
curl -X POST https://blueutils.com/api/yaml/merge \
-H "Content-Type: application/json" \
-d '{
"yamlSources": [
"appName: Blueutils\nserver:\n port: 8080",
"server:\n debug: true"
],
"arrayStrategy": "concat",
"indent": 2
}'cURL (Using Direct Left and Right Aliases)
curl -X POST https://blueutils.com/api/yaml/merge \
-H "Content-Type: application/json" \
-d '{
"yamlLeft": "server:\n port: 8080",
"yamlRight": "server:\n debug: true"
}'Python
import requests
url = "https://blueutils.com/api/yaml/merge"
payload = {
"yamlSources": [
"appName: Blueutils\nserver:\n port: 8080",
"server:\n debug: true"
],
"arrayStrategy": "replace"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.json())Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
String jsonPayload = """
{
"yamlSources": [
"appName: Blueutils\\nserver:\\n port: 8080",
"server:\\n debug: true"
],
"arrayStrategy": "concat",
"indent": 2
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://blueutils.com/api/yaml/merge"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}API Response Parameters
| Name | Type | Description | Example |
|---|---|---|---|
isValid |
Boolean | Indicates whether the operation succeeded. | true |
message |
String | Confirmation message returned on success. | "Successfully deep-merged 2 YAML documents." |
mergedYaml / result |
String | Formatted YAML string of the deep-merged document. | "appName: Blueutils\nserver:\n port: 8080\n debug: true" |
mergedObject / data |
Object | Parsed native representation of the merged result. | { "appName": "Blueutils", "server": { "port": 8080, "debug": true } } |
sourceCount |
Number | Total count of documents merged. | 2 |
originalSize |
Number | Byte size of raw inputs in UTF-8. | 48 |
resultSize |
Number | Byte size of merged output in UTF-8. | 42 |
error |
String | Error message description (when isValid is false). |
"At least two YAML documents are required for merging." |
API Response Payload Examples
Success Response (HTTP 200 OK)
{
"isValid": true,
"message": "Successfully deep-merged 2 YAML documents.",
"mergedYaml": "appName: Blueutils\nserver:\n port: 8080\n debug: true",
"result": "appName: Blueutils\nserver:\n port: 8080\n debug: true",
"mergedObject": {
"appName": "Blueutils",
"server": {
"port": 8080,
"debug": true
}
},
"data": {
"appName": "Blueutils",
"server": {
"port": 8080,
"debug": true
}
},
"sourceCount": 2,
"originalSize": 48,
"resultSize": 42
}Validation Failure Response (HTTP 400 Bad Request)
{
"isValid": false,
"error": "At least two YAML documents are required for merging."
}Rate Limit Exceeded Response (HTTP 429 Too Many Requests)
{
"error": "API rate limit exceeded. Please wait or contact support@blueutils.com."
}Why use an API to deep merge YAML?
Integrating the YAML Merge API into GitOps workflows, Helm chart packaging scripts, or CI/CD pipelines provides several advantages:
- Rapid Script Validation: Enables developers to dynamically merge base configuration templates with environment overlays (dev, staging, prod) automatically during deployments.
- Optimized Token Efficiency for AI Agents: Eliminates the need for LLMs to generate and re-parse massive YAML configurations, saving prompt and completion context tokens.
- Deterministic Accuracy Without Hallucinations: Ensures recursive merge logic and array strategies follow exact RFC-compliant algorithms without dropping sibling keys.
Native Usage
How to deep-merge YAML files locally using command-line utilities and scripts:
Windows (CMD / PowerShell)
# Deep-merge YAML documents using Python in PowerShell
python -c "
import yaml
def merge(a, b):
for k, v in b.items():
if isinstance(v, dict) and k in a and isinstance(a[k], dict): merge(a[k], v)
else: a[k] = v
return a
d1 = yaml.safe_load(open('base.yaml')) or {}
d2 = yaml.safe_load(open('override.yaml')) or {}
print(yaml.dump(merge(d1, d2), default_flow_style=False))
"Linux / Unix (Bash)
# Using yq CLI to deep-merge multiple YAML files
yq eval-all '. as $item ireduce ({}; . * $item)' base.yaml override.yamlPython
Using PyYAML in Python for recursive dictionary merging:
import yaml
def deep_merge(target, source):
for key, value in source.items():
if isinstance(value, dict) and key in target and isinstance(target[key], dict):
deep_merge(target[key], value)
else:
target[key] = value
return target
with open("base.yaml") as f1, open("override.yaml") as f2:
base_data = yaml.safe_load(f1) or {}
override_data = yaml.safe_load(f2) or {}
merged = deep_merge(base_data, override_data)
print(yaml.dump(merged, default_flow_style=False, sort_keys=False))Java
Using Jackson (YAMLMapper) with ObjectReader.readTree for deep merging in Java:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import java.io.File;
public class YamlMergeExample {
public static void merge(JsonNode mainNode, JsonNode updateNode) {
updateNode.fieldNames().forEachRemaining(fieldName -> {
JsonNode jsonNode = mainNode.get(fieldName);
if (jsonNode != null && jsonNode.isObject()) {
merge(jsonNode, updateNode.get(fieldName));
} else {
if (mainNode instanceof ObjectNode) {
((ObjectNode) mainNode).replace(fieldName, updateNode.get(fieldName));
}
}
});
}
public static void main(String[] args) throws Exception {
YAMLMapper mapper = new YAMLMapper();
JsonNode baseNode = mapper.readTree(new File("base.yaml"));
JsonNode patchNode = mapper.readTree(new File("override.yaml"));
merge(baseNode, patchNode);
System.out.println(mapper.writeValueAsString(baseNode));
}
}