change-case vs camelcase vs slugify: String Transformation in JavaScript (2026)
TL;DR
change-case is the most comprehensive string transformation library — one package that handles every case format (camelCase, PascalCase, kebab-case, snake_case, SCREAMING_SNAKE_CASE, etc.). camelcase is the single-purpose option — just converts strings to camelCase, ~300B, tree-shakable, and Sindre Sorhus quality. slugify converts strings to URL-safe slugs — handles Unicode, transliteration (converting accented chars to ASCII), and special characters. For all-in-one case conversions: change-case. For just camelCase: camelcase. For URL slugs: slugify.
Key Takeaways
- change-case: ~15M weekly downloads — all case formats in one package, tree-shakable
- camelcase: ~70M weekly downloads — single-purpose, most popular, Sindre Sorhus
- slugify: ~5M weekly downloads — URL slugs, Unicode transliteration, SEO-safe
- Node.js
String.prototype.toUpperCase/toLowerCaseare built-in — use them for simple cases - change-case is modular —
import { camelCase } from "change-case"only pulls what you need - For API/database field name conversion (snake_case → camelCase), change-case is the standard
Download Trends
| Package | Weekly Downloads | Bundle Size | All Cases | Unicode | URL Slugs |
|---|---|---|---|---|---|
change-case | ~15M | ~30KB total | ✅ | ✅ | ❌ |
camelcase | ~70M | ~300B | ❌ camelCase only | ✅ | ❌ |
slugify | ~5M | ~10KB | ❌ | ✅ | ✅ |
change-case
change-case — comprehensive case conversion:
All case formats
import {
camelCase,
pascalCase,
snakeCase,
kebabCase,
constantCase,
dotCase,
pathCase,
sentenceCase,
capitalCase,
noCase,
trainCase,
} from "change-case"
const input = "hello world foo bar"
camelCase(input) // "helloWorldFooBar"
pascalCase(input) // "HelloWorldFooBar"
snakeCase(input) // "hello_world_foo_bar"
kebabCase(input) // "hello-world-foo-bar"
constantCase(input) // "HELLO_WORLD_FOO_BAR" (SCREAMING_SNAKE_CASE)
dotCase(input) // "hello.world.foo.bar"
pathCase(input) // "hello/world/foo/bar"
sentenceCase(input) // "Hello world foo bar"
capitalCase(input) // "Hello World Foo Bar"
noCase(input) // "hello world foo bar" (normalized)
trainCase(input) // "Hello-World-Foo-Bar" (HTTP header style)
Handles mixed inputs
import { camelCase, snakeCase, kebabCase } from "change-case"
// From snake_case:
camelCase("user_first_name") // "userFirstName"
camelCase("api_response_data") // "apiResponseData"
// From camelCase:
snakeCase("userFirstName") // "user_first_name"
kebabCase("packageHealthScore") // "package-health-score"
// From PascalCase:
snakeCase("PackageHealthScore") // "package_health_score"
kebabCase("PackageHealthScore") // "package-health-score"
// From SCREAMING_SNAKE_CASE:
camelCase("HTTP_STATUS_CODE") // "httpStatusCode"
camelCase("API_ENDPOINT_URL") // "apiEndpointUrl"
// From mixed:
camelCase(" hello world ") // "helloWorld" (trims + handles spaces)
camelCase("hello-world_foo.bar") // "helloWorldFooBar" (mixed separators)
Practical use cases
import { camelCase, snakeCase, pascalCase } from "change-case"
// API response normalization — convert snake_case → camelCase:
function normalizeApiResponse<T extends Record<string, unknown>>(data: T) {
return Object.fromEntries(
Object.entries(data).map(([key, value]) => [camelCase(key), value])
)
}
const apiResponse = {
user_id: "123",
first_name: "Alice",
package_health_score: 95,
is_premium_user: true,
}
normalizeApiResponse(apiResponse)
// { userId: "123", firstName: "Alice", packageHealthScore: 95, isPremiumUser: true }
// Database query — convert camelCase → snake_case for PostgreSQL:
function toDbColumns(obj: Record<string, unknown>) {
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => [snakeCase(key), value])
)
}
// Generate component names from file names:
const fileName = "package-health-card"
pascalCase(fileName) // "PackageHealthCard" — React component name
// Environment variable names:
constantCase("databaseConnectionString") // "DATABASE_CONNECTION_STRING"
camelcase
camelcase — single-purpose, Sindre Sorhus quality:
Usage
import camelCase from "camelcase"
// Basic:
camelCase("foo bar") // "fooBar"
camelCase("foo-bar") // "fooBar"
camelCase("foo_bar") // "fooBar"
camelCase("Foo Bar") // "fooBar"
camelCase("--foo-bar--") // "fooBar"
camelCase("__foo_bar__") // "fooBar"
camelCase("FOO_BAR") // "fooBar"
// PascalCase option:
camelCase("foo bar", { pascalCase: true }) // "FooBar"
// Preserve consecutive uppercase (for acronyms):
camelCase("myURL") // "myUrl" (default)
camelCase("myURL", { preserveConsecutiveUppercase: true }) // "myURL"
// Multiple words:
camelCase(["foo", "bar"]) // "fooBar"
camelCase(["--foo-bar", "--foo-baz"]) // "fooBarFooBaz"
When camelcase beats change-case
// camelcase is 70M downloads/week vs change-case's 15M
// because it's focused, small, and trusted
// Bundle comparison:
// import camelCase from "camelcase" → 300B
// import { camelCase } from "change-case" → ~5KB (even with tree-shaking)
// For packages or libraries that only need camelCase conversion,
// camelcase is the right choice to minimize bundle size
slugify
slugify — URL-safe string transformation:
Basic usage
import slugify from "slugify"
// Basic slug:
slugify("React vs Vue: A Comprehensive Comparison (2026)")
// "React-vs-Vue-A-Comprehensive-Comparison-2026"
// Lowercase (recommended for URLs):
slugify("React vs Vue: A Comprehensive Comparison (2026)", {
lower: true,
})
// "react-vs-vue-a-comprehensive-comparison-2026"
// With strict mode (only alphanumeric + separator):
slugify("Hello World! @2026 #npm", { strict: true, lower: true })
// "hello-world-2026-npm"
Unicode transliteration
import slugify from "slugify"
// Converts accented characters to ASCII equivalents:
slugify("Ångström units & schülerschaft", { lower: true })
// "angstrom-units-and-schuleschaft"
slugify("Über alles", { lower: true })
// "uber-alles"
slugify("José García", { lower: true })
// "jose-garcia"
// Chinese/Japanese/Korean — requires locale configuration:
slugify("中文", { locale: "zh", lower: true })
// "zhong-wen"
// Custom character map:
slugify.extend({ "♥": "love", "©": "copyright" })
slugify("I ♥ npm packages © 2026")
// "I-love-npm-packages-copyright-2026"
Blog URL slug generation
import slugify from "slugify"
// Generate SEO-friendly URL slugs:
function generateSlug(title: string, date: string): string {
const slug = slugify(title, {
lower: true,
strict: true, // Remove special characters
trim: true,
})
// Optional: append date for uniqueness
// return `${date}-${slug}`
return slug
}
generateSlug("React vs Vue: Which is Better in 2026?", "2026-03-09")
// "react-vs-vue-which-is-better-in-2026"
generateSlug("Top 10 npm Packages You're Not Using (But Should)", "2026-03-09")
// "top-10-npm-packages-youre-not-using-but-should"
// For Next.js static generation:
export async function generateStaticParams() {
const posts = await getAllPosts()
return posts.map((post) => ({
slug: generateSlug(post.title, post.date),
}))
}
Feature Comparison
| Feature | change-case | camelcase | slugify |
|---|---|---|---|
| camelCase | ✅ | ✅ | ❌ |
| PascalCase | ✅ | ✅ (option) | ❌ |
| snake_case | ✅ | ❌ | ❌ |
| kebab-case | ✅ | ❌ | ❌ |
| SCREAMING_SNAKE | ✅ | ❌ | ❌ |
| URL slugs | ❌ | ❌ | ✅ |
| Unicode transliteration | ✅ | ❌ | ✅ |
| Special char removal | ✅ | ✅ | ✅ |
| Bundle size | ~5KB/fn | ~300B | ~10KB |
| TypeScript | ✅ | ✅ | ✅ |
| Tree-shakable | ✅ | N/A | N/A |
When to Use Each
Choose change-case if:
- You need multiple case formats (not just camelCase)
- Normalizing API responses (snake_case → camelCase)
- Generating database column names, environment variables, component names
- Build tools or code generation where multiple cases are needed
Choose camelcase if:
- You only need camelCase conversion — no other formats
- Bundle size is critical — 300B vs 5KB makes a difference in edge environments
- You want the Sindre Sorhus-quality
preserveConsecutiveUppercaseoption
Choose slugify if:
- Generating URL-safe slugs for blog posts, product pages, or any URL segment
- You need Unicode transliteration (accented chars → ASCII)
- SEO-friendly URL generation in Next.js/Astro/Nuxt content pipelines
Use built-ins for simple cases:
// Don't install a library for simple lowercase/uppercase:
"Hello World".toLowerCase() // "hello world" — no library needed
"hello world".toUpperCase() // "HELLO WORLD"
// For title case without a library:
const titleCase = (s: string) =>
s.replace(/\b\w/g, (c) => c.toUpperCase())
// "hello world" → "Hello World"
Methodology
Download data from npm registry (weekly average, February 2026). Feature comparison based on change-case v5.x, camelcase v8.x, and slugify v1.x.
Compare string utility and JavaScript packages on PkgPulse →