Convert camelCase and PascalCase strings to snake_case from the command line. Zero dependencies.
$ camel2snake getElementById XMLParser parseHTTPResponse
get_element_by_id
xml_parser
parse_http_response
- API migrations — JavaScript → Python field mapping in one pipe
- Env var generation —
camel2snake -uturns config keys intoUPPER_SNAKE_CASE - Acronym-aware —
XMLParser→xml_parser, notx_m_l_parser - Pipe-friendly — reads stdin, writes stdout, composes with any tool
- Zero dependencies — installs in ~1 second
npm install -g @kszongic/camel2snake-cli
# Or use without installing
npx @kszongic/camel2snake-cli helloWorld# Single string
camel2snake helloWorld
# hello_world
# Multiple strings
camel2snake getElementById XMLParser MyComponent
# get_element_by_id
# xml_parser
# my_component
# UPPER_SNAKE_CASE (perfect for env vars)
camel2snake -u databaseUrl apiKey jwtSecret
# DATABASE_URL
# API_KEY
# JWT_SECRET
# Pipe from stdin
echo "myVariable" | camel2snake
# my_variable
cat identifiers.txt | camel2snake| Flag | Description |
|---|---|
-u, --upper |
Output UPPER_SNAKE_CASE |
-h, --help |
Show help |
-v, --version |
Show version |
| Input | Output | With -u |
|---|---|---|
helloWorld |
hello_world |
HELLO_WORLD |
getElementById |
get_element_by_id |
GET_ELEMENT_BY_ID |
XMLParser |
xml_parser |
XML_PARSER |
MyComponent |
my_component |
MY_COMPONENT |
parseHTTPResponse |
parse_http_response |
PARSE_HTTP_RESPONSE |
getURLForID |
get_url_for_id |
GET_URL_FOR_ID |
cat <<EOF | camel2snake -u
databaseUrl
redisHost
jwtSecret
maxRetryCount
EOF
# DATABASE_URL
# REDIS_HOST
# JWT_SECRET
# MAX_RETRY_COUNTecho '{"firstName":"John","lastName":"Doe"}' \
| node -e "process.stdout.write(Object.keys(JSON.parse(require('fs').readFileSync(0,'utf8'))).join('\n'))" \
| camel2snake
# first_name
# last_namepaste <(cat fields.txt) <(cat fields.txt | camel2snake) > mapping.tsv# camelCase → snake_case → kebab-case
echo "myVariableName" | camel2snake | snake2kebab
# my-variable-name{
"scripts": {
"gen:env": "cat config-keys.txt | camel2snake -u > .env.example"
}
}alias c2s='camel2snake'
alias c2S='camel2snake -u'The converter scans each string character by character, inserting underscores at case boundaries. Consecutive uppercase characters (acronyms like XML, HTTP, URL) are treated as a single token rather than individual letters — so XMLParser correctly becomes xml_parser, not x_m_l_parser.
- Backend migrations — Convert field names between JS/TS and Python/Ruby/Rust conventions
- Environment variables — Generate
UPPER_SNAKE_CASEenv var names from config - Database mapping — Map ORM fields to SQL column names
- Code generation — Automate naming in scaffolding tools
- CI/CD — Enforce naming conventions in pipelines
| Tool | Zero Deps | Cross-Platform | Stdin | Acronyms | UPPER_SNAKE |
|---|---|---|---|---|---|
| camel2snake-cli | ✅ | ✅ | ✅ | ✅ | ✅ |
sed regex |
✅ | ✅ | ❌ | Manual | |
change-case (lib) |
❌ | ✅ | ❌ | ✅ | ✅ |
| Python one-liner | ❌ needs Python | ✅ | ✅ | ❌ | Manual |
| Online converters | N/A | Browser | ❌ | Varies | Varies |
Part of the @kszongic case conversion family:
- snake2camel-cli —
snake_case→camelCase - kebab2camel-cli —
kebab-case→camelCase - kebab2snake-cli —
kebab-case→snake_case - snake2pascal-cli —
snake_case→PascalCase - pascal2snake-cli —
PascalCase→snake_case
Other useful tools:
- env-lint-cli — Validate .env files
- dep-size — Check npm dependency sizes
- npm-name-check — Check npm name availability
MIT © 2026 kszongic