How to convert json keys from camelcase to snake_case
- Step 1Drop your JSON file — Drag the JSON file onto the dropzone (the tool reads a file — it does not take pasted text). Free tier accepts files up to 2 MB; the filename and size appear above the options once loaded.
- Step 2Pick the target case style — Click snake_case in the Target case style row to convert camelCase to snake_case. The five buttons are camelCase, snake_case, PascalCase, kebab-case, and UPPER_SNAKE — exactly one is active at a time.
- Step 3Decide on Deep rename — Leave Deep rename (all nested levels) checked (the default) to rewrite keys at every nesting level including arrays of objects. Uncheck it to convert only the top-level keys and leave nested objects exactly as they were.
- Step 4Run the conversion — Click Rename Keys. The tool reports how many keys were actually renamed (keys already in the target case are counted as unchanged) and shows the formatted output.
- Step 5Spot-check acronyms and collisions — Scan the output for acronym-heavy keys (
iOSVersion,customerID) and for any two source keys that could collapse to the same target — the section below explains what happens in those cases. - Step 6Copy or download — Use Copy to grab the result, or Download to save it as
<name>.renamed.json. Output indents with 2 spaces by default.
Target case styles and how the same key renders
The five styles the tool offers, each applied to the same source keys. Word boundaries are detected at case changes, hyphens, and spaces, then re-joined per style. There is no 'custom' style exposed in the UI — these five are the complete set.
| Source key | camelCase | snake_case | PascalCase | kebab-case | UPPER_SNAKE |
|---|---|---|---|---|---|
firstName | firstName | first_name | FirstName | first-name | FIRST_NAME |
user_id | userId | user_id | UserId | user-id | USER_ID |
APIKey | apiKey | api_key | ApiKey | api-key | API_KEY |
URLPath | urlPath | url_path | UrlPath | url-path | URL_PATH |
field1Name | field1Name | field1_name | Field1Name | field1-name | FIELD1_NAME |
postal code | postalCode | postal_code | PostalCode | postal-code | POSTAL_CODE |
Word-splitting behaviour
How the tokenizer decides where one word ends and the next begins, before re-casing. Understanding this explains every acronym and digit edge case.
| Rule | Input | Tokens | snake_case result |
|---|---|---|---|
| Lowercase→uppercase boundary | firstName | first, name | first_name |
| Acronym run before a capitalized word | HTMLParser | html, parser | html_parser |
| Hyphens and spaces become boundaries | order-id, postal code | order, id / postal, code | order_id, postal_code |
| Digit stays with the word it follows | v2Token | v2, token | v2_token |
| All-caps key, no internal boundary | SKU | sku | sku |
| Consecutive separators collapse | first__name | first, name | first_name |
Cookbook
Real before/after pairs. The left side is the source JSON; the right (or below) is the output after picking a target case. Watch the acronym and collision cases — those are where automatic case conversion is lossy.
camelCase API response to snake_case for Python
ExampleA JS API returns camelCase; your Python service wants snake_case dict keys. Pick snake_case with Deep rename on.
Input:
{
"userId": 1,
"firstName": "Alice",
"address": { "postalCode": "10001" }
}
Target: snake_case, Deep rename ON
Output:
{
"user_id": 1,
"first_name": "Alice",
"address": { "postal_code": "10001" }
}Arrays of objects are converted per item
ExampleA list of records is renamed element by element — every object in the array gets the same treatment.
Input:
[
{ "firstName": "Sue" },
{ "firstName": "Jon" }
]
Target: snake_case
Output:
[
{ "first_name": "Sue" },
{ "first_name": "Jon" }
]Deep rename OFF leaves nested keys alone
ExampleUnchecking Deep rename converts only the top-level keys; nested objects keep their original casing.
Input:
{ "userId": { "firstName": 1 } }
Target: snake_case, Deep rename OFF
Output:
{ "user_id": { "firstName": 1 } }Acronyms are lowercased, not preserved
ExampleGoing camelCase to snake_case flattens trailing acronyms — useful to know before you assume a round-trip is lossless.
Input:
{ "customerID": 7, "grossUSD": 42 }
Target: snake_case
Output:
{ "customer_id": 7, "gross_usd": 42 }
(Re-applying camelCase gives customerId / grossUsd — the ID/USD capitalization is gone.)Mixed-case source unified to one style
ExampleThe tool does not need to know the source case — userId, user_id, and User-Id all converge.
Input:
{ "userId": 1, "user_id": 2, "User-Id": 3 }
Target: snake_case
Note: all three keys normalize to user_id, so they collide.
Output keeps the LAST one written:
{ "user_id": 3 }Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
Two source keys collapse to the same target name
Silent overwriteIf user_id and userId both appear in one object and you convert to snake_case, both become user_id. JSON objects cannot hold duplicate keys, so the last value written wins and the earlier one is silently dropped — the renamed count still increments. Audit objects that mix casing styles before converting. To keep specific keys, prune the collisions first with json-key-filter.
lowercase-i acronym like `iOSVersion`
By designThe tokenizer splits at the lowercase→uppercase boundary, so iOSVersion becomes tokens i, os, version → i_os_version. There is no special list for product-style casing like iOS or eBay; if you need those preserved exactly, this automatic converter is the wrong tool — handle them in code or pre-rename them upstream.
Top-level value is an array
SupportedAn array at the root is handled: each object element is recursed into and renamed. A bare array of scalars (no objects) passes through unchanged because there are no keys to rename.
Top-level value is a scalar or string
PreservedInput like 42 or "hello" is valid JSON with no keys. The tool returns it unchanged and reports 0 keys renamed — it does not error.
Empty-string key `""`
PreservedA key of "" produces no word tokens, so it stays "" and is counted as unchanged. It is not dropped or turned into an error.
Non-ASCII keys (e.g. CJK, accented)
PreservedWord-boundary detection only matches A–Z. A key like 已设置 or naïveField has no ASCII case boundary to split, so non-Latin keys pass through untouched; an accented Latin key is lowercased word-by-word only where ASCII capitals occur.
Key already in the target case
ExpectedIf a key is already first_name and you choose snake_case, the output is identical and that key is not added to the renamed count. The count reflects keys that actually changed, not total keys.
Invalid JSON input
Parse errorThe input is parsed with JSON.parse after trimming whitespace. A trailing comma, single quotes, or an unquoted key throws a parse error and nothing is produced. Repair the syntax first, then rerun.
File larger than the free limit
Blocked on freeFree tier caps JSON files at 2 MB. A larger file is blocked before processing with an upgrade prompt; Pro raises the ceiling to 100 MB.
Round-trip is not guaranteed lossless
By designsnake_case → camelCase → snake_case is stable for simple keys, but acronyms do not survive: customerID → customer_id → customerId. Treat the conversion as one-directional normalization, not a reversible encoding.
Frequently asked questions
Can I convert snake_case back to camelCase?
Yes — pick the camelCase button instead of snake_case. The tool does not have a 'direction' toggle because it doesn't need one: it normalizes every key to whichever single style you select, no matter what the source keys looked like. So user_id with the camelCase target becomes userId.
Does it handle nested objects and arrays?
Yes, by default. The Deep rename (all nested levels) checkbox is on out of the box, so keys are rewritten at every depth, including inside arrays of objects. Uncheck it to touch only the top-level keys.
How are acronyms like ID, URL, or API handled?
Multi-letter acronyms that precede another capitalized word split correctly: APIKey → api_key, HTMLParser → html_parser, userId → user_id. But a trailing or standalone acronym is lowercased as one word: customerID → customer_id, SKU → sku. There is no acronym dictionary, so casing like iOS is not specially preserved.
Are there really only five case styles?
Yes: camelCase, snake_case, PascalCase, kebab-case, and UPPER_SNAKE. There is no free-text 'rename this key to that key' input in the UI — this is a case normalizer, not an arbitrary key mapper. For selecting or removing specific keys by name, use json-key-filter.
Will it change my values too?
No. Only keys are rewritten. A value such as "firstName" sitting inside a string stays exactly as typed; the tool never inspects or alters values.
What happens to digits in keys?
Digits stay attached to the word they follow: field1Name → field1_name, v2Token → v2_token, 2factorAuth → 2factor_auth. They are not split into their own token.
Can I paste JSON instead of uploading a file?
The tool reads a dropped or selected file rather than a paste box. Save your JSON to a .json file (any extension works as long as it's valid JSON) and drop it on the dropzone.
What's the file-size limit?
2 MB on the free tier for JSON tools. Pro raises it to 100 MB, and higher tiers go further. The limit is on the file, not the key count.
Does converting to camelCase or snake_case ever lose data?
It can, but only via key collisions: if two differently-cased source keys normalize to the same target name in the same object, JSON keeps just one. Values themselves are never lost. Audit mixed-casing objects before converting.
How do I implement the same conversion in Python?
Use pyhumps: pip install pyhumps, then humps.decamelize(d) for snake_case or humps.camelize(d) for camelCase. Note that library acronym handling may differ from this tool's, so spot-check acronym-heavy keys if you need byte-identical output.
Is my data uploaded anywhere?
No. All parsing and renaming happen in your browser via JSON.parse and JSON.stringify. Nothing is sent to JAD Apps servers.
How is the output indented?
Two-space indentation by default. Picking the same case as the source still re-serializes the whole document, so you also get a consistent re-format for free. If you need it minified, run the output through json-minifier.
Privacy first
Conversion runs locally in your browser. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.