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 🙏

© 2025 – Pkg Stats / Ryan Hefner

fodder

v1.3.1

Published

Feature oriented development

Downloads

22

Readme

I'm proud to say that fodder is being supported by BrowserStack!

fodder -- feature oriented development

fodder provides a new way to write applications. It looks like this:

// your features.js file.
// this is where you define all your app's features
var feature = require('fodder').feature;
feature('log in', function (when) {
  when('successful login', 'show user homepage');
  when('unsuccessful login', 'show login error message');
});

// controllers.js
var fire = require('fodder').fire;
var startFeature = require('fodder').startFeature;
function whenLoginButtonClicked() {
    startFeature('log in');
    sendLoginInfoToServer()
        .success(function() {
            fire('successful login');
        })
        .error(function() {
            fire('unsuccessful login');
        };
}

// routing.js
var listen = require('fodder').listen;
listen('show user homepage', function() {
    router.navigate('user-home');
});

// notifications.js
var listen = require('fodder').listen;
var toastr = require('toastr');
listen('show login error message', function() {
    toastr.error('There was a problem logging in!');
});

discussion

fodder provides an alternative to the 'straight line of death' that is most applications.

Usually a request comes into your application and follows a straight line from the entry point through things like database access, validation, authentication, HTML rendering, and on and on. If anything goes wrong at any point on this line, the whole thing explodes and you're left to hunt for wherever the failure occurred and why. You don't know where the logic began or what its end point is meant to be. You don't even know what the user was doing when the failure occurred!

With fodder and feature oriented development, features - and what can and will happen during their execution - are well known. If a failure occurs in one step (e.g. when logging in), you will know what the user wanted to do along with which exact step failed.

More importantly, your development is now decoupled. Chunks of functionality are put together into a cohesive whole. You can see in your code exactly where a feature's work begins, and because individual pieces are clearly defined, you can debug your code knowing exactly what it's meant to do.

Because pieces of functionality (e.g. 'send login request to server', 'add item to cart') are completely encapsulated and responsible for only one thing, you can use them elsewhere in a cause-effect relationship. This is true code reuse. This is the dream in action.

// let's reuse some things!
feature('log in', function (when) {
  when('already logged in', 'show user homepage');
  when('successful login', 'show user homepage');

  when('username not known', 'show login error message');
  when('password not correct', 'show login error message');
});

Your "features.js" file is now your map of your whole application. When you want to create a new feature, you come here and define how it should work in plain English. Even your product designers will be able to understand how the application works.

Other benefits include ultimate testability. Consider how easy it would be to pass in mock data to the 'add product to cart' step here:

// controllers.js
fire('add product to cart', {item: this.selectedItem});

// cart.js
listen('add product to cart', function(data) {
    tellServerToPutItemInCard(data.item_id);
});

more

specify an event to fire when starting a feature

You can have an event fire as soon as you call startFeature:

var startFeature = require('fodder').startFeature;
startFeature('user home page', 'load user data');

fire multiple events

You can use when to fire multiple events:

feature('user home', function (when) {
  when('user home loaded', 'show spinner', 'load user data');
  when('user data loaded', 'display user data', 'hide spinner');
});

automatically fire an event when starting a feature

feature('read book', function(when, startWith) {
  startWith('recite title of book');
  when('user wants to read book', 'open book');
})

get notified when a handler for a specific step couldn't be found.

setOnListenerNotFound(function(msg) {
  console.warn('Tinderbox didn\'t find a step handler. It said: ' + msg);
});

installation

Install fodder via npm: https://www.npmjs.com/package/fodder