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

intently

v0.2.1

Published

Intent-aware prefetching. Predicts where the cursor is headed — proximity + trajectory — and prefetches (or prerenders via the Speculation Rules API) the link a beat before the click. Zero-config, ~4KB, framework-agnostic.

Readme

intently

Intent-aware prefetching. Most prefetchers load every link in the viewport, or wait for a hover. intently watches where the cursor is actually heading — proximity and trajectory, the same prediction that powers a focus ring that warms as you approach — and prefetches (or prerenders, via the native Speculation Rules API) the link a beat before you click. Zero-config, ~4KB, framework-agnostic.

intentlyjs.com · npm · GitHub · the writeup

npm i intently

Quick start

One call binds every eligible same-origin link on the page:

import { intently } from "intently";

intently();

That's it. Move toward a link and intently prefetches its destination during the ~200ms between intent and click, so the navigation feels instant. React:

import { useIntently } from "intently/react";

function App() {
  useIntently();        // once, near the root
  return <Routes />;
}

Why another prefetcher

There are good ones, and intently borrows the best of each:

  • quicklink prefetches links in the viewport when the browser is idle. Great coverage, but it can't tell the one link you want from the fifty you don't.
  • instant.page prefetches on hover (a 65ms dwell). Precise, but hover is late — the decision is already made by the time you've parked the cursor.
  • ForesightJS predicts intent from mouse trajectory — the right signal — but you register elements yourself and wire up the prefetch.

intently combines them: zero-config auto-binding (drop it in, every <a> is covered) + trajectory + proximity prediction (the link you're aimed at, not the one you happen to be near) + a tiered loader that uses the Speculation Rules API for real prefetch and prerender, degrading to <link rel=prefetch> and then fetch where that isn't supported.

The trajectory idea is old — there are patents on cursor extrapolation going back years, and ForesightJS does it well today. intently's bet is that prediction + the right modern loader + nothing to configure is the combination worth shipping.

How it works

Three things, kept small:

1. Predict. On every pointermove, intently keeps a smoothed velocity. For each on-screen link it computes two scores — proximity (distance to the link's nearest edge, on a squared falloff) and trajectory (the dot product of your heading with the direction to the link, gated by a forward cone). The higher of the two is the confidence that this link is your next click. (This is the same math as the input-anticipation focus ring — here it drives a fetch instead of a glow.)

2. Tier by confidence. Crossing intentThreshold (default 0.5) prefetches. Sustained high confidence past prerenderThreshold (default 0.85) upgrades to a prerender — the next page is fully built in a hidden tab, so the click is instant, not just fast. Prerender is expensive, so it stays rare and high-bar.

3. Load with the best available backend.

| Tier | Used when | Does | |------|-----------|------| | Speculation Rules API | Chromium | real prefetch and prerender, cross-document, browser-prioritized | | <link rel="prefetch"> | most browsers | prefetch only | | fetch() low priority | last resort | warms the HTTP cache |

Only in-viewport links are scored (via IntersectionObserver), the scoring loop sleeps when the pointer is still, and every URL loads once. Offscreen links cost nothing.

Options

intently({
  origins: [location.hostname],   // hostnames allowed; or a (url, el) => boolean
  ignores: [/\/logout/, "?add-to-cart"], // never touch these (strings or RegExps)
  signals: ["trajectory", "proximity", "hover", "touch"], // which to use
  intentThreshold: 0.5,           // confidence (0–1) to prefetch
  prerenderThreshold: 0.85,       // confidence to prerender; false to disable
  proximityRadius: 80,            // px — how far a link "notices" the cursor
  hoverDelay: 65,                 // ms dwell before hover counts (instant.page's number)
  eagerOnPress: true,             // prefetch immediately on pointerdown / touchstart
  viewportPrefetch: false,        // also idle-prefetch in-view links (quicklink-style)
  limit: Infinity,                // cap total loads
  respectSaveData: true,          // skip on Save-Data / 2g
  onPredict: ({ el, url, confidence, signal }) => {}, // wire a visual affordance
  onLoad: (url, strategy) => {},  // "prefetch" | "prerender"
});

intently() returns a handle:

const i = intently();
i.prefetch("/pricing");   // force it
i.prerender("/checkout"); // force it (falls back to prefetch where unsupported)
i.loaded;                 // ReadonlySet<string> of URLs loaded this session
i.destroy();              // remove every listener/observer

Exposed prediction helpers

The prediction math is exported if you want to build your own affordance (a ring that warms as confidence rises, say):

import { distanceToRect, falloff, proximityScore, trajectoryScore } from "intently";

Safety & taste

  • It only guesses same-origin links by default, and never touches anything in ignores. Put sign-out, "add to cart", language switches, and any link with side effects there — especially before enabling prerender, which runs the page.
  • It respects the user. Save-Data and 2g connections turn it off. A still cursor predicts nothing.
  • It degrades. No Speculation Rules → <link rel=prefetch>fetch. SSR / no-DOM → a no-op handle.
  • Prefetch is a hint, not a navigation. The real click always works whether or not the guess landed.

When it helps (and when it doesn't)

Biggest wins are multi-page apps and hard navigations — content sites, docs, e-commerce, blogs — where the next page is a real document fetch. For SPAs with a client router (React Router, Next.js), those frameworks already prefetch route data; intently still helps for outbound and non-router links, and its prediction layer is reusable.

Credits

Trajectory prediction by way of ForesightJS and a long line of cursor-extrapolation prior art; zero-config ergonomics from instant.page; viewport idle prefetch from quicklink; the prediction math from my own input-anticipation work. Built on the Speculation Rules API.

By Sean Geng. MIT.