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

@crowi/plugin-search-elasticsearch

v0.1.0-alpha.1

Published

Elasticsearch 9 search driver for Crowi 2.0.

Readme

@crowi/plugin-search-elasticsearch

Elasticsearch 9 search driver for Crowi 2.0. Indexes pages on create / update / delete, serves the wiki search box, and rebuilds the whole index from scratch on demand. Targets a <indexName>-current alias so a rebuild can swap the underlying index atomically.

Install

crowi-admin plugin add @crowi/plugin-search-elasticsearch

(or, in dev: pnpm --filter @crowi/api add -D @crowi/plugin-search-elasticsearch)

Configure

1. Activate the driver in crowi.config.json

{
  "plugins": ["@crowi/plugin-search-elasticsearch"],
  "search": { "driver": "elasticsearch" }
}

A server restart is required when search.driver changes — Crowi reads this file once at boot.

2. Fill in connection settings in the admin UI

Open /admin/plugins and edit @crowi/plugin-search-elasticsearch:

  • urlhttps://[user:pass@]host[:port][/indexName]. The URL embeds the cluster password (Bonsai-style), so it is encrypted at rest with CROWI_ENCRYPTION_KEY.
  • indexName — base index name (default crowi). The driver reads / writes the <indexName>-current alias.
  • requestTimeout — per-request timeout in ms (default 5000).
  • analyzerdefault / kuromoji / sudachi (see below).

Hot-reload (no restart needed)

This plugin implements reconfigure, so saving connection settings in the admin UI applies without a server restart. When you save:

  • the url / indexName / requestTimeout / analyzer changes are picked up by the live driver,
  • a fresh Elasticsearch client is built and the previous one is closed in the background (its HTTP keep-alive pool drains),
  • the admin UI shows a "saved — applied immediately" toast.

Mechanics: the driver holds a module-scope state ref; each operation (query / index / remove / rebuild) snapshots the state once at the top of the call, so a save that lands mid-request cannot retarget an inflight operation onto a different cluster. The next request sees the new settings.

Caveats

  • Analyzer changes need a manual rebuild. Switching analyzer (defaultkuromojisudachi) updates the setting immediately, but the existing index keeps its old analyzer — Elasticsearch analyzers are fixed at index-creation time. Run a full rebuild from /admin/search (or the rebuild action) to create a new index with the new analyzer and swap the alias to it.
  • Empty url → configured url is restart-only. If url was empty at boot, the driver is not registered and there is nothing for reconfigure to mutate; configure a url and restart once. After that, all further changes hot-reload. Clearing a configured url (configured → empty) is handled live — search requests then fail with a clear Search not configured error until a url is set again.
  • A rebuild that is already running when you reconfigure runs to completion against the cluster / index name it started with.

Analyzer flavours

| Analyzer | Cluster requirement | |---|---| | default | No extra Elasticsearch plugin. | | kuromoji | analysis-kuromoji plugin (Elastic-distributed). The dev image (elasticsearch.Dockerfile) preinstalls it. | | sudachi | Third-party analysis-sudachi plugin + dictionary. Not bundled in the dev image — operators must build a derived image. Picking this without the plugin makes rebuild() fail. |

Verifying hot-reload in dev

The dev docker compose stack includes an Elasticsearch service, so you can exercise the hot-reload path end to end:

  1. docker compose up -d — brings up mongo / redis / elasticsearch.
  2. pnpm dev — starts api + web.
  3. In /admin/plugins, set @crowi/plugin-search-elasticsearch's url to http://elasticsearch:9200/crowi and save; restart once if the driver was previously unconfigured.
  4. From /admin/search, run a rebuild to populate the index.
  5. Change requestTimeout (or point indexName at a freshly rebuilt index) and save without restarting. The next search query uses the new settings — confirmed by the api log line reconfigured elasticsearch search driver (...).

See also

  • RFC-0001 §"Search" for the migration story from the legacy ES7 indexer.
  • @crowi/plugin-storage-aws-s3 — the reference implementation of the same state-ref + snapshot hot-reload pattern.