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

rampike

v0.0.13

Published

non-reactive vanilla typed JS framework

Downloads

24

Readme

rampike

Non-reactive vanilla typed JS framework

Actually, a document.createElement() wrapper bundled with utilities for attaching objects to elements and cloning elements from templates

No dependencies btw

Features and usage

rampike

Attaches an object (or any other value) and a render function to an Element, returns the same element with rampike property added

// Create or retrieve an element via querySelector
const element = document.createElement("div");

// Create params variable
const props = {
	counter: 0,
	caption: "uhhh"
};
// Attach params and render function to the element
// Render function is called on init (can be skipped by providing options)
const rampikeElement = rampike(
	element, props,
	(params, root) => {
	root.textContent = `${params.value} ${params.counter}`;
});
// rampikeElement can be put into DOM directly
document.body.append(rampikeElement);

// ...

rampikeElement.addEventListener("click", () => {
	// Params can be updated by accessing .rampike.params
	rampikeElement.rampike.params.counter += 1;
	// OR by changing the original variable, since it is attached as is
	props.counter += 1;
	// Render function should be called explicitly after update
	rampikeElement.rampike.render();
});

In theory, it is possible to make params changes to trigger update in a very primitive way by using Proxies

mudcrack

Creates a new element while setting properties like events, attributes, styles, classes and more in a single call

Before (cringe):

const description = document.createElement("div");
description.className = "device-ritual-description";
description.textContent = ritual.desc;
document.body.append(description);

const time = document.createElement("div");
time.textContent = `every ${ritual.days} days`;
document.body.append(time);

const remove = document.createElement("button");
remove.className = "strip-defaults butt-on";
remove.addEventListener("click", removeCB);
remove.textContent = "remove"
document.body.append(remove);

After (based):

document.body.append(
	mudcrack({
		tagName: "div",
		className: "device-ritual-description",
		contents: ritual.desc
	}),
	mudcrack({
		tagName: "div",
		contents: `every ${ritual.days} days`
	}),
	mudcrack({
		tagName: "button",
		className: "strip-defaults butt-on",
		contents: "remove",
		events: {
			"click": removeCB
		}
	})
);

Available parameters:

type Params = {
	tagName: E,
	elementOptions: ElementCreationOptions,
	attributes: Record<string, string>,
	className: string,
	style: CSSRecord,
	events: EventsRecord,
	contents: string | Element[], // either textContent value or children
}

All parameters are optional. tagName is div by default

soilborne

Same as mudcrack, but takes an already created element, overwriting specified properties

sirocco

Generic version of rampike(). Simply attaches a value to an object while updating the type

const augmented = sirocco([0], 0, "map");
console.log(typeof augmented.map); // number

fromTemplateFirst and fromTemplateAll

Helpers for cloning element nodes from template element, see MDN

const template = document.querySelector<HTMLTemplateElement>("template#template-id")!;
const element = fromTemplateFirst(template);
const [title, body] = fromTemplateAll(template);

Reference

All functions are fully typed and self-documented, please consult the sources for other details

Credits

The tree clipart used as reference

Yapping

Reactive frameworks were a mistake. Reactivity is effective for state management when used with libraries like Jotai, but delegating updating the DOM to a big black box leads to unnecessary complexity which leads to bugs and even performance issues. It is faster to develop that way and thus it is commercially effective to use frameworks like Vue or React, but it's not fun and requires advanced expertise with specific frameworks instead of more general skills and knowledge

These tools, while proving themselves useful when working on small project like WebExtension views and small apps, are not meant to replace other JS frameworks. The idea is to experiment with DOM manipulation approaches and have fun, hence the silly names