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

sidebarius

v1.0.2

Published

Sidebarius is a lightweight JavaScript tool that makes sidebars sticky and scrollable. It is independent of any third-party libraries.

Readme

Sidebarius

NPM License NPM version NPM downloads (total) NPM Downloads (montly)

Sidebarius is a lightweight, dependency-free JavaScript tool for creating a "sticky" sidebar that adapts to scroll movements. This allows for dynamic interfaces with elements that stay in view as the user scrolls the page.

Demo 👈

Table of Contents


Installation

Install the package via npm:

npm install sidebarius

Usage

Vanilla JS

<main>
  <aside id="container">
    <div id="container_inner"><!-- Sidebar content --></div>
  </aside>
  <section><!-- Section content --></section>
</main>

<!-- Import globally, or use ES Modules as shown below -->
<!-- <script src="./sidebarius.iife.min.js"></script> -->

<script type="module">
  import Sidebarius from './sidebarius.esm.min.js'; // Or use the global import (see commented line above)

  const sidebarius = new Sidebarius(
    document.getElementById('container'),
    document.getElementById('container_inner'),
    16, // spaceBottom (optional, default is 0)
    16, // spaceTop (optional, default is 0)
    callback, // optional callback
  );

  sidebarius.start();

  function callback(state, direction, strategy) {
    console.log('STATE: ' + ['None', 'ContainerBottom', 'ColliderTop', 'ColliderBottom', 'TranslateY', 'Rest'][state]);
    console.log('DIRECTION: ' + ['None', 'Down', 'Up'][direction]);
    console.log('STRATEGY: ' + ['None', 'Both', 'Top'][strategy]);
  }
</script>

Latest release


React Typescript

import React, { useRef, useEffect, FC, HTMLAttributes, CSSProperties } from 'react';
import Sidebarius from 'sidebarius';

type SidebarContainerProps = Omit<HTMLAttributes<HTMLElement>, 'style'> & {
  style?: Omit<CSSProperties, 'padding'>;
};

type SidebarContainerInnerProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {
  style?: Omit<CSSProperties, 'margin'>;
};

interface SidebarProps {
  container?: SidebarContainerProps;
  containerInner?: SidebarContainerInnerProps;
}

const Sidebar: FC<SidebarProps> = ({ container = {}, containerInner = {}, children }) => {
  const containerRef = useRef<HTMLElement | null>(null);
  const containerInnerRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    if (!containerRef.current || !containerInnerRef.current) return;

    const sidebarius = new Sidebarius(
      containerRef.current,
      containerInnerRef.current,
      16, // spaceBottom
      16, // spaceTop
    );

    sidebarius.start();

    return () => {
      sidebarius.stop();
    };
  }, []);

  return (
    <aside ref={containerRef} {...container}>
      <div ref={containerInnerRef} {...containerInner}>
        {children}
      </div>
    </aside>
  );
};

export default Sidebar;

API

| Method | Description | | ---------------------------------- | ----------------------------------------------------------- | | start() | Starts the sticky scrolling behavior. | | stop() | Stops the sticky scrolling behavior. | | setSpaces(bottomSpace, spaceTop) | Sets the distance to the collider and triggers a re-render. |


Constructor Parameters

constructor(
  container: HTMLElement,
  containerInner: HTMLElement,
  spaceBottom: number = 0,
  spaceTop: number = 0,
  callback: Callback = () => {}
);

| Parameter | Type | Description | | ---------------- | ----------- | ----------------------------------------------------------------------------------- | | container | HTMLElement | The parent element (Container) that holds the sticky element. | | containerInner | HTMLElement | The element endowed with stickiness and scrolling abilities relative to its parent. | | spaceBottom | number | The space between the bottom of the viewport and the visible area. Default is 0. | | spaceTop | number | The space between the top of the viewport and the visible area. Default is 0. | | callback | Callback | A function called before changes to the ContainerInner occur. See Callback |


Callback

type Callback = (state: State, direction: Direction, strategy: Strategy) => void;

See also: State, Direction, Strategy


State

Defines the positioning states of the ContainerInner.

| Value | Description | | ----- | -------------------------------------------------------------------------------------------------- | | 0 | None: Default behavior of ContainerInner. | | 1 | ContainerBottom: ContainerInner is affixed to the bottom of the Container. | | 2 | ColliderTop: ContainerInner is fixed at the top of the viewport area, including SpaceTop. | | 3 | ColliderBottom: ContainerInner is fixed at the bottom of the viewport area, including SpaceBottom. | | 4 | TranslateY: ContainerInner is offset along the Y-axis relative to the Container. | | 5 | Rest: Rendering is paused until the state changes. |


Direction

Defines the direction of the viewport.

| Value | Description | | ----- | -------------------------------------- | | 0 | None: No movement in the viewport. | | 1 | Down: The viewport is moving downward. | | 2 | Up: The viewport is moving upward. |


Strategy

Defines the sticky behavior strategy.

| Value | Description | | ----- | ------------------------------------------------------------- | | 0 | None: No sticky behavior is applied. | | 1 | Both: Sticky behavior is applied on both edges of the Y-axis. | | 2 | Top: Sticky behavior is applied only at the top edge. |


Limitations

  1. Container cannot use the CSS property padding (must be 0).
  2. ContainerInner cannot use the CSS property margin (must be 0).

Concept

Preview

Viewport concepts | Viewport | Collider


Strategy

Strategy


Development

Commit Message Guidelines

  • feat - new feature
  • fix - bug fix
  • docs - documentation
  • style - formatting, whitespace, no code logic changes
  • refactor - code refactoring
  • test - adding/changing tests
  • chore - minor tasks, build process, configuration

Examples:

git commit -m "feat: add setSpaces to set top and bottom collider spaces"
# Or
git commit -m "docs: add API usage examples"

Links


Copyright and license

Copyright 2026 Mikhail Prugov. Code released under the MIT License.