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

unicode-picker

v0.1.1

Published

A framework-agnostic, tree-shakable Unicode character picker component in vanilla TypeScript

Readme

unicode-picker

npm Tests unicode-picker GitHub repo Coverage Status LICENSE MIT

Vanilla TypeScript framework-agnostic Unicode character picker component.

  • Data-agnostic core — bring your own characters (a few hardcoded glyphs, a whole Unicode block, or the full set). The core bundle ships no character data.
  • Tree-shakable datasetimport { greek, math } from 'unicode-picker/data' pulls only those blocks.
  • Popover positioning via the native Popover API, anchored to any element.
  • Insert = event only — a unicode-picker:insert event and an onInsert callback; the library never touches your editor.
  • Light / dark / auto theme, Shadow DOM style isolation, keyboard navigation, search.
  • Ships as an ESM module and a browser IIFE (<script>, window.Picker).

Built on Unicode 17.0.0 data (via @unicode/unicode-17.0.0, used only at build time).

Screenshots

Unicode Picker Dark Mode Unicode Picker Light Mode

Install

npm install unicode-picker

Quick start

import Picker from 'unicode-picker';
import { emoji, arrows, mathematicalOperators } from 'unicode-picker/data';

const picker = Picker({
  width: 380, // px
  height: 480, // px
  include: [emoji, arrows, mathematicalOperators],
});

picker.append(document.body);

const button = document.querySelector('#open')!;
button.addEventListener('click', () => picker.toggle({ anchor: button }));

picker.on('insert', ({ char }) => {
  // do whatever you want with the character
  document.querySelector('textarea')!.value += char;
});

picker.on('select', (data) => {
  console.log(data);
});

Omit include to load the entire Unicode set lazily from unicode-picker/data (virtualized, so it stays fast):

const picker = Picker(); // everything, loaded on first show()

Options

| Option | Type | Default | Description | | ---------- | -------------------------------- | -------- | ------------------------------------------------------------ | | width | number | 380 | Width in pixels. | | height | number | 480 | Height in pixels. | | include | BlockSource | full set | Characters to show (see Data). Omit for everything. | | theme | 'light' \| 'dark' \| 'auto' | 'auto' | Colour theme (auto follows prefers-color-scheme). | | onInsert | (detail: InsertDetail) => void | — | Convenience callback, fired with the insert event. |

Instance API

interface PickerInstance {
  append(parent: HTMLElement): PickerInstance;
  show(opts?: ShowOptions): PickerInstance; // ShowOptions: { anchor?, placement? }
  hide(): PickerInstance;
  toggle(opts?: ShowOptions): PickerInstance;
  on(event, cb): () => void; // returns an unsubscribe function
  setTheme(theme): PickerInstance;
  search(query: string): PickerInstance;
  destroy(): void;
  readonly element: HTMLElement;
}

show({ anchor, placement }) positions the popover against anchor (placement: 'top' | 'bottom' | 'left' | 'right' | 'auto', default 'auto').

Events

Subscribe with picker.on(name, cb) (returns an unsubscribe function). insert is also dispatched as a bubbling, composed DOM CustomEvent named unicode-picker:insert on picker.element.

| Event | Detail | | -------- | --------------------------------------- | | insert | { char, codePoint, name, block, hex } | | select | same shape as insert | | copy | { value, char, codePoint } | | show | void | | hide | void |

Data

The include option is a BlockSource — the core renders whatever you give it:

interface PickerChar {
  char: string; // the symbol (may be a surrogate pair)
  name?: string; // enables the inspector title + name search
  codePoint?: number; // derived from `char` when omitted
}

interface PickerBlock {
  name: string; // chip + section header label
  characters: string | Array<string | PickerChar>; // a string is split by code point
  range?: [number, number]; // derived from the characters otherwise
}

type BlockSource = PickerBlock[] | (() => PickerBlock[] | Promise<PickerBlock[]>);

Examples:

// Hardcoded — tiny bundle, no dataset dependency
Picker({ include: [{ name: 'Arrows', characters: '←↑→↓' }] });

// Named blocks from the bundled dataset (tree-shaken)
import { emoji, greekAndCoptic } from 'unicode-picker/data';
Picker({ include: [emoji, greekAndCoptic] });

// Lazy / async source
Picker({ include: async () => (await fetch('/my-chars.json')).json() });

// Straight from @unicode via the adapter (pairs symbols with names)
import { fromUnicodePackage } from 'unicode-picker/adapters';
Picker({ include: () => fromUnicodePackage(() => import('@unicode/unicode-17.0.0/Block')) });

unicode-picker/data

Named exports, one PickerBlock per Unicode block (camelCase of the official name), plus a curated emoji set and heavy all / blocks arrays:

import { basicLatin, greekAndCoptic, mathematicalOperators, emoji, all } from 'unicode-picker/data';

Importing individual blocks is tree-shakable — only the blocks you name end up in your bundle. all / blocks include everything and intentionally opt out of tree-shaking.

The curated emoji export names every emoji — including multi-code-point sequences such as flags (🇬🇧 → “flag: United Kingdom”) and ZWJ families — using the CLDR annotations from emojibase-data (build-time only).

IIFE note: tree-shaking is an ESM/bundler feature. For plain <script> usage, the data script (unicode-picker-data.global.js) exposes the whole dataset on window.UnicodePickerData; it cannot be tree-shaken.

See the full list of blocks below.

Usage in the browser (<script>)

<script src="https://unpkg.com/unicode-picker"></script>
<!-- optional: the full dataset on window.UnicodePickerData -->
<script src="https://unpkg.com/unicode-picker/dist/unicode-picker-data.global.js"></script>
<script>
  const { emoji, arrows } = window.UnicodePickerData;
  const picker = Picker({ include: [emoji, arrows] });
  picker.append(document.body);
  document.querySelector('#open').onclick = (e) => picker.toggle({ anchor: e.currentTarget });
  picker.on('insert', ({ char }) => console.log('picked', char));
</script>

Usage with React

import { useEffect, useRef, useState } from 'react';
import Picker, { type PickerInstance } from 'unicode-picker';
import { emoji, arrows } from 'unicode-picker/data';

export function CharField() {
  const btn = useRef<HTMLButtonElement>(null);
  const picker = useRef<PickerInstance | null>(null);
  const [value, setValue] = useState('');

  useEffect(() => {
    const p = Picker({ include: [emoji, arrows] });
    p.append(document.body);
    p.on('insert', ({ char }) => setValue((v) => v + char));
    picker.current = p;
    return () => p.destroy();
  }, []);

  return (
    <>
      <button ref={btn} onClick={() => picker.current?.toggle({ anchor: btn.current! })}>
        Pick a character ❖
      </button>
      <textarea value={value} onChange={(e) => setValue(e.target.value)} />
    </>
  );
}

Usage with Vue

<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref } from 'vue';
import Picker, { type PickerInstance } from 'unicode-picker';
import { emoji, arrows } from 'unicode-picker/data';

const btn = ref<HTMLButtonElement>();
const value = ref('');
let picker: PickerInstance;

onMounted(() => {
  picker = Picker({ include: [emoji, arrows] });
  picker.append(document.body);
  picker.on('insert', ({ char }) => (value.value += char));
});
onBeforeUnmount(() => picker.destroy());
</script>

<template>
  <button ref="btn" @click="picker.toggle({ anchor: btn })">Pick a character ❖</button>
  <textarea v-model="value" />
</template>

Unicode blocks

Each block below is a named export of unicode-picker/data. Click a reference to see every character in that block.

| Import | Unicode block | Chars | Reference | | --------------------------------------------- | ------------------------------------------------ | ----- | ------------------------------------------------------------------------------------------------------------------------------ | | emoji | Emoji | 1940 | chars | | adlam | Adlam | 88 | chars | | aegeanNumbers | Aegean Numbers | 57 | chars | | ahom | Ahom | 65 | chars | | alchemicalSymbols | Alchemical Symbols | 128 | chars | | alphabeticPresentationForms | Alphabetic Presentation Forms | 58 | chars | | anatolianHieroglyphs | Anatolian Hieroglyphs | 583 | chars | | ancientGreekMusicalNotation | Ancient Greek Musical Notation | 70 | chars | | ancientGreekNumbers | Ancient Greek Numbers | 79 | chars | | ancientSymbols | Ancient Symbols | 14 | chars | | arabic | Arabic | 248 | chars | | arabicExtendedA | Arabic Extended a | 95 | chars | | arabicExtendedB | Arabic Extended B | 41 | chars | | arabicExtendedC | Arabic Extended C | 21 | chars | | arabicMathematicalAlphabeticSymbols | Arabic Mathematical Alphabetic Symbols | 143 | chars | | arabicPresentationFormsA | Arabic Presentation Forms a | 656 | chars | | arabicPresentationFormsB | Arabic Presentation Forms B | 140 | chars | | arabicSupplement | Arabic Supplement | 48 | chars | | armenian | Armenian | 91 | chars | | arrows | Arrows | 112 | chars | | avestan | Avestan | 61 | chars | | balinese | Balinese | 127 | chars | | bamum | Bamum | 88 | chars | | bamumSupplement | Bamum Supplement | 569 | chars | | basicLatin | Basic Latin | 95 | chars | | bassaVah | Bassa Vah | 36 | chars | | batak | Batak | 56 | chars | | bengali | Bengali | 96 | chars | | beriaErfe | Beria Erfe | 50 | chars | | bhaiksuki | Bhaiksuki | 97 | chars | | blockElements | Block Elements | 32 | chars | | bopomofo | Bopomofo | 43 | chars | | bopomofoExtended | Bopomofo Extended | 32 | chars | | boxDrawing | Box Drawing | 128 | chars | | brahmi | Brahmi | 115 | chars | | braillePatterns | Braille Patterns | 256 | chars | | buginese | Buginese | 30 | chars | | buhid | Buhid | 20 | chars | | byzantineMusicalSymbols | Byzantine Musical Symbols | 246 | chars | | cjkCompatibility | CJK Compatibility | 256 | chars | | cjkCompatibilityForms | CJK Compatibility Forms | 32 | chars | | cjkCompatibilityIdeographs | CJK Compatibility Ideographs | 472 | chars | | cjkCompatibilityIdeographsSupplement | CJK Compatibility Ideographs Supplement | 542 | chars | | cjkRadicalsSupplement | CJK Radicals Supplement | 115 | chars | | cjkStrokes | CJK Strokes | 39 | chars | | cjkSymbolsAndPunctuation | CJK Symbols and Punctuation | 64 | chars | | cjkUnifiedIdeographs | CJK Unified Ideographs | 20992 | chars | | cjkUnifiedIdeographsExtensionA | CJK Unified Ideographs Extension a | 6592 | chars | | cjkUnifiedIdeographsExtensionB | CJK Unified Ideographs Extension B | 42720 | chars | | cjkUnifiedIdeographsExtensionC | CJK Unified Ideographs Extension C | 4160 | chars | | cjkUnifiedIdeographsExtensionD | CJK Unified Ideographs Extension D | 222 | chars | | cjkUnifiedIdeographsExtensionE | CJK Unified Ideographs Extension E | 5774 | chars | | cjkUnifiedIdeographsExtensionF | CJK Unified Ideographs Extension F | 7473 | chars | | cjkUnifiedIdeographsExtensionG | CJK Unified Ideographs Extension G | 4939 | chars | | cjkUnifiedIdeographsExtensionH | CJK Unified Ideographs Extension H | 4192 | chars | | cjkUnifiedIdeographsExtensionI | CJK Unified Ideographs Extension I | 622 | chars | | cjkUnifiedIdeographsExtensionJ | CJK Unified Ideographs Extension J | 4298 | chars | | carian | Carian | 49 | chars | | caucasianAlbanian | Caucasian Albanian | 53 | chars | | chakma | Chakma | 71 | chars | | cham | Cham | 83 | chars | | cherokee | Cherokee | 92 | chars | | cherokeeSupplement | Cherokee Supplement | 80 | chars | | chessSymbols | Chess Symbols | 102 | chars | | chorasmian | Chorasmian | 28 | chars | | combiningDiacriticalMarks | Combining Diacritical Marks | 112 | chars | | combiningDiacriticalMarksExtended | Combining Diacritical Marks Extended | 58 | chars | | combiningDiacriticalMarksForSymbols | Combining Diacritical Marks for Symbols | 33 | chars | | combiningDiacriticalMarksSupplement | Combining Diacritical Marks Supplement | 64 | chars | | combiningHalfMarks | Combining Half Marks | 16 | chars | | commonIndicNumberForms | Common Indic Number Forms | 10 | chars | | controlPictures | Control Pictures | 42 | chars | | coptic | Coptic | 123 | chars | | copticEpactNumbers | Coptic Epact Numbers | 28 | chars | | countingRodNumerals | Counting Rod Numerals | 25 | chars | | cuneiform | Cuneiform | 922 | chars | | cuneiformNumbersAndPunctuation | Cuneiform Numbers and Punctuation | 116 | chars | | currencySymbols | Currency Symbols | 34 | chars | | cypriotSyllabary | Cypriot Syllabary | 55 | chars | | cyproMinoan | Cypro Minoan | 99 | chars | | cyrillic | Cyrillic | 256 | chars | | cyrillicExtendedA | Cyrillic Extended a | 32 | chars | | cyrillicExtendedB | Cyrillic Extended B | 96 | chars | | cyrillicExtendedC | Cyrillic Extended C | 11 | chars | | cyrillicExtendedD | Cyrillic Extended D | 63 | chars | | cyrillicSupplement | Cyrillic Supplement | 48 | chars | | deseret | Deseret | 80 | chars | | devanagari | Devanagari | 128 | chars | | devanagariExtended | Devanagari Extended | 32 | chars | | devanagariExtendedA | Devanagari Extended a | 10 | chars | | dingbats | Dingbats | 192 | chars | | divesAkuru | Dives Akuru | 72 | chars | | dogra | Dogra | 60 | chars | | dominoTiles | Domino Tiles | 100 | chars | | duployan | Duployan | 143 | chars | | earlyDynasticCuneiform | Early Dynastic Cuneiform | 196 | chars | | egyptianHieroglyphFormatControls | Egyptian Hieroglyph Format Controls | 22 | chars | | egyptianHieroglyphs | Egyptian Hieroglyphs | 1072 | chars | | egyptianHieroglyphsExtendedA | Egyptian Hieroglyphs Extended a | 3995 | chars | | elbasan | Elbasan | 40 | chars | | elymaic | Elymaic | 23 | chars | | emoticons | Emoticons | 80 | chars | | enclosedAlphanumericSupplement | Enclosed Alphanumeric Supplement | 200 | chars | | enclosedAlphanumerics | Enclosed Alphanumerics | 160 | chars | | enclosedCjkLettersAndMonths | Enclosed CJK Letters and Months | 255 | chars | | enclosedIdeographicSupplement | Enclosed Ideographic Supplement | 64 | chars | | ethiopic | Ethiopic | 358 | chars | | ethiopicExtended | Ethiopic Extended | 79 | chars | | ethiopicExtendedA | Ethiopic Extended a | 32 | chars | | ethiopicExtendedB | Ethiopic Extended B | 28 | chars | | ethiopicSupplement | Ethiopic Supplement | 26 | chars | | garay | Garay | 69 | chars | | generalPunctuation | General Punctuation | 86 | chars | | geometricShapes | Geometric Shapes | 96 | chars | | geometricShapesExtended | Geometric Shapes Extended | 103 | chars | | georgian | Georgian | 88 | chars | | georgianExtended | Georgian Extended | 46 | chars | | georgianSupplement | Georgian Supplement | 40 | chars | | glagolitic | Glagolitic | 96 | chars | | glagoliticSupplement | Glagolitic Supplement | 38 | chars | | gothic | Gothic | 27 | chars | | grantha | Grantha | 86 | chars | | greekAndCoptic | Greek and Coptic | 135 | chars | | greekExtended | Greek Extended | 233 | chars | | gujarati | Gujarati | 91 | chars | | gunjalaGondi | Gunjala Gondi | 63 | chars | | gurmukhi | Gurmukhi | 80 | chars | | gurungKhema | Gurung Khema | 58 | chars | | halfwidthAndFullwidthForms | Halfwidth and Fullwidth Forms | 225 | chars | | hangulCompatibilityJamo | Hangul Compatibility Jamo | 94 | chars | | hangulJamo | Hangul Jamo | 256 | chars | | hangulJamoExtendedA | Hangul Jamo Extended a | 29 | chars | | hangulJamoExtendedB | Hangul Jamo Extended B | 72 | chars | | hangulSyllables | Hangul Syllables | 11172 | chars | | hanifiRohingya | Hanifi Rohingya | 50 | chars | | hanunoo | Hanunoo | 23 | chars | | hatran | Hatran | 26 | chars | | hebrew | Hebrew | 88 | chars | | hiragana | Hiragana | 93 | chars | | ipaExtensions | IPA Extensions | 96 | chars | | ideographicDescriptionCharacters | Ideographic Description Characters | 16 | chars | | ideographicSymbolsAndPunctuation | Ideographic Symbols and Punctuation | 12 | chars | | imperialAramaic | Imperial Aramaic | 31 | chars | | indicSiyaqNumbers | Indic Siyaq Numbers | 68 | chars | | inscriptionalPahlavi | Inscriptional Pahlavi | 27 | chars | | inscriptionalParthian | Inscriptional Parthian | 30 | chars | | javanese | Javanese | 91 | chars | | kaithi | Kaithi | 66 | chars | | kaktovikNumerals | Kaktovik Numerals | 20 | chars | | kanaExtendedA | Kana Extended a | 35 | chars | | kanaExtendedB | Kana Extended B | 13 | chars | | kanaSupplement | Kana Supplement | 256 | chars | | kanbun | Kanbun | 16 | chars | | kangxiRadicals | Kangxi Radicals | 214 | chars | | kannada | Kannada | 92 | chars | | katakana | Katakana | 96 | chars | | katakanaPhoneticExtensions | Katakana Phonetic Extensions | 16 | chars | | kawi | Kawi | 87 | chars | | kayahLi | Kayah Li | 48 | chars | | kharoshthi | Kharoshthi | 68 | chars | | khitanSmallScript | Khitan Small Script | 471 | chars | | khmer | Khmer | 114 | chars | | khmerSymbols | Khmer Symbols | 32 | chars | | khojki | Khojki | 65 | chars | | khudawadi | Khudawadi | 69 | chars | | kiratRai | Kirat Rai | 58 | chars | | lao | Lao | 83 | chars | | latin1Supplement | Latin 1 Supplement | 95 | chars | | latinExtendedA | Latin Extended a | 128 | chars | | latinExtendedAdditional | Latin Extended Additional | 256 | chars | | latinExtendedB | Latin Extended B | 208 | chars | | latinExtendedC | Latin Extended C | 32 | chars | | latinExtendedD | Latin Extended D | 204 | chars | | latinExtendedE | Latin Extended E | 60 | chars | | latinExtendedF | Latin Extended F | 57 | chars | | latinExtendedG | Latin Extended G | 37 | chars | | lepcha | Lepcha | 74 | chars | | letterlikeSymbols | Letterlike Symbols | 80 | chars | | limbu | Limbu | 68 | chars | | linearA | Linear a | 341 | chars | | linearBIdeograms | Linear B Ideograms | 123 | chars | | linearBSyllabary | Linear B Syllabary | 88 | chars | | lisu | Lisu | 48 | chars | | lisuSupplement | Lisu Supplement | 1 | chars | | lycian | Lycian | 29 | chars | | lydian | Lydian | 27 | chars | | mahajani | Mahajani | 39 | chars | | mahjongTiles | Mahjong Tiles | 44 | chars | | makasar | Makasar | 25 | chars | | malayalam | Malayalam | 118 | chars | | mandaic | Mandaic | 29 | chars | | manichaean | Manichaean | 51 | chars | | marchen | Marchen | 68 | chars | | masaramGondi | Masaram Gondi | 75 | chars | | mathematicalAlphanumericSymbols | Mathematical Alphanumeric Symbols | 996 | chars | | mathematicalOperators | Mathematical Operators | 256 | chars | | mayanNumerals | Mayan Numerals | 20 | chars | | medefaidrin | Medefaidrin | 91 | chars | | meeteiMayek | Meetei Mayek | 56 | chars | | meeteiMayekExtensions | Meetei Mayek Extensions | 23 | chars | | mendeKikakui | Mende Kikakui | 213 | chars | | meroiticCursive | Meroitic Cursive | 90 | chars | | meroiticHieroglyphs | Meroitic Hieroglyphs | 32 | chars | | miao | Miao | 149 | chars | | miscellaneousMathematicalSymbolsA | Miscellaneous Mathematical Symbols a | 48 | chars | | miscellaneousMathematicalSymbolsB | Miscellaneous Mathematical Symbols B | 128 | chars | | miscellaneousSymbols | Miscellaneous Symbols | 256 | chars | | miscellaneousSymbolsAndArrows | Miscellaneous Symbols and Arrows | 254 | chars | | miscellaneousSymbolsAndPictographs | Miscellaneous Symbols and Pictographs | 768 | chars | | miscellaneousSymbolsSupplement | Miscellaneous Symbols Supplement | 34 | chars | | miscellaneousTechnical | Miscellaneous Technical | 256 | chars | | modi | Modi | 79 | chars | | modifierToneLetters | Modifier Tone Letters | 32 | chars | | mongolian | Mongolian | 157 | chars | | mongolianSupplement | Mongolian Supplement | 13 | chars | | mro | Mro | 43 | chars | | multani | Multani | 38 | chars | | musicalSymbols | Musical Symbols | 225 | chars | | myanmar | Myanmar | 160 | chars | | myanmarExtendedA | Myanmar Extended a | 32 | chars | | myanmarExtendedB | Myanmar Extended B | 31 | chars | | myanmarExtendedC | Myanmar Extended C | 20 | chars | | nko | NKo | 62 | chars | | nabataean | Nabataean | 40 | chars | | nagMundari | Nag Mundari | 42 | chars | | nandinagari | Nandinagari | 65 | chars | | newTaiLue | New Tai Lue | 83 | chars | | newa | Newa | 97 | chars | | numberForms | Number Forms | 60 | chars | | nushu | Nushu | 396 | chars | | nyiakengPuachueHmong | Nyiakeng Puachue Hmong | 71 | chars | | ogham | Ogham | 29 | chars | | olChiki | Ol Chiki | 48 | chars | | olOnal | Ol Onal | 44 | chars | | oldHungarian | Old Hungarian