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

ice-js

v0.0.4

Published

An tool for easily building isomorphic javascript applications on top of Backbone and React

Readme

Ice.js

NPM Version Build Status

What it is

Ice is a small framework for making performant single-page javascript applications easier to build with Express.js. It allows you to define routes and handlers and automatically handles data bootstrapping and markup pre-rendering. It's fully isomorphic, which means that once you finish defining routes and behavior, it will execute on both the client and the server. It also supports rendering React.

What it isn't

Ice is not a standalone solution for building a web application, because it relies on an external API. It does not support any I/O besides HTTP, and it doesn't support sockets or have an extensive library. It just consumes data from the existing API and renders it into views efficiently and using as little code as possible. The focus of Ice is to help you write an application that is naturally isomorphic, leaving server-specific logic to a separate codebase.

Why use it?

If you already know Express.js and Backbone, there's very little to learn in order to start building an Ice app. Ice deliberately extends these two popular libraries to provide minimal overhead to getting started. Ice also imposes minimal structure; beyond the route/handler paradigm there is very little stopping you from using Ice to implement exotic architectures of your own. In particular, the Ice.Router class is composable and modular in the spirit of Express, encouraging tidy, scalable code.

Getting Started

You should use NPM to get the latest version of Ice.js and require it into your project (you'll also need Express):

npm install -S ice-js

Then define the structure of your application by creating an instance of Ice.Router and specifying path/handler pairs:

//router.js
var Ice = require('ice-js'),
    router = new Ice.Router;

router.path('/', function(page){
  page.render('Hello World!');
});

module.exports = router;

In a separate file, require the router you created above and call router.make() to mount it onto an existing Express server:

//index.js
var express = require('express'),
    router = require('./router.js');
    
var app = express();

app.use(router.make());
app.listen(3000);

You now have a minimal but complete Ice.js application. The above code creates a server that renders the string "Hello World!" in response to requests for the / route. In addition, visiting / will instantiate a client-side application that reproduces the exact same behavior, rendering "Hello World!" when the browser's url is at the root location.

Using Ice it's trivial to build applications that automaticaly 'pre-render' server-side and then run as client-side apps once the page is loaded in the browser. Below is an overview of features of Ice and how to use them. You should also check out the full docs, specifically important caveats about using Ice, and how it works. Enjoy!

Ice is built on top the following open-source technologies:

React  |  Backbone.js  |  Express.js  |  Browserify

Ice Class Overview

Ice.Router

The Ice Router Class is inspired by the Express router class. Like it's cousin, it has use and all functions for attaching other router instances together and create complex routing schemes that are separated into modules. You can also use express-style regexes, globs, and parameters within your route definitions. See the full documentation for more details.

Here's an example of a number of these features implemented:

// router1.js
var Ice = require('ice-js'),
    router = new Ice.Router;

router.path('/ab*cd', function(page){
  page.render('OK');
});
router.path(/[A-Z]+/, function(page){
  page.render('OK');
});

module.exports = router;
// router2.js
var Ice = require('ice-js'),
    router = new Ice.Router;

router.path('/lower/:string', function(page){
  page.render(page.params.string.toLowerCase());
});

// mount router1 at /foo
router.use('/foo', require('./router1.js'));

module.exports = router;
// index.js
var router = require('./router2.js');
app.use(router.exportServer());
app.listen(3000);
// accepts routes /foo/abXcd, /foo/HELLO, /lower/HELLO

Ice.Page

Each route defined on a router gets a callback with a reference to a page object, which holds any params defined in routes, a query object, and cookies. While the page object's render function can accept strings as shown in the 'getting started' example, you can also supply a React component and dynamic data:

var Greeting = React.createClass({
  render: function(){
    return <div>
      Hello {this.props.name} !
    </div>
  }
});

router = new Ice.Router();
router.path('/greet/:name', function(page){
  page.render(Greeting, {
    name: page.params.name
  });
});

express().use(router).listen(3000);

GET localhost:3000/greet/tom --> <div>Hello tom !</div>

The page object works with the router to present a consistent api for dealing with the routes on either the client or server. The render function allows the Ice.Router class to serve as a fully-featured router for React. Check out the full documentation.

Ice.Model and Ice.Collection

These classes are extensions of Backbone Models and Collections and behave very much the same way, but with added isomorphic features. Used together with Ice.Router, they provide automatic bootstrapping via the function populate, which has the same signature as fetch. Here's an example that uses an Ice Model to fetch data from an API by ID, then render it asynchronously:

// dataModel.js
module.exports = Ice.Model.extend({
  urlRoot: 'http://data-api.com'
});
// router.js
var DataModel = require('./dataModel.js'),
    router = new Ice.Router();

router.path("/getData/:id", function(page){
  var model = new DataModel({id: page.params.id});
  model.populate().then(function(){
    page.render(model.get('data'));
  });
});

module.exports = router;

On the server, populate makes a call to http://data-api.com/[id] by delegating to Backbone.fetch, then bootstraps the response. On the client, populate fills the model with the bootstrapped data without having to make a network request. View the full documentation.

Examples

coming soon...