diff --git a/nlohmann_json.natvis b/nlohmann_json.natvis
index 557717663b..b101771e6f 100644
--- a/nlohmann_json.natvis
+++ b/nlohmann_json.natvis
@@ -1,5 +1,9 @@
+
+
+
+
null
{*(m_value.object)}
@@ -20,8 +24,8 @@
-
+
{second}
@@ -29,4 +33,244 @@
+
+
+ null
+ {*(m_value.object)}
+ {*(m_value.array)}
+ {*(m_value.string)}
+ {m_value.boolean}
+ {m_value.number_integer}
+ {m_value.number_unsigned}
+ {m_value.number_float}
+ discarded
+
+
+ *(m_value.object),view(simple)
+
+
+ *(m_value.array),view(simple)
+
+
+
+
+
+
+ {second}
+
+ second
+
+
+
+
+
+ null
+ {*(m_value.object)}
+ {*(m_value.array)}
+ {*(m_value.string)}
+ {m_value.boolean}
+ {m_value.number_integer}
+ {m_value.number_unsigned}
+ {m_value.number_float}
+ discarded
+
+
+ *(m_value.object),view(simple)
+
+
+ *(m_value.array),view(simple)
+
+
+
+
+
+
+ {second}
+
+ second
+
+
+
+
+
+ null
+ {*(m_value.object)}
+ {*(m_value.array)}
+ {*(m_value.string)}
+ {m_value.boolean}
+ {m_value.number_integer}
+ {m_value.number_unsigned}
+ {m_value.number_float}
+ discarded
+
+
+ *(m_value.object),view(simple)
+
+
+ *(m_value.array),view(simple)
+
+
+
+
+
+
+ {second}
+
+ second
+
+
+
+
+
+ null
+ {*(m_value.object)}
+ {*(m_value.array)}
+ {*(m_value.string)}
+ {m_value.boolean}
+ {m_value.number_integer}
+ {m_value.number_unsigned}
+ {m_value.number_float}
+ discarded
+
+
+ *(m_value.object),view(simple)
+
+
+ *(m_value.array),view(simple)
+
+
+
+
+
+
+ {second}
+
+ second
+
+
+
+
+
+ null
+ {*(m_value.object)}
+ {*(m_value.array)}
+ {*(m_value.string)}
+ {m_value.boolean}
+ {m_value.number_integer}
+ {m_value.number_unsigned}
+ {m_value.number_float}
+ discarded
+
+
+ *(m_value.object),view(simple)
+
+
+ *(m_value.array),view(simple)
+
+
+
+
+
+
+ {second}
+
+ second
+
+
+
+
+
+ null
+ {*(m_value.object)}
+ {*(m_value.array)}
+ {*(m_value.string)}
+ {m_value.boolean}
+ {m_value.number_integer}
+ {m_value.number_unsigned}
+ {m_value.number_float}
+ discarded
+
+
+ *(m_value.object),view(simple)
+
+
+ *(m_value.array),view(simple)
+
+
+
+
+
+
+ {second}
+
+ second
+
+
+
+
+
+ null
+ {*(m_value.object)}
+ {*(m_value.array)}
+ {*(m_value.string)}
+ {m_value.boolean}
+ {m_value.number_integer}
+ {m_value.number_unsigned}
+ {m_value.number_float}
+ discarded
+
+
+ *(m_value.object),view(simple)
+
+
+ *(m_value.array),view(simple)
+
+
+
+
+
+
+ {second}
+
+ second
+
+
+
+
+
+ null
+ {*(m_value.object)}
+ {*(m_value.array)}
+ {*(m_value.string)}
+ {m_value.boolean}
+ {m_value.number_integer}
+ {m_value.number_unsigned}
+ {m_value.number_float}
+ discarded
+
+
+ *(m_value.object),view(simple)
+
+
+ *(m_value.array),view(simple)
+
+
+
+
+
+
+ {second}
+
+ second
+
+
+
diff --git a/tools/generate_natvis/README.md b/tools/generate_natvis/README.md
new file mode 100644
index 0000000000..b4d3a7d7f1
--- /dev/null
+++ b/tools/generate_natvis/README.md
@@ -0,0 +1,10 @@
+generate_natvis.py
+==================
+
+Generate the Natvis debugger visualization file for all supported namespace combinations.
+
+## Usage
+
+```
+./generate_natvis.py --version X.Y.Z output_directory/
+```
diff --git a/tools/generate_natvis/generate_natvis.py b/tools/generate_natvis/generate_natvis.py
new file mode 100755
index 0000000000..e3d6a0094a
--- /dev/null
+++ b/tools/generate_natvis/generate_natvis.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python3
+
+import argparse
+import itertools
+import jinja2
+import os
+import sys
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--version', required=True, help='Library version number')
+ parser.add_argument('output', help='Output directory for nlohmann_json.natvis')
+ args = parser.parse_args()
+
+ namespaces = ['nlohmann']
+ abi_prefix = 'json_abi'
+ abi_tags = ['_diag', '_ldvcmp']
+ version = '_v' + args.version.replace('.', '_')
+ inline_namespaces = []
+
+ for n in range(0, len(abi_tags) + 1):
+ for tags in itertools.combinations(abi_tags, n):
+ ns = abi_prefix + ''.join(tags)
+ inline_namespaces += [ns]
+ inline_namespaces += [ns + version]
+
+ namespaces += [f'{namespaces[0]}::{ns}' for ns in inline_namespaces]
+
+ env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath=sys.path[0]), autoescape=True, trim_blocks=True,
+ lstrip_blocks=True, keep_trailing_newline=True)
+ template = env.get_template('nlohmann_json.natvis.j2')
+ natvis = template.render(namespaces=namespaces)
+
+ with open(os.path.join(args.output, 'nlohmann_json.natvis'), 'w') as f:
+ f.write(natvis)
diff --git a/tools/generate_natvis/nlohmann_json.natvis.j2 b/tools/generate_natvis/nlohmann_json.natvis.j2
new file mode 100644
index 0000000000..0a9ee2ce24
--- /dev/null
+++ b/tools/generate_natvis/nlohmann_json.natvis.j2
@@ -0,0 +1,38 @@
+
+
+
+
+
+{% for ns in namespaces %}
+
+
+ null
+ {*(m_value.object)}
+ {*(m_value.array)}
+ {*(m_value.string)}
+ {m_value.boolean}
+ {m_value.number_integer}
+ {m_value.number_unsigned}
+ {m_value.number_float}
+ discarded
+
+
+ *(m_value.object),view(simple)
+
+
+ *(m_value.array),view(simple)
+
+
+
+
+
+
+ {second}
+
+ second
+
+
+
+{% endfor %}
+