flashman
← All posts

Identifier case splitter debugging

Debug camel, snake, and kebab results by checking which separators the converter splits on, and which acronyms it folds into a single lowercase token.

2026-10-18 · 6 min read · Rahul Chitturi

  • naming
  • json
  • api

A case converter is a splitter plus a joiner. If the splitter does not see a boundary, the joiner cannot invent one. Flashman's case tool lowercases with toLowerCase, not with a locale, and the three outputs do not use the same split.

Camel case trims the input and splits on spaces, underscores, and hyphens. It then lowercases every piece and capitalizes every piece after the first. It does not split on a capital letter. Snake case inserts an underscore only between a lowercase letter or digit and a following capital, turns spaces and hyphens into underscores, and lowercases. Kebab case uses that same capital boundary, then turns spaces and underscores into hyphens.

Paste the identifier that still has its capitals

maxTorque is one camel token, so the camel box prints maxtorque. The snake box prints max_torque and the kebab box prints max-torque, because those two see the eT boundary. fooBarBaz becomes foobarbaz in the camel box and foo_bar_baz in the snake box. Running camel case on a value that is already camel case destroys the boundaries the other two boxes need.

XMLHttpRequest becomes xmlhttprequest in camel case. Snake case finds only the pR boundary and prints xmlhttp_request, not xml_http_request. HTTPResponse has no lowercase-then-uppercase pair, so all three boxes print httpresponse. userIDNumber becomes user_idnumber: the only inserted boundary is before the I, and Number stays glued to it.

  • Split API_KEY on the underscore and you get apiKey.
  • Keep a camelCase name out of the camel box if you still need its capitals.
  • Expect HTTPResponse and XMLHttpRequest to lose their inner words.
  • Compare the three boxes on the original string, not on each other's output.

Separators and the Turkish capital I are not the same bug

a__b stays a__b in snake case, because existing underscores are not collapsed. Kebab case turns that run into one hyphen and prints a-b. A leading underscore on _private survives in snake case and becomes -private in kebab case. Camel case drops the empty piece and prints private. 123abc is unchanged apart from case, and a leading digit is still not a legal identifier in most languages.

ASCII I becomes i. The Turkish capital İ, U+0130, becomes U+0069 followed by the combining dot U+0307. İstanbul therefore looks like istanbul and is not the same string as the ASCII result of ISTANBUL. The tool does not call toLocaleLowerCase, so a Turkish browser locale does not turn a plain I into a dotless ı.

Diff the key, not a second conversion

Put the original key and the three outputs in one note. If a JSON payload must change from maxTorque to max_torque, copy the snake result and diff it against the key the server already stores. Do not camel-case the snake result and assume you have returned to the input: that round trip works only when the separators were already present.

Use the JSON formatter to see the key in context, the case tool on the untouched identifier, and diff before you rename a column or a field. The ticket should quote the input and the output that will ship.

Try these tools