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

kenro-wasm

v0.3.0

Published

SpatiaLite-style spatial SQL for SQLite in the browser — PostGIS-compatible ST_ functions as UDFs for sql.js, wa-sqlite and the official SQLite WASM build

Readme

kenro-wasm

SpatiaLite-style spatial SQL for SQLite in JavaScript — PostGIS-compatible ST_ functions registered as JS-level UDFs on any wasm SQLite host: the official @sqlite.org/sqlite-wasm build, sql.js, and wa-sqlite. On hosts whose SQLite takes no UDFs at all — Cloudflare D1 and Durable Objects — the same functions run standalone, from JS.

kenro is a spatial SQL engine in pure Rust (~210 functions: the DE-9IM predicate family, overlay/repair/buffer, CRS transform, H3, GeoJSON, MVT vector tiles, spatial aggregates), golden-tested against PostGIS. This package is its wasm build plus one small adapter per host. The bundled wasm is the full feature tier (~661 KB gzipped, the EPSG registry included); smaller tiers are attached to the GitHub Releases.

Live demo: https://reearth.github.io/kenro/ — drag a GeoPackage in and query it, entirely client-side.

Usage

import sqlite3InitModule from "@sqlite.org/sqlite-wasm";
import initKenro, * as kenroWasm from "kenro-wasm";
import { registerKenro } from "kenro-wasm/sqlite-wasm";

await initKenro();
const sqlite3 = await sqlite3InitModule();
const db = new sqlite3.oo1.DB(":memory:");
registerKenro(db, kenroWasm, sqlite3); // sqlite3 namespace needed for aggregates

db.selectValue("SELECT ST_AsText(ST_GeomFromText('POINT(1 2)'))"); // POINT(1 2)
// sql.js
import { registerKenro } from "kenro-wasm/sqljs";
registerKenro(db, kenroWasm);

// wa-sqlite
import { registerKenro } from "kenro-wasm/wa-sqlite";
registerKenro(sqlite3, db, kenroWasm);

Host support matrix, per-host limitations (sql.js: no int64 → the h3_* functions error loudly; no R-tree module) and measured sizes: docs/wasm.md. The full function table with PostGIS/DuckDB comparison: docs/functions.md.

Cloudflare Workers, D1 and Durable Objects

Neither D1 nor Durable Object SQLite supports user-defined functions or an R-tree, so ST_Intersects(...) can never appear in their SQL. The split that does work: kenro derives a bounding box and tile cells at write time for plain SQL to index, then runs the exact predicate in JS on the survivors.

import wasmModule from "kenro-wasm/pkg/kenro_wasm_bg.wasm";  // Workers hand you the Module
import * as kenro from "kenro-wasm";
import { cellFilterSql } from "kenro-wasm/quadtree";

kenro.initSync({ module: wasmModule });                      // once per isolate

using win = kenro.Prepared.fromText(wkt, 4326);              // decode once per scan
const hits = rows.filter((r) => {
  using g = kenro.Prepared.fromBlob(r.geom);
  return g.stIntersects(win);
});

Four subpaths carry this, all typed:

| | | |---|---| | kenro-wasmPrepared | a geometry decoded once, then predicates, GeoJSON/WKT output and reprojection chained off it | | kenro-wasm/quadtree | bounding box → variable-depth quadtree cell ids: the B-tree-indexable stand-in for the missing R-tree (sql.js lacks one too), with nothing to tune | | kenro-wasm/tiles | the same idea at one fixed zoom — simpler, and faster for windows near that zoom | | kenro-wasm/prepared | handle lifetimes where using isn't available |

A complete Worker on both backends, with tests that run in workerd: the Cloudflare example. API reference: docs/wasm.md.

License

MIT OR Apache-2.0, at your option.