Word and Character Counts for UI Copy, SEO, and Reviews
How to count words and characters the way products and platforms do — limits, diffs, Markdown pitfalls, and a practical editing workflow for developers who ship copy.
A practical guide to naming conventions across JavaScript, APIs, CSS, and URLs — plus how to convert cases safely without breaking acronyms or slugs.
By codefunc
Naming conventions are boring until two systems disagree. JavaScript wants userId, Postgres wants user_id, CSS wants user-id, and your URL wants /users/jane-doe. A single mismatched case style creates subtle bugs: JSON fields that never bind, CSS classes that never match, and import paths that work on macOS and fail on Linux. Converting case is easy; converting it correctly across acronyms, numbers, and existing APIs is the real work.
Bottom line: Pick one convention per layer and convert at the boundary. Use a Case Converter for bulk renames, a Slug Generator for URL paths, and Line Sort & Dedupe when cleaning exported name lists — all in the browser, with no upload required.
Frontend and full-stack developers who rename props, sync OpenAPI schemas with database columns, or generate CSS class names and routes from human titles. If you have ever shipped userID in one service and userId in another, this guide is for you.
| Case | Example | Typical home |
|---|---|---|
| camelCase | createdAt |
JavaScript / TypeScript variables and object keys |
| PascalCase | CreatedAt |
React components, types, classes |
| snake_case | created_at |
Python, Ruby, SQL columns, many JSON APIs |
| SCREAMING_SNAKE | CREATED_AT |
Environment variables, constants |
| kebab-case | created-at |
CSS classes, HTML attributes, URL slugs |
| Train-Case | Created-At |
Occasional HTTP headers / legacy docs |
| dot.case | created.at |
Some config keys and i18n paths |
"Correct" means consistent with the ecosystem you are in, not universally elegant.
A durable default for web apps:
| Layer | Convention |
|---|---|
| TypeScript source | camelCase values, PascalCase types/components |
| React components | filename and export PascalCase |
| CSS modules / utility classes | kebab-case or team BEM variant |
| REST JSON (public) | Pick one of camel or snake and document it |
| SQL | snake_case |
| Env vars | SCREAMING_SNAKE |
| URLs | kebab-case slugs |
Convert at boundaries with explicit mappers (or a serialization layer), not by hoping humans remember.
Naïve converters turn userID into user_i_d or XMLParser into x_m_l_parser. Teams need a policy:
ID, URL, API, HTTP, JSONuserId over userID in TypeScript (ESLint camelcase / naming-convention rules often enforce this)parse_xml over parse_x_m_l in snake_caseWhen bulk-converting a list of identifiers, preview results. Paste into a Case Converter, scan for acronym damage, then apply in the editor.
Numbers also bite: base64Encoder → base_64_encoder is usually right; s3Bucket → s_3_bucket may not match an existing AWS-shaped name. Preserve established public names even when they violate local style.
There is no universal JSON standard. Practical guidance:
If you must accept both temporarily, normalize on the server and emit one shape. Dual response keys (user_id and userId) create clients that depend on both forever.
GraphQL fields are typically camelCase in the schema even when the database is snake_case — resolvers own the mapping. Protobuf fields use lower_snake in .proto files; generated JS/TS stubs may expose camelCase depending on the generator. Inspect generated types before writing manual converters.
CSS custom properties and class names favor kebab-case:
.button-primary { }
--color-bg-subtle: …;
HTML data-* attributes are case-insensitive in the DOM's HTML parsing quirks — data-userId becomes awkward; prefer data-user-id. In React, className and htmlFor are the camelCase exceptions driven by the DOM API, not by CSS naming.
Design tokens often start as camelCase in JS and compile to kebab-case CSS variables. Automate that transform; do not rename by hand in two files.
Human titles become path segments with different rules than code identifiers:
Product Launch — Q3! should become something like product-launch-q3, not ProductLaunchQ3. Use a Slug Generator when turning titles into routes, CMS keys, or anchor IDs. Case conversion alone is not slugification.
Migrating a messy list of names (CSV export, spreadsheet of field labels, dump of CSS classes):
For codemods in a repo, prefer AST tools (jscodeshift, TS morph) over regex for symbols. Use converters for documentation tables, config keys, and one-off renames.
Encode the convention so review does not rely on memory:
@typescript-eslint/naming-conventionkebab-case paths are common)Automated case tools help humans; linters keep the boundary from drifting.
Use these codefunc tools alongside this guide:
Choose a convention per layer, convert at the edges, and document the public JSON shape. Watch acronyms and numbers during bulk renames. Use kebab-case for URLs and CSS, camelCase for most TypeScript values, snake_case for SQL, and SCREAMING_SNAKE for env vars. For everyday transforms, keep the work local with Case Converter, Slug Generator, and Line Sort & Dedupe — paste, transform, copy, with no data leaving your machine.
How to count words and characters the way products and platforms do — limits, diffs, Markdown pitfalls, and a practical editing workflow for developers who ship copy.
How to use Lorem Ipsum, fake user data, and Markdown fixtures effectively — when placeholder text helps layouts, when it hides product problems, and how to generate it locally.
When to use XPath vs CSS selectors, how to write stable queries, and a browser-side workflow for testing against real HTML without shipping brittle scrapers.
Find a developer tool