Skip to content

Repository files navigation

Typeable

Find the name that's easiest to type.

Naming a product, a company, a CLI command, a package, a domain? If people are going to type it thousands of times, it's worth knowing how it feels under the fingers. Typeable takes a list of candidates, "types" each one on the keyboard layout you pick, and ranks them by estimated comfort and speed. There's no typing test involved: the score comes from a documented finger-effort model.

Everything runs in your browser. No backend, no network calls.

Try it at typeable.dev

What it shows

  • Candidates ranked smoothest first — by estimated WPM, a length-independent measure of typing flow — with a toggle to rank by total typing time instead, where shorter names get their due.
  • A keyboard heatmap of the selected candidate, colored by per-key effort or key frequency.
  • The WPM (or time) spread as a bar chart, so the gaps between candidates are obvious.
  • Per-candidate stats: estimated time, same-finger pairs, hand alternation, finger travel, and left/right hand balance.
  • Seven layouts: QWERTY, QWERTZ, Dvorak, Colemak, Colemak Mod-DH, Workman and Norman. Switching layouts re-ranks the list and relabels the keyboard live.

How the score works

The model "types" each candidate and sums a per-keystroke cost in milliseconds. It lives in src/model/effort.ts and is tunable from a single MODEL constants object.

Each keystroke starts from a fixed base interval and pays for:

  • finger travel: distance from the finger's home key (farther is slower),
  • finger weakness: the pinky is slower than the index finger,
  • row: the home row is free, top and bottom rows cost a little, the number row costs the most,
  • shift: uppercase letters and shifted symbols add the cost of holding Shift.

Consecutive pairs of keys matter more than the keys themselves:

  • the same finger twice in a row is the main speed killer, and it gets worse with the distance the finger has to jump,
  • two keys on the same hand cost a little extra, plus a row-jump penalty, minus a discount for comfortable home-row rolls,
  • alternating hands is the fastest pattern and earns a bonus.

The total time converts to WPM with the usual five-characters-per-word convention. Values are calibrated so comfortable words land in a realistic touch-typing range and awkward, same-finger-heavy words drop well below it. Treat the numbers as relative: they compare candidates, they don't predict your actual typing speed.

Two rankings are available. Smoothest (the default) sorts by WPM; since WPM divides time by length, it measures per-keystroke flow and never punishes a name just for being long — a long name can out-rank a short one if it flows better. Fastest sorts by total estimated typing time, where every extra character counts.

A sanity script asserts the model keeps behaving sensibly (for example, island must rank far above minimum):

npx tsx src/model/effort.sanity.ts

Running

npm install
npm run dev      # dev server (Vite) on http://localhost:5173
npm run build    # type-check (tsc -b) + production build to dist/
npm run preview  # preview the production build
npm run lint     # eslint

Requires Node 20+. Stack: Vite, React 19, TypeScript, and plain CSS with design tokens. No UI framework.

Project layout

src/
  model/                 # pure typing-effort model (no React)
    types.ts             # shared type contract for the whole app
    keys.ts              # physical ANSI keyboard: positions, fingers, home keys, distances
    layouts.ts           # keyboard layout legends (QWERTY, Dvorak, Colemak, ...) + resolveChar()
    effort.ts            # the effort/speed model: analyzeTerm() / analyzeTerms()
    effort.sanity.ts     # runtime assertions that the rankings make sense
    index.ts             # barrel — the UI imports the model from here
  components/
    Keyboard.tsx/.css    # SVG keyboard heatmap (effort / frequency)
    ResultsTable.tsx     # ranked, selectable rows
    ComparisonChart.tsx  # horizontal WPM / time bars (follows the active sort)
    TermInput.tsx        # candidate chips input (Enter/comma/paste to add)
    LayoutPicker.tsx     # grouped layout dropdown
    Methodology.tsx      # collapsible "how the score works"
  App.tsx / App.css      # shell, state, two-column responsive layout
  index.css              # design tokens (dark theme) + base styles

The keyboard is modeled once as layout-independent physical keys; a layout is just a set of legends mapping each physical key to the character it types. That is why adding a layout is cheap.

Architecture notes, conventions, and extension guides (adding a layout, tuning the model) live in AGENTS.md.

Limitations

  • Assumes touch typing with standard finger assignments on a staggered ANSI keyboard.
  • Estimates steady-state typing; it doesn't model learning, autocomplete, or personal quirks.
  • Candidates are analyzed lowercased. Characters that don't exist on the chosen layout are flagged per candidate and skipped.

About

Find the name that's easiest to type — ranks candidate names by typing comfort and speed across seven keyboard layouts. Fully client-side.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages