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

dom-scope

v2.1.2

Published

Lightweight, typesafe DOM scoping and reference management library.

Readme

DomScope

DomScope is a lightweight, zero-dependency JavaScript library for working with isolated DOM sections. It allows you to create named scopes, safely reference elements without global selector collisions, and provides industry-standard TypeScript typing.

Key Features

  • Isolated DOM Scopes — Elements in different scopes can share identical data-ref names without conflict.
  • Multi-Root Support — Manage "teleported" elements or disconnected DOM nodes as a single logical unit via API.
  • Full TypeScript Support — Generic-based autocompletion and strict type checking.
  • Runtime Validation — Built-in checkRefs to ensure your DOM matches your code expectations.
  • SSR & Shadow DOM — Works seamlessly with Server-Side Rendering (JSDOM) and Web Components.
  • Performance — Uses TreeWalker for high-speed traversal with FILTER_REJECT for boundary isolation.

Installation

npm install dom-scope

Quick Start

Basic Example

<div id="app" data-scope="main">
    <button data-ref="submitBtn">Submit</button>

    <div data-scope="userForm" data-ref="formContainer">
        <input data-ref="name" type="text" />
        <button data-ref="submitBtn">Inner Submit</button> 
    </div>
</div>
import { DomScope } from 'dom-scope';

const scope = new DomScope(document.querySelector('#app'));

// 1. References are scoped (isolated)
console.log(scope.refs.submitBtn); // The outer button

// 2. Access nested scopes
const form = scope.scopes.userForm;
console.log(form.refs.submitBtn); // The inner button (no collision!)

// 3. Runtime validation
scope.checkRefs({
    submitBtn: HTMLButtonElement,
    formContainer: HTMLDivElement
});

Advanced: Multi-Root (Teleports)

If your component has elements in different parts of the DOM (e.g., a Modal body at the end of <body>), use the functional API:

import { selectRefs } from 'dom-scope';

const header = document.querySelector('#header');
const portal = document.querySelector('#modal-portal');

// Merges multiple roots into one logical set of refs
const refs = selectRefs([header, portal], {
    title: HTMLElement,
    closeBtn: HTMLButtonElement
});

TypeScript & JSDoc

Using Generics

import { DomScope } from 'dom-scope';

interface MyRefs {
    saveBtn: HTMLButtonElement;
    title: HTMLHeadingElement;
}

const scope = new DomScope<MyRefs>(element);
scope.refs.saveBtn.disabled = true; // Fully typed!

Using JSDoc

/** @type {DomScope<{title: HTMLHeadingElement}>} */
const scope = new DomScope(element);
scope.refs.title.textContent = "Hello";

API Reference

DomScope<T> Class

  • root — The root element/fragment.
  • refs — Object containing elements marked with data-ref.
  • scopes — Object containing child DomScope instances.
  • update(callback?) — Rescans the DOM for changes.
  • checkRefs(annotation) — Validates that refs exist and match the provided constructors.
  • querySelectorAll(query) — Scans elements strictly within the current scope boundaries.
  • contains(element) — Returns true if the element belongs to this scope (and not a sub-scope).
  • destroy() — Cleans up references.

Helper Functions

  • selectRefs(roots, annotation?, options?) — Functional way to collect refs. Supports single or multiple roots.
  • walkDomScope(roots, callback, options?) — Traverses the DOM until it hits a sub-scope boundary.

Configuration

type ScopeOptions = {
    refAttribute?: string;         // default: 'data-ref'
    scopeAttribute?: string | string[]; // default: 'data-scope'
    window?: any;                  // For SSR environments
    isScopeElement?: (el, conf) => string | null; // Custom scope detection
    scopeAutoNamePrefix?: string;  // default: 'unnamed-scope'
};

Performance Note

DomScope uses an optimized TreeWalker with NodeFilter.FILTER_REJECT. When it encounters an element that defines a new scope, it skips that entire branch during the current scope's scan. This makes it extremely efficient even for very deep and complex DOM trees.

License

MIT © Albert Bazaleev