snake_case Converter
snake_case writes hello_world_example. It is the convention for variables and functions in Python and Ruby, and for column names in SQL, where case-insensitive identifiers make camelCase unreliable.
Conversions
| Input | snake_case |
|---|---|
hello world example | hello_world_example |
XMLHttpRequest | xml_http_request |
user_first_name | user_first_name |
Total Order Count | total_order_count |
XMLHttpRequest becomes xml_http_request. That uniformity is why snake_case survives round-tripping better than the camel family — there is no capitalisation left to get wrong on the way back.The Same Text in Other Cases
| Case | Result |
|---|---|
| camelCase | helloWorldExample |
| PascalCase | HelloWorldExample |
| SCREAMING_SNAKE_CASE | HELLO_WORLD_EXAMPLE |
| kebab-case | hello-world-example |
| Train-Case | Hello-World-Example |
| dot.case | hello.world.example |
Where snake_case Fits
snake_case is the convention across Python, Ruby, Rust and SQL, and it is the safest choice for anything that will cross a language boundary — a database column, a JSON key consumed by several stacks, a config file read by more than one tool.
Converting in Code
``javascript
const snake = (s) => words(s).map((w) => w.toLowerCase()).join('_');
`
The failure mode is on the way *in*, not out. A converter that splits only on existing underscores turns userId into userid rather than user_id, and the mistake is invisible until someone searches for a column that does not exist.
Where snake_case Is the Convention
| Language / context | Uses snake_case for |
|---|---|
| Python | Variables, functions, modules (PEP 8) |
| Ruby | Variables, methods, files |
| Rust | Variables, functions, modules, files |
| SQL | Table and column names |
| C | Most identifiers by tradition |
SQL is the strongest case for it. Most database engines fold unquoted identifiers to one case,
so userId and userid are the same column — camelCase simply does not survive, and
quoting every identifier to preserve it is worse than adopting underscores.Snake case is also measurably faster to read for non-native English speakers, since the
underscore is an unambiguous word boundary where a case change is a subtler cue.
Converting at the API Boundary
The recurring friction is that JavaScript uses camelCase and Python, Ruby, Go and SQL use
snake_case. The fix is to convert in exactly one place — the client that talks to the API —
rather than letting both conventions into the same codebase.
`javascript
const toCamel = (s) => s.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
const toSnake = (s) => s.replace(/[A-Z]/g, (c) => '_' + c.toLowerCase());
// Recursively, for a whole payload
const convertKeys = (value, fn) =>
Array.isArray(value)
? value.map((v) => convertKeys(v, fn))
: value && typeof value === 'object'
? Object.fromEntries(Object.entries(value).map(([k, v]) => [fn(k), convertKeys(v, fn)]))
: value;
`
Two things to watch: keys that are user data rather than field names must not be
converted, and the round trip is not always lossless — userID → user_id → userId
changes the original.
Where Each Convention Is Mandatory
Not stylistic — these will break if you deviate:
| Context | Requirement |
|---|---|
| Environment variables | Uppercase with underscores; POSIX reserves lowercase |
| Custom HTML elements | Must contain a hyphen |
| Python modules | Cannot contain hyphens; the import statement will not parse |
| SQL identifiers | Folded to one case unless quoted, so camelCase does not survive |
| React components | Must start uppercase, or JSX treats it as an HTML tag |
Renaming Safely
A find-and-replace across a codebase will hit strings, comments and unrelated identifiers.
Use your language server's rename symbol instead — it understands scope. For a bulk rename
across files, restrict the pattern with word boundaries and review the diff before
committing:
`bash
grep -rn '\buserId\b' src/ # look first
``