npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

miftah

v1.1.5

Published

Arabic keyboard layout search filter — maps Arabic keyboard input back to Latin for correct search matching

Readme

miftah

CI npm npm downloads bundle size bundle size license

Arabic-speaking users often type on a QWERTY keyboard with their OS input switched to Arabic. Their muscle memory produces Arabic characters — عربي instead of uvfd — because the mapping is by key position, not by sound.

miftah handles both: it maps Arabic keyboard layout characters back to the Latin keys that produced them, and also matches by phonetic transliteration — as a drop-in filter function for any search input.

Install

bun add miftah
# or
npm install miftah

Usage

import { keyboardUnmap, keyboardRemap, keyboardFilter } from 'miftah'

// Unmap — Arabic keyboard input → Latin
keyboardUnmap('عربي')   // → 'uvfd'
keyboardUnmap('hello')  // → 'hello'  (Latin passes through)

// Remap — Latin keys → Arabic chars (reverse direction)
keyboardRemap('flag')   // → 'بمشل'  (what those keys produce on Arabic layout)
keyboardRemap('عربي')   // → 'عربي'  (Arabic passes through)

// Plain JS filter
items.filter(item => keyboardFilter(item.name, searchQuery))

// Vuetify
// <VAutocomplete :custom-filter="(v, s) => keyboardFilter(v, s)" />

// With options
keyboardFilter('arabic', 'عربي')                                  // → true  (keyboard unmap match)
keyboardFilter('بمشل', 'flag')                                    // → true  (keyboard remap match)
keyboardFilter('thursday', 'ث')                                   // → true  (phonetic: th)
keyboardFilter('2024', '٢٠٢٤')                                    // → true  (numeral normalization)
keyboardFilter('Hello', 'HELLO', { caseSensitive: true })         // → false

API

keyboardUnmap(input, layout?)

Converts Arabic keyboard layout characters back to the Latin keys that produced them. Non-Arabic characters pass through unchanged.

| Parameter | Type | Default | |---|---|---| | input | string | — | | layout | 'windows-arabic' \| 'mac-arabic' | 'windows-arabic' |

keyboardRemap(input, layout?)

Converts Latin keys to the Arabic characters they produce on the given keyboard layout. The reverse of keyboardUnmap. Non-Latin characters and unmapped keys pass through unchanged.

| Parameter | Type | Default | |---|---|---| | input | string | — | | layout | 'windows-arabic' \| 'mac-arabic' | 'windows-arabic' |

keyboardFilter(value, search, options?)

Returns true if value matches search via any of these strategies, in order:

  1. Empty search — always true
  2. Direct match (case and numeral normalized)
  3. Keyboard layout unmap — convert Arabic chars in search to Latin keys, check against value
  4. Phonetic match — transliterate Arabic chars in search to Latin, check against value
  5. Keyboard layout remap — convert Latin keys in search to Arabic chars, check against value
  6. No match — false

| Option | Type | Default | |---|---|---| | layout | 'windows-arabic' \| 'mac-arabic' | 'windows-arabic' | | phonetic | boolean | true | | caseSensitive | boolean | false |

React Native

Supported. On mobile, keyboard layout mismatch is rare — users explicitly switch keyboards. The phonetic path is the dominant match strategy on RN.

Keyboard layout notes

The default is Windows Arabic (101) — the most common layout in Gulf/MENA regions. The map is verified against the Windows Arabic (101) .klc source from Microsoft Keyboard Layout Creator.

Mac Arabic is supported as a named variant via layout: 'mac-arabic'.

License

MIT