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

lingua-priority

v0.1.0

Published

Sensible language ordering for dropdowns. Stop scrolling past Somali to find Spanish.

Readme

lingua-priority

Stop scrolling past Somali to find Spanish.

npm version bundle size tests zero dependencies

A tiny (~2.5KB) zero-dependency library that sorts languages by actual global usage instead of alphabetically. Because Spanish has 500+ million speakers and shouldn't be buried under Samoan, Serbian, and Shona.

The Problem

Every language dropdown ever:

Afrikaans
Albanian  
Amharic
Armenian
Azerbaijani
...
[42 languages later]
...
Slovenian
Somali
Spanish   ← There it is! The 4th most spoken language on Earth!

Your users in Madrid, Mexico City, and Miami are mass-scrolling past Sango (5M speakers) to find their language. This is broken UX that's been copy-pasted across the internet for decades.

The Solution

npm install lingua-priority
import { suggest } from 'lingua-priority'

const { suggested, rest } = suggest(10)
// suggested: English, Chinese, Spanish, Hindi, Arabic... (by actual usage)
// rest: Afrikaans, Albanian, Amharic... (alphabetical)

That's it. Two arrays. Build your dropdown with a separator.

Perfect Dropdown Pattern

┌─────────────────────────────┐
│ 🔥 Suggested                │
├─────────────────────────────┤
│ Español                     │  ← Browser detected: Spanish
│ English                     │  ← Browser detected: English
│ 中文 (Chinese)              │  ← Top global #2
│ हिन्दी (Hindi)               │  ← Top global #4
│ العربية (Arabic)            │  ← Top global #5
├─────────────────────────────┤
│ 🌍 All Languages            │
├─────────────────────────────┤
│ Afrikaans                   │
│ Albanian                    │
│ Amharic                     │
│ ...                         │
└─────────────────────────────┘

The suggest() function:

  1. Detects browser languages via navigator.languages
  2. Backfills with top global languages by speaker count
  3. Returns the rest alphabetically

Your Spanish user sees Spanish first. Your Japanese user sees Japanese first. Everyone else gets English, Chinese, Spanish at the top — languages that cover 60% of the internet.

React Example

import { suggest } from 'lingua-priority'

function LanguageSelect({ value, onChange }) {
  const { suggested, rest } = suggest(10)

  return (
    <select value={value} onChange={(e) => onChange(e.target.value)}>
      <optgroup label="Suggested">
        {suggested.map((lang) => (
          <option key={lang.code} value={lang.code}>
            {lang.nativeName}
          </option>
        ))}
      </optgroup>
      <optgroup label="All Languages">
        {rest.map((lang) => (
          <option key={lang.code} value={lang.code}>
            {lang.nativeName}
          </option>
        ))}
      </optgroup>
    </select>
  )
}

Vue Example

<script setup>
import { suggest } from 'lingua-priority'

const { suggested, rest } = suggest(10)
const selected = ref('en')
</script>

<template>
  <select v-model="selected">
    <optgroup label="Suggested">
      <option v-for="lang in suggested" :key="lang.code" :value="lang.code">
        {{ lang.nativeName }}
      </option>
    </optgroup>
    <optgroup label="All Languages">
      <option v-for="lang in rest" :key="lang.code" :value="lang.code">
        {{ lang.nativeName }}
      </option>
    </optgroup>
  </select>
</template>

API

suggest(n?: number)

The main event. Returns browser-detected languages first, filled with top global languages.

const { suggested, rest } = suggest(10)
// suggested: Language[] - Smart picks (max n)
// rest: Language[] - Everything else, A-Z

getTop(n?: number)

Top languages by composite rank (speakers + internet usage).

getTop(5)
// → English, Chinese, Spanish, Hindi, Arabic

sortBy(metric)

Sort by a specific metric.

sortBy('native')   // By native speakers: Chinese, Spanish, English...
sortBy('total')    // By total speakers: English, Chinese, Spanish...
sortBy('internet') // By web content: English, Russian, German...

preset(region)

Regional language packs.

preset('EU')       // German, French, Spanish, Italian, Polish...
preset('Americas') // English, Spanish, Portuguese, French
preset('APAC')     // Chinese, Japanese, Korean, Hindi...
preset('MENA')     // Arabic, Turkish, Persian, Hebrew, Urdu
preset('Africa')   // English, French, Arabic, Swahili...

find(code)

Find by ISO 639-1 or 639-2 code.

find('es')  // → { code: 'es', name: 'Spanish', nativeName: 'Español', ... }
find('spa') // → Same (ISO 639-2 also works)

codes(n?: number)

Just the codes, for <option value="">.

codes(5) // → ['en', 'zh', 'es', 'hi', 'ar']

detectBrowser()

Get browser language preferences. SSR-safe (returns [] on server).

detectBrowser() // → [{ code: 'es', ... }, { code: 'en', ... }]

Data Shape

interface Language {
  code: string         // 'es' (ISO 639-1)
  code3: string        // 'spa' (ISO 639-2)
  name: string         // 'Spanish'
  nativeName: string   // 'Español'
  nativeSpeakers: number // 475 (millions)
  totalSpeakers: number  // 550 (millions)
  internetUsage: number  // 4.4 (% of web content)
}

Why This Ranking?

The composite score balances three factors:

| Factor | Weight | Why | |--------|--------|-----| | Total speakers | 40% | Actual reach (native + L2) | | Native speakers | 30% | Cultural weight | | Internet usage | 30% | Digital relevance |

This puts English first (internet dominance), Chinese second (speaker count), and Spanish third (huge L2 population). Hindi and Arabic round out the top 5.

Data Sources

  • Ethnologue 2024 — Speaker counts
  • W3Techs — Web content statistics
  • Wikipedia — Cross-reference

SSR / Next.js / Remix

Works perfectly. detectBrowser() returns [] when navigator is undefined, so suggest() gracefully falls back to pure ranking. No hydration mismatches.

// Server: suggest() returns top by rank
// Client: suggest() returns browser langs + top by rank

Bundle Size

| Format | Size | Gzipped | |--------|------|---------| | ESM | 7.9 KB | 2.5 KB | | CJS | 8.0 KB | 2.6 KB |

Zero dependencies. Tree-shakeable.

FAQ

Q: Why not just use the browser's locale?

navigator.language gives you one language. navigator.languages gives you a preference list, but most users don't configure this. Our approach: use browser preferences when available, fall back to global usage statistics.

Q: Why not alphabetical with "popular" pinned at top?

That's essentially what suggest() does, but smarter. The "popular" list is generated from actual data, and it adapts to the user's browser settings.

Q: Can I customize the ranking weights?

Not yet. Open an issue if you need this.

Q: What about country-specific variants (en-US, en-GB)?

We normalize to base language codes. en-US and en-GB both map to en. For most dropdowns, this is what you want.

Contributing

PRs welcome. The language data is in src/data.ts. If you find outdated statistics, please submit a fix with sources.

License

MIT © SPANISH FLU


Stop punishing your users with alphabetical language lists. Spanish speakers shouldn't have to scroll past Somali. Hindi speakers shouldn't hunt past Hausa. Fix your dropdowns.

npm install lingua-priority