Docker Image Name Converter
kebab-case writes hello-world-example. Docker repository names must be lowercase — the daemon rejects MyApp:latest outright with "repository name must be lowercase". Separators are limited to periods, single underscores, double underscores and one or more hyphens, which in practice means a lowercase hyphenated name is the only form that is always safe across registries.
Conversions
| Input | kebab-case |
|---|---|
hello world example | hello-world-example |
XMLHttpRequest | xml-http-request |
user_first_name | user-first-name |
Total Order Count | total-order-count |
XMLHttpRequest becomes xml-http-request. That is the correct behaviour for a URL or a CSS class, where case sensitivity varies by context and mixed case causes more problems than it solves.The Same Text in Other Cases
| Case | Result |
|---|---|
| camelCase | helloWorldExample |
| PascalCase | HelloWorldExample |
| snake_case | hello_world_example |
| SCREAMING_SNAKE_CASE | HELLO_WORLD_EXAMPLE |
| Train-Case | Hello-World-Example |
| dot.case | hello.world.example |
The Daemon Rejects Uppercase Outright
docker build -t MyApp . fails with "repository name must be lowercase" — one of the few naming rules enforced by an error rather than by convention. The separator rules are narrower than most registries suggest: periods, single underscores, double underscores, or runs of hyphens.
The tag is separate and *is* case-sensitive, so myapp:V2 and myapp:v2 are different images. Keeping tags lowercase too avoids a class of deployment confusion that is very hard to spot in a log.
Converting in Code
``javascript
const kebab = (s) => words(s).map((w) => w.toLowerCase()).join('-');
`
A hyphen is a subtraction operator in most languages, so kebab-case identifiers cannot be used unquoted in code. That is precisely why it belongs in URLs, CSS and filenames and not in variable names.
Converting at the API Boundary
The recurring friction is that JavaScript uses camelCase and Python, Ruby, Go and SQL use
snake_case. The fix is to convert in exactly one place — the client that talks to the API —
rather than letting both conventions into the same codebase.
`javascript
const toCamel = (s) => s.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
const toSnake = (s) => s.replace(/[A-Z]/g, (c) => '_' + c.toLowerCase());
// Recursively, for a whole payload
const convertKeys = (value, fn) =>
Array.isArray(value)
? value.map((v) => convertKeys(v, fn))
: value && typeof value === 'object'
? Object.fromEntries(Object.entries(value).map(([k, v]) => [fn(k), convertKeys(v, fn)]))
: value;
`
Two things to watch: keys that are user data rather than field names must not be
converted, and the round trip is not always lossless — userID → user_id → userId
changes the original.
Where Each Convention Is Mandatory
Not stylistic — these will break if you deviate:
| Context | Requirement |
|---|---|
| Environment variables | Uppercase with underscores; POSIX reserves lowercase |
| Custom HTML elements | Must contain a hyphen |
| Python modules | Cannot contain hyphens; the import statement will not parse |
| SQL identifiers | Folded to one case unless quoted, so camelCase does not survive |
| React components | Must start uppercase, or JSX treats it as an HTML tag |
Renaming Safely
A find-and-replace across a codebase will hit strings, comments and unrelated identifiers.
Use your language server's rename symbol instead — it understands scope. For a bulk rename
across files, restrict the pattern with word boundaries and review the diff before
committing:
`bash
grep -rn '\buserId\b' src/ # look first
``