New:Microsoft Teams Notifications Are Now Available in Socket.Learn more →
Get Started

caseparser

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

caseparser

Convert Strings/Arrays/Objects from a type of case to another one.

Source
npmnpm
Version
4.3.0
Version published
Weekly downloads
973
-35.35%
Maintainers
1
Weekly downloads
 
Created
Source

CaseParser

npm version JSR JSR Score CI npm downloads license

Convert Strings and JSON (Object Keys) from a case type to another one with type inference based on parameter's type.

  • Zero dependencies
  • Written in TypeScript, published as ESM and CommonJS with type declarations
  • Available on npm and JSR
  • Tree-shakeable
Note:

If you're looking for version 1.x.x, click here to see the docs.

Installation

npm add caseparser    # or: pnpm add caseparser / yarn add caseparser
Deno (JSR)
deno add jsr:@nandomb/caseparser
import { camelToSnake } from '@nandomb/caseparser';
Bun / Node.js from JSR
bunx jsr add @nandomb/caseparser
npx jsr add @nandomb/caseparser

Compatibility

EnvironmentSupported
ESM (import)Node.js 12.22+, Deno, Bun, bundlers
CommonJS (require)Node.js 8+, Bun
TypeScript4.1+ (any moduleResolution: node, node16/nodenext, bundler). The toX type inference needs 4.5+ for keys longer than ~20 characters
BrowsersAny ES2015 browser (via bundler)
EdgeCloudflare Workers

Every change is tested in CI on Node.js 22, 24 and 26, Bun, Deno, Cloudflare Workers, and in Chromium, Firefox and WebKit.

Ready-to-run projects for each environment (Node.js ESM/CommonJS, TypeScript, TypeScript 4.1, Bun, Deno, the browser and Cloudflare Workers) are in examples/.

How to use

import { toSnake } from 'caseparser';      // ESM
// const { toSnake } = require('caseparser'); // CommonJS

toSnake('helloWorld'); // 'hello_world'

toSnake({ firstName: 'John', addresses: [{ postalCode: '61105' }] });
// { first_name: 'John', addresses: [{ postal_code: '61105' }] }

Objects are converted deeply, including objects inside arrays. The input is never mutated: a new object is returned.

There is one function per target case, and the input can be in any case (see From any case):

toCamel('helloWorld');      // 'helloWorld'
toPascal('helloWorld');     // 'HelloWorld'
toSnake('helloWorld');      // 'hello_world'
toDash('helloWorld');       // 'hello-world'
toUpperSnake('helloWorld'); // 'HELLO_WORLD'
toUpperDash('helloWorld');  // 'HELLO-WORLD'
toTrain('helloWorld');      // 'Hello-World'
toDot('helloWorld');        // 'hello.world'
toTitle('helloWorld');      // 'Hello World'
toSentence('helloWorld');   // 'Hello world'

Typical use: API responses

import { toCamel, toSnake } from 'caseparser';

const res = await fetch('/api/users/1');
const user = toCamel(await res.json());   // { firstName, lastName, ... }

await fetch('/api/users/1', {
  method: 'PUT',
  body: JSON.stringify(toSnake(user)),          // back to { first_name, ... }
});

Type inference

The resulting keys are inferred at the type level, so your editor autocompletes the converted names:

const user = toCamel({ first_name: 'John', addresses: [{ postal_code: '61105' }] });
//    ^? { firstName: string; addresses: { postalCode: string }[] }

user.firstName;  // ✅
user.first_name; // ❌ Property 'first_name' does not exist

From any case

You don't need to know the input's case: the input is split into words whatever its case, so keys in different cases can even be mixed in the same object:

import { toCamel, toSnake } from 'caseparser';

toSnake('helloWorld');  // 'hello_world'
toSnake('Hello World'); // 'hello_world'
toSnake('HELLO-WORLD'); // 'hello_world'

toCamel({ user_id: 1, 'Last-Name': 'Doe', XMLHttpRequest: true });
//    ^? { userId: number; lastName: string; xmlHttpRequest: boolean }

Words are split on _, -, . and spaces, and before an uppercase letter that starts a new word.

Conversion Types

Deprecated: the <from>To<To> functions below are deprecated in favor of the toX functions (How to use) and will be removed in the next major version. They keep working until then. See Migrating to toX.

Every function is named <from>To<To>, e.g. snakeToCamel. The case names are:

NameExample
camelhelloWorld
pascalHelloWorld
snakehello_world
dashhello-world
upperSnakeHELLO_WORLD
upperDashHELLO-WORLD
trainHello-World
dothello.world
titleHello World
sentenceHello world

All 90 functions:

  • camelCase: camelToPascal, camelToSnake, camelToDash, camelToUpperSnake, camelToUpperDash, camelToTrain, camelToDot, camelToTitle, camelToSentence
  • PascalCase: pascalToCamel, pascalToSnake, pascalToDash, pascalToUpperSnake, pascalToUpperDash, pascalToTrain, pascalToDot, pascalToTitle, pascalToSentence
  • snake_case: snakeToCamel, snakeToPascal, snakeToDash, snakeToUpperSnake, snakeToUpperDash, snakeToTrain, snakeToDot, snakeToTitle, snakeToSentence
  • dash-case: dashToCamel, dashToPascal, dashToSnake, dashToUpperSnake, dashToUpperDash, dashToTrain, dashToDot, dashToTitle, dashToSentence
  • UPPER_SNAKE_CASE: upperSnakeToCamel, upperSnakeToPascal, upperSnakeToSnake, upperSnakeToDash, upperSnakeToUpperDash, upperSnakeToTrain, upperSnakeToDot, upperSnakeToTitle, upperSnakeToSentence
  • UPPER-DASH-CASE: upperDashToCamel, upperDashToPascal, upperDashToSnake, upperDashToDash, upperDashToUpperSnake, upperDashToTrain, upperDashToDot, upperDashToTitle, upperDashToSentence
  • Train-Case: trainToCamel, trainToPascal, trainToSnake, trainToDash, trainToUpperSnake, trainToUpperDash, trainToDot, trainToTitle, trainToSentence
  • dot.case: dotToCamel, dotToPascal, dotToSnake, dotToDash, dotToUpperSnake, dotToUpperDash, dotToTrain, dotToTitle, dotToSentence
  • Title Case: titleToCamel, titleToPascal, titleToSnake, titleToDash, titleToUpperSnake, titleToUpperDash, titleToTrain, titleToDot, titleToSentence
  • Sentence case: sentenceToCamel, sentenceToPascal, sentenceToSnake, sentenceToDash, sentenceToUpperSnake, sentenceToUpperDash, sentenceToTrain, sentenceToDot, sentenceToTitle

Migrating to toX

Replace each <from>To<To> function with the toX function for its target case, whatever the source case: camelToSnake, dashToSnake, titleToSnake... all become toSnake.

For well-formed keys (firstName, first_name) the result is the same. It differs when a key has consecutive uppercase letters or doesn't match the source case:

Call<from>To<To> resulttoX result
camelToSnake('userID') / toSnake('userID')'user_i_d''user_id'
camelToSnake('XMLHttpRequest') / toSnake('XMLHttpRequest')'_x_m_l_http_request''xml_http_request'
camelToSnake('HelloWorld') / toSnake('HelloWorld')'_hello_world''hello_world'
snakeToCamel('user_ID') / toCamel('user_ID')'userID''userId'

If your code reads keys like user_i_d produced by the old functions, update those reads when migrating. The inferred types follow the new results, so TypeScript points out every place to change.

Behavior and limitations

  • Only keys are converted, never values. In { userName: 'johnDoe' }, userName becomes user_name but 'johnDoe' is kept. Strings inside arrays are kept too.
  • Only plain objects are traversed. Date, Map, Set and class instances are returned as they are (same reference), without converting their contents.
  • Acronyms are kept together, but not restored: toSnake('userID') → 'user_id', and back toCamel('user_id') → 'userId'.
  • Words are lowercased before converting, so toCamel('X-API-Key') → 'xApiKey' and toCamel('First Name') → 'firstName'.
  • Title Case capitalizes every word, including short ones: toTitle('termsOfUse') → 'Terms Of Use'.
  • Digits stay attached to the previous word: toSnake('html5Parser') → 'html5_parser', toSnake('user1Name') → 'user1_name'.
  • Type inference has a key length limit. TypeScript limits how deeply a type can recurse, and keys are converted character by character at the type level. With TypeScript 4.5+, the toX functions infer keys up to ~120 characters; with TypeScript 4.1 to 4.4, only up to ~20 characters. Longer keys fail to compile with Type instantiation is excessively deep and possibly infinite. The runtime conversion has no limit.

Security

caseparser is safe to use with untrusted input (e.g. request bodies or JSON.parse output): keys such as __proto__ are copied as regular keys and never change an object's prototype, and only the object's own properties are converted.

Releases are built and published from GitHub Actions without long-lived tokens (OIDC), with npm provenance, so every published version can be traced back to the exact commit and workflow that built it. On npm, new versions are staged and only go live after a maintainer approves them with 2FA.

Found a vulnerability? Please report it privately, see SECURITY.md.

License

MIT © 2017 Fernando Machado Bernardino

Keywords

caseparser

FAQs

Package last updated on 24 Sep 2026

Related posts