Converting Cases Across Programming Languages: A Practical Reference

May 28, 20267 min read

Why Case Conversion Matters

Different contexts demand different naming conventions. An API returns snake_case keys, but your TypeScript codebase uses camelCase. A database column is created_at, but your Java model needs createdAt. A CLI flag is --max-retries, but your Python variable is max_retries.

Case conversion bridges these boundaries. Doing it correctly — handling abbreviations, acronyms, and edge cases — separates robust code from fragile string manipulation.

Case Types at a Glance

CasePatternExampleTypical Use
camelCasefirstWordLower, restUppergetUserByIdJS/TS variables, functions
PascalCaseeveryWordUpperUserServiceClasses, types, components
snake_caseall_lower_with_underscoresuser_namePython, Ruby, database columns
SCREAMING_SNAKEALL_UPPER_WITH_UNDERSCORESMAX_RETRIESConstants
kebab-caseall-lower-with-hyphenscontent-typeURLs, CLI flags, HTTP headers
UPPER_KEBABALL-UPPER-WITH-HYPHENSCONTENT-TYPEHTTP headers (alternative)

JavaScript / TypeScript

Using Lodash

import { camelCase, snakeCase, kebabCase, upperFirst } from 'lodash'

camelCase('user_name')      // 'userName'
snakeCase('userName')       // 'user_name'
kebabCase('userName')       // 'user-name'
upperFirst(camelCase('user_name'))  // 'UserName' (PascalCase)

Manual Conversion

// camelCase to snake_case
function toSnakeCase(str) {
  return str
    .replace(/([A-Z])/g, '_$1')
    .toLowerCase()
    .replace(/^_/, '')
}

// snake_case to camelCase
function toCamelCase(str) {
  return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase())
}

// Any case to PascalCase
function toPascalCase(str) {
  return str
    .replace(/([_-][a-z])/g, (_, c) => c.slice(1).toUpperCase())
    .replace(/^[a-z]/, c => c.toUpperCase())
}

Transforming Object Keys

A common use case: converting API response keys from snake_case to camelCase:

function transformKeys(obj) {
  if (Array.isArray(obj)) return obj.map(transformKeys)
  if (obj !== null && typeof obj === 'object') {
    return Object.fromEntries(
      Object.entries(obj).map(([key, value]) => [
        toCamelCase(key),
        transformKeys(value)
      ])
    )
  }
  return obj
}

Python

Built-in (Limited)

# Only handles a few conversions
'userName'.replace('_', '-').lower()  # not general-purpose

Using inflection

import inflection

inflection.camelize('user_name')         # 'UserName' (PascalCase)
inflection.camelize('user_name', False)   # 'userName' (camelCase)
inflection.underscore('UserName')         # 'user_name' (snake_case)
inflection.dasherize('user_name')         # 'user-name' (kebab-case)

Using pydantic

Pydantic models support automatic alias generation:

from pydantic import BaseModel, ConfigDict

class User(BaseModel):
    model_config = ConfigDict(alias_generator=lambda x: inflection.camelize(x, False))

    first_name: str
    last_name: str

# Accepts camelCase input, uses snake_case internally
user = User.model_validate({'firstName': 'Alice', 'lastName': 'Smith'})
user.first_name  # 'Alice'

Java

Using Jackson

Jackson can map between naming conventions during serialization:

@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class User {
    private String firstName;
    private String lastName;
}
// Serializes as: {"first_name": "Alice", "last_name": "Smith"}

Available strategies:

StrategyConverts to
SnakeCaseStrategyfirst_name
UpperCamelCaseStrategyFirstName
KebabCaseStrategyfirst-name
LowerDotCaseStrategyfirst.name

Using Guava

import com.google.common.base.CaseFormat;

CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, "firstName");  // "first_name"
CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, "first_name"); // "FirstName"
CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, "firstName");     // "first-name"

Go

Using strcase

import "github.com/iancoleman/strcase"

strcase.ToCamel("user_name")    // "UserName" (PascalCase)
strcase.ToLowerCamel("user_name") // "userName" (camelCase)
strcase.ToSnake("userName")     // "user_name"
strcase.ToKebab("userName")     // "user-name"

Using struct tags

Go's JSON and YAML tags handle naming convention mapping:

type User struct {
    FirstName string `json:"first_name" yaml:"first-name"`
    LastName  string `json:"last_name"  yaml:"last-name"`
}

Edge Cases to Handle

InputcamelCasesnake_casekebab-casePitfall
XMLParserxmlParserxml_parserxml-parserAcronym splitting
getUserIDget_user_idget-user-idConsecutive uppercase
HTTPSConnectionhttpsConnectionhttps_connectionhttps-connectionAcronym at start
already_snakealreadySnakealready-snakeDouble underscore
3dModel3dModel3d_model3d-modelLeading digit

No library handles all edge cases perfectly. Test against your actual data, especially names with acronyms and numbers.

Key Takeaways

  • Case conversion is essential at API boundaries, database mappings, and framework integrations
  • Lodash (JS), inflection (Python), Guava (Java), and strcase (Go) handle common conversions
  • Object key transformation is the most frequent use case — build a recursive transformer once and reuse it
  • Acronyms and consecutive uppercase letters are the hardest edge cases — test against real data
  • Prefer library solutions over regex for production code; they handle more edge cases
  • Use framework features (Pydantic aliases, Jackson naming strategies, Go struct tags) when available

Try It Yourself

Convert text between any naming convention instantly with our free Case Converter. Paste any string and see conversions across camelCase, PascalCase, snake_case, kebab-case, and more.