Naming Conventions

Typeweaver names are not just cosmetic. Resource names, operationId values, and response names all shape the generated clients, validators, request types, and response types you work with later.

Choose them like public API surface for your own codebase.

The short recommendation

Upstream guidance prefers:

  • singular camelCase resource names such as todo or authSession
  • camelCase operationId values such as getTodo or createTodo
  • clear PascalCase response names such as GetTodoSuccess or TodoNotFoundError

That is the official preference.

These docs still use PascalCase examples for many operations because generated class names such as GetTodoRequestCommand, TodoClient, and GetTodoResponseValidator are also PascalCase, and the current examples are easier to scan that way.

The important compatibility point is simple: camelCase is preferred, PascalCase is fully supported, and snake_case / kebab-case are rejected.

operationId naming

Preferred

Official guidance prefers camelCase:

operationId: "getTodo"
operationId: "createTodo"

Also supported

PascalCase is fully supported and appears throughout current examples and tests:

operationId: "GetTodo"
operationId: "CreateTodo"

These docs use PascalCase in many examples for consistency with generated class names and surrounding documentation.

Not supported

These formats are not supported:

operationId: "get_todo"
operationId: "get-todo"

Resource naming

Preferred

Prefer a singular camelCase resource key in defineSpec(...):

resources: {
  todo: {
    operations: [GetTodoDefinition],
  },
}

Good examples:

  • todo
  • user
  • authSession

Also supported

The current project also supports:

  • PascalCase resource names such as Todo
  • plural resource names such as todos

Those work, but singular camelCase tends to produce the cleanest long-term output.

Not supported

These are not supported for resource names:

  • todo_item
  • todo-item

Response naming

Response names should be explicit and descriptive because they become the response.type discriminator and generated type/factory names.

Examples:

  • GetTodoSuccess
  • ValidationError
  • TodoNotFoundError

Global uniqueness rule

Response names must be globally unique across the whole spec.

This is valid:

defineResponse({ name: "ValidationError", ... })
defineResponse({ name: "TodoNotFoundError", ... })

This is not:

// reused for a different response shape somewhere else
defineResponse({ name: "ValidationError", ... })

If two different responses share the same name, generation fails.

How names show up in generated output

Spec nameWhere it appears
resource namegenerated folders and resource-level classes such as TodoClient, TodoRouter, TodoHono, TodoHttpApiRoutes
operationIdrequest/response validators, request commands, handler method names, operation files
response nameresponse.type, generated response types, and create<ResponseName>Response(...) factory names

That is why naming cleanup later can create noisy diffs across generated code.

Choosing between camelCase and PascalCase for operationId

Use this rule and move on:

  • starting a new codebase today: choose camelCase
  • matching an existing Typeweaver codebase that already uses PascalCase heavily: staying consistent is fine

Consistency inside one spec matters more than chasing style purity across old and new files.

Practical pitfalls

Avoid these common mistakes:

  • changing names casually after clients or handlers already depend on them
  • mixing getTodo, CreateTodo, and list_todos styles in one spec
  • using vague response names like Success or Error
  • reusing the same response name for different shapes

Was this page helpful?