How to document json config records as a markdown table
- Step 1Reshape the config into an array of flat records — This tool wants
[{...}, {...}]. A nestedconfig.jsontree won't tabulate well — turn it into a list of flat records, one per setting/service/flag, with primitive values. - Step 2Redact secrets — Configs hold passwords, tokens, and connection strings. Run the sample through md-secret-redactor first — it replaces API keys, Bearer tokens, AWS keys, and private-key blocks with placeholders.
- Step 3Flatten remaining nested sections — Any value that's still an object renders as
[object Object]. Promote the sub-keys you want (e.g.db.host→db.hostas a flat key) before converting. - Step 4Paste and Run — Paste the array (or upload the
.json). No options to set — Run produces the config table, columns drawn from every record's keys. - Step 5Confirm no secrets slipped through — Scan the output table for any credential, hostname, or token that shouldn't be in a doc. The tool converts verbatim, so this check is on you.
- Step 6Embed in the runbook — Paste into the runbook or deployment guide. To publish, convert with md-to-html or hand off as md-to-docx.
Config value types in the output
How config values render. All cells go through String(value ?? "").
| Config value | Example | Cell output |
|---|---|---|
| String setting | "production" | production |
| Numeric setting | 5432 | 5432 |
| Boolean flag | true | true |
| Unset / null | null | (empty cell) |
| Missing key | (absent) | (empty cell) |
| Nested section | {"host":"db"} | [object Object] — flatten first |
| List value | ["a","b"] | a,b |
Reshaping a config tree into a tabulatable array
The single most useful pattern for ops docs: turn one nested config object into an array of flat records.
| You have | Tool result if pasted as-is | Reshape to |
|---|---|---|
One nested config.json object | Single row, [object Object] cells | Array of flat records, one per section |
{"services": [...]} | One row; services shows [object Object] | Paste the inner services array |
Feature-flags map {a:true,b:false} | One row, columns a/b | Array [{flag:"a",on:true},...] for a flag-per-row table |
| Already an array of flat records | Clean table | No reshape needed |
Tier limits
Markdown-family caps. Config samples are small; uploads matter only for large generated configs.
| Tier | Upload size | Paste characters | Files/run |
|---|---|---|---|
| Free | 1 MB | 500,000 | 1 |
| Pro | 10 MB | 5,000,000 | 10 |
| Pro-media | 50 MB | 20,000,000 | 50 |
| Developer | 500 MB | unlimited | unlimited |
Cookbook
Config shapes ops teams actually document, with the reshaping each needs. Secrets shown redacted.
An array of service records
The ideal shape: a list of flat service objects. One row per service — exactly what a deployment guide needs.
Input:
[
{"service": "api", "port": 8080, "replicas": 3},
{"service": "worker", "port": 0, "replicas": 2}
]
Output:
| service | port | replicas |
| --- | --- | --- |
| api | 8080 | 3 |
| worker | 0 | 2 |Reshape a feature-flags map into rows
A flags object converts to a single wide row. Reshape to an array of flag records so each flag is a row you can annotate in the runbook.
You have:
{"darkMode": true, "betaSearch": false}
Reshape to:
[
{"flag": "darkMode", "enabled": true},
{"flag": "betaSearch", "enabled": false}
]
Output:
| flag | enabled |
| --- | --- |
| darkMode | true |
| betaSearch | false |'Uses default' shown as a blank cell
Leave a setting null or omit it to signal it uses the default — it renders as an empty cell, which reads cleanly in a config reference.
Input:
[
{"env": "prod", "timeout": 30},
{"env": "staging", "timeout": null}
]
Output:
| env | timeout |
| --- | --- |
| prod | 30 |
| staging | |Redact a connection string first
Configs leak credentials. Run md-secret-redactor before converting so the runbook table is safe.
Before redaction:
[{"name": "db", "password": "s3cr3t-pw-9921"}]
After md-secret-redactor:
[{"name": "db", "password": "password=[REDACTED]"}]
Then convert →
| name | password |
| --- | --- |
| db | password=[REDACTED] |A path value with a pipe stays in one cell
Config values often include pipes (alternation, shell). The tool escapes | so the column boundary holds.
Input:
[{"key": "healthcheck", "cmd": "curl -s url | grep ok"}]
Output:
| key | cmd |
| --- | --- |
| healthcheck | curl -s url \| grep ok |Edge cases and what actually happens
Whole nested config pasted as one object
Single-row tableA typical config.json is one big nested object, so the tool produces a single row whose section values all show [object Object]. This tool is for an array of flat records — reshape the config into a list of settings/services first.
Nested config sections render as [object Object]
By designAny value that is itself an object becomes [object Object] (the tool uses String()). Flatten the sub-keys you want as columns, or document each nested section as its own table.
Secret left in the config sample
Security riskThe tool converts verbatim and redacts nothing. A password, token, or connection string in the input will appear in the runbook table. Always run md-secret-redactor on config samples first.
List values flatten to comma text
By designAn allowedHosts: ["a","b"] value becomes a,b via String(). Usually fine for a reference; if exact formatting matters, pre-serialize the list as a string field.
Invalid JSON
Invalid JSON inputConfig files with comments (JSONC), trailing commas, or unquoted keys are not valid JSON — JSON.parse fails and the tool returns Invalid JSON input.. Strip comments and validate first; YAML/TOML configs must be converted to JSON beforehand.
Empty array
Empty arrayInput [] returns Empty array.. Provide at least one config record.
Array of bare strings
No object keys foundA list of plain values (["prod","staging"]) returns No object keys found.. Wrap each as an object — [{"env":"prod"}] — to get a column.
Multi-line value (e.g. a script) in a cell
Row breakA config value containing a newline (an inline shell script) breaks the row, since newlines aren't escaped. Collapse it to one line or replace newlines with spaces before converting; md-table-repair can re-align afterward.
Same setting under different key names across records
Two columnstimeout in one record and timeoutMs in another become two columns under the union rule. Normalize key names across records so the reference shows one column per setting.
Generated config exceeds the paste limit
413 over limitLarge generated configs can blow past the paste character cap (Free 500,000). Upload the .json file instead (Free 1 MB), trim to documented settings, or upgrade for higher limits.
Frequently asked questions
Can I paste my whole config.json directly?
Only if it's already an array of flat objects. A typical nested config is one big object, which produces a single row whose section values show as [object Object]. Reshape it into an array of records — one per setting, service, or flag — with primitive values first.
How do I keep secrets out of the runbook?
Run the config sample through md-secret-redactor before converting. It replaces API keys, Bearer tokens, AWS access keys (AKIA…), generic password=/token= patterns, and private-key blocks with placeholders. This tool itself does no redaction.
How are nested config sections handled?
They render as [object Object] because the tool coerces values with String(), not JSON.stringify. Flatten the sub-keys you want as columns (e.g. db.host) before converting, or document each section in its own table.
How do I show that a setting uses the default?
Leave it null or omit the key — both render as empty cells, which reads naturally as 'default/unset' in a config reference. The output never prints a literal 'null'.
Are there any options, like choosing columns?
No options at all. Columns are always the union of record keys. To control which columns appear, remove unwanted keys from the records before converting, or trim the resulting table by hand.
My config is YAML / TOML — can I use this?
Not directly; this tool takes JSON. Convert YAML or TOML to JSON first (Kubernetes manifests are YAML, for example), reshape into an array of flat records, then convert here.
What about JSONC (config with comments)?
JSON with comments or trailing commas isn't valid JSON — JSON.parse fails and you'll see Invalid JSON input.. Strip the comments and trailing commas first, then convert.
Is the config uploaded anywhere?
No. Everything runs in your browser tab — production config never reaches a server. The only server write is an anonymous usage counter for signed-in dashboards, with no content, which you can disable.
Do connection strings with pipes survive?
Yes — | is escaped to \|, so a command or connection string with a pipe stays in one cell. Newlines are not escaped, so collapse any multi-line values to a single line before converting.
How large a config can I convert?
Free: 1 MB upload or 500,000 pasted characters. Pro: 10 MB / 5,000,000. Pro-media: 50 MB / 20,000,000. Developer: 500 MB / unlimited. A reference table usually needs only a trimmed sample.
How do I publish the runbook table?
Convert the Markdown with md-to-html for a wiki/web page, or md-to-docx for a Word deliverable. Both are markdown-family siblings.
My config data started as CSV — what should I use?
Use csv-to-md-table, which parses CSV with a header-row option. This tool is for JSON arrays of objects. If a config table gets misaligned during edits, md-table-repair fixes alignment.
Privacy first
All Markdown processing runs locally in your browser using JavaScript. No file is ever uploaded to JAD Apps servers — only metadata counters are saved for signed-in dashboard stats.