JavaScript and TypeScript voice dictation

JavaScript and TypeScript dictation that keeps camelCase intact

In a TypeScript codebase nearly every name has a shape a speech model cannot hear: handleSubmit, CheckoutFormProps, MAX_UPLOAD_SIZE, order-history.tsx. Say them and you get loose words, which a coding agent then has to hunt for. This guide covers the casing rules JavaScript and TypeScript projects follow, what IraVoice types for each kind of name, why React’s own hooks need one extra step, how kebab-case files behave, and which other voice tools are worth a look.

Source-reviewed

1. Where “use effect” and “Jason” come from

A dictation model turns sound into ordinary words. useEffect becomes “use effect”, handleSubmit becomes “handle submit”, a capital letter may appear at the start of the sentence, and JSON can be written as the name Jason. Kebab-case file names lose their dashes, and extensions become words: “order history dot tsx”.

In a pull request description, or a prompt for Claude Code, Codex or Cursor, that costs time. The agent searches for something that does not exist under the name you said, and a reviewer reading “the use local storage hook” has to work out which file you meant. Spelling capitals aloud (“handle capital submit”) is slower than typing. What helps is a dictation tool that already knows the names in the project in front of you.

2. The casing rules a TypeScript codebase follows

Google’s TypeScript style guide is a representative rulebook. It uses UpperCamelCase for classes, interfaces, types, enums, decorators, type parameters and component functions in TSX; lowerCamelCase for variables, parameters, functions, methods, properties and module aliases; and CONSTANT_CASE for global constant values, including enum values. It treats abbreviations as whole words, loadHttpUrl rather than loadHTTPURL, and lists customerID as incorrect camel case.

React adds two rules of its own: component names must start with a capital letter, like StatusBar and SaveButton, and Hook names must start with use followed by a capital letter, like the built-in useState or a custom useOnlineStatus. File naming varies by team. Angular’s style guide separates words in file names with hyphens, so a UserProfile component lives in user-profile.ts and its unit test in user-profile.spec.ts, while many React projects name the file after the component. Around them sit package.json, where npm requires new package names to have no uppercase letters, and tsconfig.json, whose presence marks the root of a TypeScript project.

  • getUserById is said “get user by ID”; this style treats ID as an ordinary word.
  • CheckoutFormProps is said “checkout form props”.
  • MAX_UPLOAD_SIZE is said “max upload size”.
  • order-history.tsx is said “order history tsx” or “order dash history dot tsx”.

3. Spoken to typed in a React and TypeScript repo

This is what IraVoice’s matching rules produce for a small storefront project with a hooks folder, a CheckoutForm.tsx component, an api/client.ts module, a vite.config.ts and a kebab-case order-history.tsx, dictated into a recognized app on a Mac or Windows PC:

  • “the use debounce hook resets on every keystroke” → the useDebounce hook resets on every keystroke
  • “handle submit runs twice in checkout form dot tsx” → handleSubmit runs twice in CheckoutForm.tsx
  • “get user by ID returns undefined” → getUserById returns undefined
  • “checkout form props” → CheckoutFormProps; “cart item” → CartItem
  • “max upload size” → MAX_UPLOAD_SIZE
  • “new HTTP client” → newHttpClient, following the project’s whole-word acronym
  • “ts config dot json” → tsconfig.json; “vite config ts” → vite.config.ts
  • “package dot json” → package.json

4. useEffect, imports, and names that live only in node_modules

The project’s spelling always wins over the speech model’s: “Use local storage throws in Safari” becomes useLocalStorage throws in Safari despite the capital U. A comma ends a name, so “the user, account page” stays as said. Two everyday words never become an identifier, so “save button” stays prose even in a project with a SaveButton component, while names with a more distinctive word, such as useOnlineStatus or CheckoutFormProps, come through.

IraVoice’s list comes from your repository, and it skips dependency folders such as node_modules. Your own hooks, components and utilities are spelled from the first dictation, and since version 1.2.1 so are the names your files import: a component with import { useEffect } from "react" puts useEffect in the list, so “wrap it in a use effect hook” comes out as useEffect. Named, default and namespace imports count, and so do names destructured from require(). A name that lives only inside a dependency, which no file of yours imports, is still unknown to it.

Teach those once. Dictate, press Quick Fix (⌃⌥⇧F on a Mac, Ctrl+Alt+Shift+F on Windows and Linux), correct the misheard name, and press Enter. The corrected sentence is copied for you to paste back, and IraVoice types the name right from then on, in every app. The same works for “Jason” to JSON or “next JS” to Next.js. On a Mac it also learns from corrections you make by hand in most apps. Each lesson is a word pair you can review or forget under Advanced → Learn from my fixes.

5. Kebab-case files, monorepos and other edge cases

When a file and the component inside it share their words, as order-history.tsx and OrderHistory do, one phrase can only produce one name, and in that layout IraVoice types the file name: “the order history component” arrives as the order-history component. An agent will still find the component through its file. For the file itself, say every separator or none: “order history tsx” and “order dash history dot tsx” both give order-history.tsx, while “order history dot tsx” mixes the two and leaves “dot tsx” as words. The same goes for an Angular test file: “user profile spec ts” gives user-profile.spec.ts.

Two-word names made of everyday words are the other gap. In a project with an ApiError class, “API error” stays two words, because both are ordinary words. A Replacement for a more specific phrase, such as “API error class”, types ApiError class every time. Replacements are also the place for fixed text, such as a phrase that types your repository URL or the sign-off you add to review comments.

In a large monorepo, IraVoice indexes a bounded number of files and names, so a declaration deep inside one package may be missing even when its file name is present. Saying the file name is the more dependable way to point an agent at it.

6. VS Code, WebStorm, Cursor and the alternatives

On a Mac, IraVoice spells names in VS Code and VS Code Insiders, Cursor, Windsurf, Zed, WebStorm and the other JetBrains IDEs, Sublime Text, Terminal, iTerm2, Ghostty, Warp and other terminals, and the Claude and Codex desktop apps. On Windows it includes VS Code, Cursor, Windsurf, Zed, WebStorm, Windows Terminal, PowerShell and cmd. Browser-based editors are not on the list, so dictation there arrives as plain text. On Linux, IraVoice is a beta that dictates without code names.

It is not a way to write JSX by voice. It does not type braces, arrow functions, angle brackets, semicolons or indentation; describe the change in words and let the agent or the editor’s completion produce the code.

If VS Code is your only editor, try its built-in dictation first. On the desktop it downloads a speech model and recognizes speech locally, starts with ⌘I or Ctrl+I in the chat input, and, while its default LLM cleanup setting is on, sends the finished transcript to a Copilot model that you can steer with a .github/dictation.md file listing preferred terminology. Claude Code’s /voice is tuned for coding terms such as JSON and OAuth and adds your project and branch names as hints, with audio transcribed by Anthropic. Talon builds identifiers with formatters like camel, hammer and kebab. Serenade lists JavaScript and TypeScript support, but its open-source repository has not changed since July 2022.

IraVoice works the same in every one of those apps: Hold Right Command on a Mac or Right Ctrl on Windows, speak, and release, with recognition on the computer by NVIDIA Parakeet. It needs no subscription: $79 once for one computer, $109 for two, or $149 for three, with a 3-day free trial that starts at your first dictation.

Decision guide

Which voice tool fits your JavaScript and TypeScript work?

Match the tool to where you write and which names you need spelled.

If you needChooseWhy
Prompts naming your hooks, components and files in Cursor, VS Code or a terminal agentIraVoice on a Mac or Windows PCIt types the project’s spelling of declared and imported names and file names; nothing leaves the computer.
A library name that none of your files importQuick Fix oncenode_modules is not read; a learned fix covers the name in every app afterwards.
Copilot Chat in VS Code and nothing elseVS Code built-in dictationLocal recognition on the desktop, and dictation instructions can list preferred spellings while LLM cleanup is on.
Writing JSX and TypeScript syntax by voiceTalonFormatters, symbol commands and snippets are designed for entering code.
Claude Code only, signed in with Claude.aiClaude Code /voiceBuilt in and tuned for coding vocabulary; audio is processed by Anthropic, not on your computer.

Primary sources

Use the current documentation.

This guide was reviewed October 3, 2026. Product versions, settings, policies, and availability can change.

  1. Google TypeScript Style Guide ↗

    Identifier casing by category, CONSTANT_CASE for global constants, and abbreviations treated as whole words (loadHttpUrl, not customerID).

  2. React: Reusing Logic with Custom Hooks ↗

    Component names start with a capital letter; Hook names start with use followed by a capital letter.

  3. Angular: Style guide ↗

    Hyphen-separated file names (user-profile.ts) and .spec.ts test files.

  4. npm Docs: package.json ↗

    New package names must not have uppercase letters.

  5. TypeScript Handbook: What is a tsconfig.json ↗

    A tsconfig.json marks the root of a TypeScript project.

  6. Visual Studio Code: Voice support ↗

    On-device dictation model, chat shortcut, LLM cleanup default and dictation instructions files.

  7. Claude Code Docs: Voice dictation ↗

    Coding-vocabulary tuning, project and branch hints, cloud transcription and Claude.ai requirement.

  8. Talon Community Wiki: Formatters ↗

    camel, hammer and kebab identifier formatters.

Questions

What readers usually ask next.

Will IraVoice type useEffect when I say “use effect”?

Yes, from version 1.2.1, as soon as a file in your project imports it, as every React component that calls useEffect does. A name that exists only in node_modules and that no file imports is taught once with Quick Fix and typed right from then on.

Can I dictate TypeScript or JSX code with IraVoice?

No. It types your words and spells the project’s names inside them, but never braces, arrow functions, tags or semicolons. Use it for prompts, commit messages, review comments and docs.

Why does “order history” come out as order-history?

Your project has an order-history.tsx file, and its name and the OrderHistory component share the same letters. IraVoice can type only one name for one phrase, and here it is the file. Agents find the component from its file.

Does IraVoice read node_modules or my .env files?

No. It skips dependency folders and files that may hold secrets, keeps only names rather than source text, and nothing leaves the computer.

Does it work in WebStorm on Windows?

Yes. WebStorm is on IraVoice’s Windows list, as are VS Code, Cursor, Windsurf, Zed and Windows Terminal. On a Mac it works in all JetBrains IDEs.

Mac, Windows, and Linux

Try private, on-device dictation for yourself.

Hold one key, speak, and the words are typed where your cursor is. The 3-day free trial starts with your first dictation.