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

@tofsjonas/searchable

v0.3.1

Published

<!-- markdownlint-disable MD033 MD026 MD024 --> <h1>searchable</h1> <h5>- a tiny, vanilla/plain JavaScript table search</h5>

Readme

Makes any table with class="searchable" searchable. Click the search button to filter table rows in real-time as you type.

Just include the JavaScript+CSS and it works automatically. No function calls needed.

sortable - makes tables sortable with similar simplicity.

https://tofsjonas.github.io/searchable/

Features

  • 1.41K minified (786 bytes gzipped)
  • Real-time search - filter as you type (case-insensitive)
  • Works with dynamic tables - JavaScript generated content supported
  • Lightning fast - handles large tables smoothly
  • Zero dependencies - vanilla JavaScript only
  • Auto-initialization - just add the class
  • Multi-language support - 29 languages available
  • Customizable - button position, icons, styling
  • Modern browsers - requires CSS :has() support (Chrome 105+, Firefox 121+, Safari 15.4+)

Installation

npm

npm install @tofsjonas/searchable

Import in your JavaScript/TypeScript:

import '@tofsjonas/searchable' // default = english version
import '@tofsjonas/searchable/dist/searchable.css'

Or for a specific language (e.g., Swedish):

import '@tofsjonas/searchable/dist/sv/searchable.min.js'
import '@tofsjonas/searchable/dist/sv/searchable.min.css'

CDN (jsDelivr)

Default (English):

<link href="https://cdn.jsdelivr.net/gh/tofsjonas/searchable@latest/dist/searchable.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/gh/tofsjonas/searchable@latest/dist/searchable.min.js"></script>

Or use a specific language (e.g., Swedish):

<link href="https://cdn.jsdelivr.net/gh/tofsjonas/searchable@latest/dist/sv/searchable.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/gh/tofsjonas/searchable@latest/dist/sv/searchable.min.js"></script>

Local files

Copy files from dist/ (or dist/[language]/ for specific languages) and link locally:

<link href="/assets/searchable.css" rel="stylesheet" />
<script src="/assets/searchable.min.js"></script>

Languages

searchable comes with built-in support for 29 languages. Each language version includes localized text for the search placeholder, empty state message, and search icon.

Supported Languages

  • ar - Arabic (العربية)
  • cs - Czech (Čeština)
  • da - Danish (Dansk)
  • de - German (Deutsch)
  • el - Greek (Ελληνικά)
  • en - English (default)
  • es - Spanish (Español)
  • fi - Finnish (Suomi)
  • fr - French (Français)
  • he - Hebrew (עברית)
  • hi - Hindi (हिन्दी)
  • hu - Hungarian (Magyar)
  • id - Indonesian (Bahasa Indonesia)
  • it - Italian (Italiano)
  • ja - Japanese (日本語)
  • ko - Korean (한국어)
  • nl - Dutch (Nederlands)
  • no - Norwegian (Norsk)
  • pl - Polish (Polski)
  • pt - Portuguese (Português)
  • ro - Romanian (Română)
  • ru - Russian (Русский)
  • sv - Swedish (Svenska)
  • th - Thai (ไทย)
  • tr - Turkish (Türkçe)
  • uk - Ukrainian (Українська)
  • vi - Vietnamese (Tiếng Việt)
  • zh - Chinese (中文)

Using a Specific Language

To use a specific language, include the language-specific files from the dist/[language]/ folder:

<!-- German example -->
<link href="https://cdn.jsdelivr.net/gh/tofsjonas/searchable@latest/dist/de/searchable.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/gh/tofsjonas/searchable@latest/dist/de/searchable.min.js"></script>

The default files in the root dist/ folder use English. You can still override any text using the data attributes described in the Configuration section.

Usage

Add class="searchable" to any table with <thead> and <tbody>:

<table class="searchable">
  <thead>
    <tr>
      <th>Product</th>
      <th>Price</th>
      <th>Category</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Laptop</td>
      <td>$999</td>
      <td>Electronics</td>
    </tr>
    <tr>
      <td>Coffee Mug</td>
      <td>$12</td>
      <td>Kitchen</td>
    </tr>
  </tbody>
</table>

A search button appears automatically. Click it to show/hide the search input.

Configuration

Button Position

Left vs Right Per table

<table class="searchable sb-left"></table>
<!-- left -->
<table class="searchable"></table>
<!-- right (default) -->

Globally using CSS

.searchable::before {
  top: 9px;
  left: 80px;
}

Custom Button Icon

Per table

<table class="searchable" data-sb-icon="🔍"></table>
<table class="searchable" data-sb-icon="Search"></table>

Globally

.searchable::before {
  content: 'anything you want' !important;
}

Input Styling

Per table

<table class="searchable" data-sb-input-class="form-control"></table>

Globally

Using HTML

<script
  data-sb-input-class="form-control bg-warning etc"
  src="https://cdn.jsdelivr.net/gh/tofsjonas/searchable@latest/dist/searchable.min.js"
></script>

Using CSS

.searchable thead input {
  background: purple;
  font-family: 'Comic Sans MS', 'Comic Sans', cursive;
}

Placeholder

Per table

<table class="searchable" data-sb-placeholder="Search..."></table>

Globally

<script
  data-sb-placeholder="Placeholder for all searchable inputs"
  src="https://cdn.jsdelivr.net/gh/tofsjonas/searchable@latest/dist/searchable.min.js"
></script>

Empty State Message

Per table

<table class="searchable" data-sb-empty="No matches found"></table>

Globally

.searchable thead::after {
  content: 'Nothing here, move along' !important;
}

Table Background

Set a background so the empty-state pseudo-element is not visible through transparent table areas.

.searchable,
.searchable td {
  background: white;
  color: black;
}

@media (prefers-color-scheme: dark) {
  .searchable,
  .searchable td {
    background: #333;
    color: #fff;
  }
}

How It Works

Uses event delegation and CSS :has() pseudo-class. The search input is created dynamically and filters rows by hiding non-matching content in real-time.