Next Phenomenal Microbrewery
    Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »


    This library has been replaced by ctrl

    build status


    Simplifies asynchronous control flow in coffeescript making parallel code, synchronous code, and error handling simple

    Why make another control flow library?

    • One often desires to pass additional state to all the functions. Most of the control flow libraries I have seen do not allow for this. The issue can be worked around with a closure but closures are exactly what we are trying to avoid!
    • There are tons of control flow libraries out there but none of them seem to play well with coffeescript; they all override this which does not play well with coffeescript's bound function (()=>) syntax.


    • Makes it easy to write synchronous code without nested callbacks
    • Makes it easy to write parallel code without keeping track of all the pesky callbacks
    • Allows all your functions to easily share state without using a closure
    • Designed to be compatible with coffeescript's cool features
    • Works in nodejs and the browser

    How to install

    $ npm install funcflow

    Basic usage

    FuncFlow is really easy to use and consists of a single function to which you pass an array of functions to call. The first parameter to each function is a reference to a step object which allows you to control the flow of the program. If the previous function threw an error, it is passed as the second parameter to the next function. If there was no error, null is passed instead.

    steps = []
    steps.push (step, err)->
        console.log("working on the first thing")
        setTimeout(, 300)
    steps.push (step, err)->
        console.log("working on second thing whos callback returns stuff")
        setTimeout(, 300, "someString", 6969)
    # if the function calling the callback passes arguments, they are passed as additional arguments to the function.
    steps.push (step, err, someString, someNumber)->
        console.log("callback argument 1: " + someString)
        console.log("callback argument 2: " + someNumber)
        #If the current step does not need a callback simply call the next function yourself
    # to use the funcflow function require it and then pass in the steps and a callback
    funcflow = require('funcflow')
    funcflow(steps, ()->console.log('we are done!'))

    Error handling

    Any errors that are thrown within a step are passed to the next step to be handled

    steps = []
    steps.push (step, err)->
        raise "I am the first step and I am throwing an error"
    steps.push (step, err)->
        if err != null
            console.log("The first step raised an error")
    steps.push (step, err)->
        # You can use the "raise" function on the step object so that your error will not be caught
        step.raise("This error is not going to be caught and will bubble out") 
    funcflow = require('funcflow')
    funcflow(steps, ()->console.log('we are done!'))

    Parallel code

    Using the spawn function on the step object you can run tasks in parallel and the next step will only be run when all of the tasks are complete

    steps = []
    steps.push (step, err)->
        console.log("Starting the first task")
        setTimeout(step.spawn(), 300)
        console.log("Starting the second task")
        setTimeout(step.spawn(), 600)
        #tasks are started immediately so you should call next to let the library know you are done spawning tasks 
    funcflow = require('funcflow')
    funcflow(steps, ()->console.log('we are done!'))

    Sharing state

    Using an optional parameter, state can be passed to all the step functions

    steps = []
    steps.push (step, err)->
        step.sharedString = "step 1 has been here"
        setTimeout(, 300)
    steps.push (step, err)->
        setTimeout(, 300)
    sharedStateObject = {
        sharedString:"step 1 has not modified me"
        sharedFunc:(stepNum)->console.log("Starting Step " + stepNum)
    funcflow = require('funcflow')
    funcflow(steps, sharedStateObject, ()->console.log('we are done!'))

    The above code would output the following to the console

    Starting Step 1
    step 1 has not modified me
    Starting Step 2
    step 1 has been here




    npm i funcflow

    Downloadsweekly downloads








    last publish


    • avatar