caseflipper
v1.1.0
Published
A package that converts a string into different casing formats
Maintainers
Readme
Case Flipper
A lightweight TypeScript utility library for converting strings between various casing formats — plus a CLI to rename identifiers across your entire project.
Features
- 🚀 Zero Dependencies (library): Pure TypeScript implementation.
- 📦 ESM Support: Built for modern environments.
- 📘 TypeScript Ready: Full type definitions included.
- ✅ Tested: High test coverage with Vitest.
- 🔧 CLI: Rename variables project-wide with AST-based precision.
Supported Formats
snake_casekebab-casecamelCasePascalCaseCONSTANT_CASE
Installation
npm install caseflipperLibrary Usage
import {
snakeCase,
kebabCase,
camelCase,
pascalCase,
constantCase,
} from 'caseflipper';
// Snake Case
console.log(snakeCase('helloWorld')); // hello_world
console.log(snakeCase('hello-world')); // hello_world
// Kebab Case
console.log(kebabCase('helloWorld')); // hello-world
console.log(kebabCase('hello_world')); // hello-world
// Camel Case
console.log(camelCase('hello_world')); // helloWorld
console.log(camelCase('hello-world')); // helloWorld
// Pascal Case
console.log(pascalCase('hello_world')); // HelloWorld
console.log(pascalCase('hello-world')); // HelloWorld
// Constant Case
console.log(constantCase('helloWorld')); // HELLO_WORLD
console.log(constantCase('hello-world')); // HELLO_WORLDCLI Usage
Scan a project's source files and rename all variable/identifier names to a target case convention using AST-based renaming (powered by ts-morph).
Quick Start
# Convert all identifiers in a specific file
npx caseflipper snakecase ./src/App.tsx
# Convert all identifiers in ./src to snake_case
npx caseflipper snakecase
# Convert to camelCase in a specific directory
npx caseflipper camelcase ./lib
# Preview changes without modifying files
npx caseflipper snakecase ./src/index.js --dry-runSupported Case Types
| Case Type | Example Output |
| -------------- | -------------- |
| snakecase | my_variable |
| camelcase | myVariable |
| pascalcase | MyVariable |
| constantcase | MY_VARIABLE |
Note:
kebabcaseis not supported for identifier renaming because JavaScript/TypeScript identifiers cannot contain hyphens.
Flags
| Flag | Description | Default |
| ------------------ | ------------------------------------------ | ----------------------------- |
| --dry-run | Preview changes without writing files | false |
| --ext <exts> | Comma-separated file extensions to include | .ts,.tsx,.js,.jsx,.mjs,.cjs |
| --ignore <globs> | Comma-separated glob patterns to exclude | node_modules,dist |
| --force | Skip git dirty-check warning | false |
Safety Features
- Git dirty check: If the target directory is in a git repo with uncommitted changes, the CLI will warn you and exit. Use
--forceto override. - Automatic backup: If the target directory is not in a git repo, a
.caseflipper-backup/directory is created with copies of all files before modification. - Dry run: Use
--dry-runto see what would change without modifying any files.
What Gets Renamed
The CLI uses AST-based renaming to safely transform:
- Variable declarations (
const,let,var) and their references - Function declarations and parameters
- Class, interface, type alias, and enum declarations
- Destructured binding names (e.g. React hooks
const [count, setCount] = useState(0))
It does not rename:
- Imported/exported names from external packages (e.g.,
useState,React,next/link) - Object property keys or string literals
- Reserved words
- Single-character identifiers
Project-Specific Guides
1. Vanilla JavaScript Projects (.js, .mjs, .cjs)
Whether you have a Node.js backend, a static website, or a Vanilla JS module:
Step 1: Run with npx (No installation needed)
# Convert a single file (preview first)
npx caseflipper snakecase ./index.js --dry-run
# Convert a single file in-place
npx caseflipper snakecase ./index.js
# Convert an entire folder of scripts
npx caseflipper snakecase ./srcStep 2: Or install locally
npm install -D caseflipperAdd convenient scripts to your package.json:
{
"scripts": {
"case:snake": "caseflipper snakecase ./src",
"case:camel": "caseflipper camelcase ./src"
}
}What Happens to Your Code
// Before
function calculateTotalPrice(productCount, itemRate) {
let discountAmount = 5;
return productCount * itemRate - discountAmount;
}
// After: npx caseflipper snakecase ./index.js
function calculate_total_price(product_count, item_rate) {
let discount_amount = 5;
return product_count * item_rate - discount_amount;
}2. React.js Projects (.jsx, .tsx - Vite, Create React App, etc.)
Case Flipper parses JSX/TSX syntax cleanly and respects React hooks, props, and component scopes.
Step 1: Run with npx
# Convert a single component file
npx caseflipper snakecase ./src/components/UserProfile.tsx --dry-run
# Convert the component file in-place
npx caseflipper snakecase ./src/components/UserProfile.tsx
# Convert all components in ./src
npx caseflipper camelcase ./srcWhat Happens to Your Code
- Preserved: External imports (e.g.
import React, { useState, useEffect } from 'react') are never renamed. - Converted: Component names, state variables, destructured props, and all JSX expressions
{user_name}are updated in sync.
// Before
import React, { useState } from 'react';
export const UserCard = ({ userAge }: { userAge: number }) => {
const [userName, setUserName] = useState('Alex');
return (
<div>
<h3>{userName}</h3>
<p>Age: {userAge}</p>
<button onClick={() => setUserName('Jordan')}>Update</button>
</div>
);
};
// After: npx caseflipper snakecase ./src/components/UserCard.tsx
import React, { useState } from 'react';
export const user_card = ({ user_age }: { user_age: number }) => {
const [user_name, set_user_name] = useState('Alex');
return (
<div>
<h3>{user_name}</h3>
<p>Age: {user_age}</p>
<button onClick={() => set_user_name('Jordan')}>Update</button>
</div>
);
};3. Next.js Projects (App Router & Pages Router)
Works seamlessly with TypeScript (.ts, .tsx) or JavaScript (.js, .jsx) in Next.js 13, 14, and 15+.
Step 1: Run with npx
# Target a specific page or route
npx caseflipper snakecase ./app/dashboard/page.tsx --dry-run
# Convert an App Router route or page in-place
npx caseflipper snakecase ./app/dashboard/page.tsx
# Convert all UI components, ignoring build output
npx caseflipper camelcase ./components --ignore node_modules,.nextWhat Happens to Your Code
- Preserved: Next.js framework imports (
next/link,next/image,next/navigation,next/headers) and external libraries remain completely untouched. - Converted: Local helper functions, parameters, fetched state, and destructured variables are safely updated.
// Before
import Link from 'next/link';
import Image from 'next/image';
export default async function DashboardPage() {
const userProfile = await fetchUserData();
const avatarUrl = userProfile.avatar;
return (
<main>
<h1>Welcome, {userProfile.name}</h1>
<Image src={avatarUrl} alt="Avatar" width={64} height={64} />
<Link href="/settings">Settings</Link>
</main>
);
}
// After: npx caseflipper snakecase ./app/dashboard/page.tsx
import Link from 'next/link';
import Image from 'next/image';
export default async function dashboard_page() {
const user_profile = await fetch_user_data();
const avatar_url = user_profile.avatar;
return (
<main>
<h1>Welcome, {user_profile.name}</h1>
<Image src={avatar_url} alt="Avatar" width={64} height={64} />
<Link href="/settings">Settings</Link>
</main>
);
}License
MIT © Khalid Kakar
