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

venom-js

v1.0.28

Published

Venom templating library

Readme

VenomJS

Templating library with components, reactive variables (supports nested reactiveness too) and more.

Usage

To use either manage your own project and import venom from node_modules as module or install venom-cli and run:

venom init project_name

Running

If you created project from venom-cli you can start application with:

npm start

or build with:

npm run build

Development

To launch venom you need to import venom and mount it to element. you can do this by venom's mount function which takes as arguments element selector and component to start with:

import Venom  from "venom-js";
import AppComponent from "./src/app.component.js";

Venom.mount('#app', AppComponent);

You will also need component to mount. To create component, simply extend VenomComponent with your class and define render function:

import {template, VenomComponent} from "venom-js";

export default class AppComponent extends VenomComponent {
  constructor() {
    super();
  }

  render() {
    return template`
      <div class="my-app">
        Hello, Venom!
      </div>
    `;
  }
}

template takes html string and transforms it into real html. render function returns this html and after mounting this element becomes root of the app.

Components

From here we can define new components and use them. To use component instead of html element name we need to inject class of the component we are using and close tag with empty closing tag:

template`
  <div>
    <${MyComponent}></>
  </div>
`

You can declare any kind of variables and use them in templates. when variable values are updated, venom component also updates every place in real dom where it was used:

import {template, VenomComponent} from "venom-js";

export default class AppComponent extends VenomComponent {
  constructor() {
    super();
    this.name = 'venom-js';
  }

  updateName = e => {
    this.name = e.target.value;
  };

  render() {
    return template`
      <div class="my-app">
        Hello, ${this.name}!
        <input value="${this.name}" oninput=${this.updateName} />
      </div>
    `;
  }
}

Arrays

You can create templates for arrays which will be updated automatically + inserting new items in array won't rerender all items templates, but will only generate new template for new item and attach it to dom:

import {template, VenomComponent} from "venom-js";

export default class ArraySimpleComponent extends VenomComponent {
  constructor() {
    super();
    this.arr = [];
    this.counter = 0;
  }

  addToArray = () => {
    this.arr.push(this.counter++);
  };

  pop = () => {
    this.arr.pop();
  };

  render() {
    return template`
      <div>
        <button onclick="${this.addToArray}">Add ${this.counter}</button>
        <button onclick="${this.pop}">Pop last item</button>
        ${this.arr.map((value, i) => template`
          <div>value ${i}: ${value}</div>
        `)}
      </div>
    `;
  }
}

Objects

You can create any kind of object and update as nested value of it as you wish (Not sure you may find some bug but...) venom will be able to update all occurences of that nested object in the html:

import {template, VenomComponent} from "venom-js";

export default class ObjectNestedComponent extends VenomComponent {
  obj;
  constructor() {
    super();
    this.counter = 0;
    this.obj = {
      obj: {
        obj: {
          x: 1,
          y: 2
        },
        arr: []
      }
    };
  }

  update = xy => e => {
    console.log(this.obj.get());
    this.obj.obj.obj[xy] = e.target.value;
  };

  addToArray = () => {
    this.obj.obj.arr.push(this.counter++);
  };

  render() {
    return template`
      <div>
        <div>
          x input: <input type="text" oninput="${this.update('x')}"/>
        </div>
        <div>
          y input: <input type="text" oninput="${this.update('y')}"/>
        </div>
        x: ${this.obj.obj.obj.x}
        y: ${this.obj.obj.obj.y}
        <button onclick="${this.addToArray}">Add ${this.counter} to array</button>
        ${this.obj.obj.arr.map(value => template`<div>this is special div #${value}</div>`)}
      </div>
    `;
  }
}

while nested reactiveness is supported, objects in component might look a little bit uggly, so you can use get method to get fresh javascript object.

Venom Values

Venom thinks it should spread everywhere in the body, so instead of standard waterfall flow of variables, venom values are two way binded to each component, so no matter where you update the value if it was given from the parent, it will be given back to parent with new value. If you still preffer one way flow you can use copy method that every variable (or nested variable) of venom component has:

import {template, VenomComponent} from "venom-js";

class CounterComponent extends VenomComponent {
  class = "counter";
  constructor() {
    super();
    this.counter = 0;
  }

  addCounter = () => {
    this.counter++;
  };

  render() {
    return template`
      <span class="${this.class}">
        <div>${this.children}: ${this.counter}</div>
        <button onclick=${this.addCounter}>Add Counter</button>
      </span>
    `;
  }
}

export default class SimpleExampleComponent extends VenomComponent {
  constructor() {
    super();
    this.counter = 10;
  }
  render() {
    return template`
      <div>
        <h1>App Global Counter: ${this.counter}</h1>
        <${CounterComponent} counter="${this.counter.copy()}" class="counter-1">
          first <span style="color: red">counter</span>
        </>
        <${CounterComponent} counter="${this.counter}" class="counter-2">
          second <span style="color: green">counter</span>
        </>
      </div>
    `;
  }
}

That's pretty much all for now. I hope venom will soon support ternary operators in templates. p.s. you may not use variables as you would use it anywhere in render method. render method is only for declaring templates.