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

live-templates

v1.0.4

Published

reference data directly from templates, and get updates for nothing

Readme

live-templates.js

NPM version npm Travis

Bind data directly to HTML. No virtual DOM! No wasted elements! Write only changes directly onto the relevant elements (in the client or on the server).

Generally speaking, it's as if you insert variables directly onto the page, rather than rendering dead text.

What?!

As your objects update, thier DOM references are kept in sync without any need for selection logic, html manipulation or textual replacement and does not require a 1:1 binding between view and model. Because templates have access to many models on a namespace, it removes the need for any kind of boilerplate to bind a view to it's model allowing you to reduce MVVM or MVC to MV. It runs on the client or on the server under Node.js. It uses a comment marking strategy which is widely compatible with new and old browsers alike and it's economical because the only new DOM creation is rows being added or deleted and all values are directly inserted at a rate your browser can withstand.

Because live-templates does not replace or rerender HTML elements, there is no orphaned/zombie listener problem, so we can get back to using core web features.

Installation

npm install live-templates

Usage

live-templates supports a number of module idioms, because it is natively UMD it may be included without modification from source and will work in all targets. While it is webpack and browserify (and other preprocessors), it is written in browser and node compatible JS and needs no retargeting to function.

  • AMD
    define(['live-templates'], function(Live){
        //do stuff
    });
  • commonjs
    var Live = require('live-templates');
  • browser global
    <script src="node_modules/live-templates/live-templates.js"></script>

Configuration

live-templates wraps the raw arrays and objects you provide with array-events and object-events which then are then always up to date in the DOM as long as you use functions to update them. Soon there will be support for Indexed.Set and it's possible to write an adapter for almost any ORM or object hierarchy. To setup the Live object:

    Live.models(require(live-templates/models/evented));
    Live.templates(require(live-templates/models/handlebars));
    Live.setGlobalContext(window);

request and browser-request are used by default(serving from the /templates/ directory), but should you want to change the loader:

    Live.enableRequestTemplateLoader(request, '/myTemplateDir/');

The Model Namespace

To register a model, you just have to call Live.model(<namespace>, <model or collection>) and pass in a namespace (something like root.subitem.item) and the object or array. And to return the wrapped value just use Live.model(<namespace>).

Creating Views

Promises

Live.template() uses a promise based idiom

    Live.template(<template>).then(function(view){
        // view.dom is available as well as view.appendTo(el);
    });

Objects

new Live.Template() creates a new instance of the view, which is immediately ready for interaction (though devoid of any content until the callback)

    var sameView = new Live.Template('my-template.handlebars', function(view){
        // view.dom is available as well as view.appendTo(el);
    });

Either way, the produced view has a number of events (blur, focus, activate, deactivate, dom-update, before-dom-update, object-update, before-object-update) and member functions:

  • .on('event'[, conditions], handlerFunction); An implementation of Emitter.on() which accepts mongo-style selectors.
  • .once('event'[, conditions], handlerFunction); An implementation of Emitter.once() which accepts mongo-style selectors.
  • .off('event', handlerFunction); An implementation of Emitter.off().
  • .emit('event', data ... ); An implementation of Emitter.emit().
  • .when(event/asyncFn ... ); Allows you to chain ready functions or promises to events.
  • .focus(); Force browser/application cursor focus onto this element
  • .blur(); Force browser/application cursor focus onto this element
  • .activate(); Make sure an element is in it's active state, without triggering focus
  • .deactivate(); Make sure an element is in it's inactive state, without triggering blur

If you want the events to bubble through the DOM call view.proxyEventsToDOM();

also if you bind a field to an input, you may automatically update the model on field changes:

view.enableModelFeedback([selector, ]confirmationFunction);

the confirmation function allows you to do form checking, or any async action before the object is updated There's also some available properties:

  • view.dom : this is the generated DOM, which may be a DocumentFragment with many nodes or a single node;

Template Macros

Handlebars integration with live-templates takes the form of 'model' and 'models'. All template loading and interaction is handled for you.

  • {{#models "model-list-name"}} : this iterates through a list of models and generates a live template for each object, and monitors the list adding and removing content to reflect the model
  • {{#model ":"}} : this outputs a single live field from an object, if the model-name is omitted and you are inside a {{models}} scope that item is used.

Examples

  • User Feed - A simple feed-based content stream
  • Chat App[TBD]
  • Badges[TBD]

Now you can just concentrate on the models/data and stop screwing around in the DOM. (and there was much rejoicing)

##Contributing Make sure you add a test for your new feature, then submit a pull request.

##Testing for the local tests, just run

mocha

for the full suite of tests run

./full-test.sh

##Disclaimer

This is not an official Google product. (The only commit requiring this notice is this one )

Enjoy,

-Abbey Hawk Sparrow