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

@kehto/wm

v0.0.1

Published

Generic window manager service contract for NIP-5D shells (draft — Phase 11 proposal from hyprgate).

Readme

@kehto/wm

Structural primitives for consumer-implemented layout strategies.

Alpha status: Kehto is an early runtime implementation for a draft NIP-5D protocol. Window-management contracts are shell-owned and experimental; they are not a NUB and may change as runtime implementations evolve.

What this package is

@kehto/wm provides the type contracts that shell consumers implement against:

  • LayoutStrategy (D1) — a pure arrange() function interface. No side effects. Consumers implement their own layout algorithm (BSP, master-stack, floating, etc.) in their shell repo using this contract.
  • WindowState (D2) — minimal universal window descriptor: id, focused, minimized, rect. Passed to arrange() on every layout pass.
  • WindowPlacement (D3)id + rect only. Output of an arrange() pass. Consumers track focus and stacking externally.
  • createWmService({ hooks, strategy? }) (D4) — factory with a no-op default strategy. Consumers can ship a working shell before implementing a real layout.

@kehto/wm is shell-internal state — it is not a NUB domain and there is no @napplet/nub/wm subpath.

What this package is not

  • Not a layout engine — no BSP, master-stack, floating, or other concrete algorithms ship here. Consumers build those in their own repos.
  • Not a strategy registrycreateWmService accepts exactly one strategy. Switching algorithms at runtime is a consumer-side concern.
  • Not a NUB domain — window management is shell-internal state. There is no @napplet/nub/wm subpath. Do not expose WM state to napplets via the napplet protocol.
  • Not algorithm-prescriptive@kehto/wm deliberately exports no string-literal union of algorithm names (H-04 anti-feature). Consumers choose their own names.

Consumer-integration example

The LayoutStrategy implementation lives in your shell repo — @kehto/wm ships only the contract.

// This LayoutStrategy implementation lives in your shell repo — @kehto/wm ships only the contract.
import type { LayoutStrategy, WindowState, WindowPlacement, Rect } from '@kehto/wm';
import { createWmService } from '@kehto/wm';

// Define your own layout algorithm in your shell repo:
const masterStackStrategy: LayoutStrategy = {
  arrange(windows: ReadonlyArray<WindowState>, containerRect: Rect): ReadonlyArray<WindowPlacement> {
    const visible = windows.filter(w => !w.minimized);
    if (visible.length === 0) return [];
    const [main, ...rest] = visible;
    const mainW = rest.length > 0 ? Math.floor(containerRect.w * 0.6) : containerRect.w;
    const sideW = containerRect.w - mainW;
    const sideH = rest.length > 0 ? Math.floor(containerRect.h / rest.length) : 0;
    return [
      { id: main.id, rect: { x: containerRect.x, y: containerRect.y, w: mainW, h: containerRect.h } },
      ...rest.map((win, i) => ({
        id: win.id,
        rect: { x: containerRect.x + mainW, y: containerRect.y + i * sideH, w: sideW, h: sideH },
      })),
    ];
  },
};

// Wire it into the service:
const wm = createWmService({ hooks: myHooks, strategy: masterStackStrategy });

Default no-op strategy

Omitting strategy from createWmService yields a no-op identity strategy: it returns windows unchanged (each WindowPlacement mirrors the WindowState rect). This is useful for bootstrapping a shell — the factory no longer throws, so consumers can get end-to-end wiring in place and add a real layout algorithm incrementally. The strategy is closure-scoped; consumers call strategy.arrange(windows, containerRect) from their own event handlers using state snapshots from wm.state.get().