HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
Sage
streamlinejs
JavaScript2012–2015
Sage / streamlinejs

streamlinejs

Asynchronous JavaScript for dummies

10Distinct people
10Mentions
1Explicit recommenders
961GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Asynchronous JavaScript for dummies

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

I'd like to mention my favorite tool to deal with Callback Hell: Streamline, a JavaScript (and CoffeeScript) language extension that can compile to either 1) callback spaghetti…

DonPellegrino used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year10 dated mentions

Observed mentions: 2012-03-12 11:21:41 UTC to 2015-05-10 23:01:10 UTC.

012342012-01-01 00:00:00 UTC to 2013-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments20122013-01-01 00:00:00 UTC to 2014-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments20132014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments2015

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20122012-01-01 00:00:00 UTC2013-01-01 00:00:00 UTC404
20132013-01-01 00:00:00 UTC2014-01-01 00:00:00 UTC303
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC101
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC211

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
streamline.js streamline.js is a language tool to simplify asynchronous Javascript programming. tldr; See Cheat Sheet Instead of writing hairy code like: function archiveOrders(date, cb) { db.connect(function(err, conn) { if (err) return cb(err); conn.query("select * from orders where date < ?", [date], function(err, orders) { if (err) return cb(err); helper.each(orders, function(order, next) { conn.execute("insert into archivedOrders ...", [order.id, ...], function(err) { if (err) return cb(err); conn.execute("delete from orders where id=?", [order.id], function(err) { if (err) return cb(err); next(); }); }); }, function() { console.log("orders have been archived"); cb(); }); }); }); } you write: function archiveOrders(date, _) { var conn = db.connect(_); conn.query("select * from orders where date < ?", [date], _).forEach_(_, function(_, order) { conn.execute("insert into archivedOrders ...", [order.id, ...], _); conn.execute("delete from orders where id=?", [order.id], _); }); console.log("orders have been archived"); } and streamline transforms the code and takes care of the callbacks! No control flow APIs to learn! You just have to follow a simple rule: Replace all callbacks by an underscore and write your code as if all functions were synchronous. Streamline is not limited to a subset of Javascript. You can use all the features of Javascript in your asynchronous code: conditionals, loops, try/catch/finally blocks, anonymous functions, chaining, this, etc. Streamline also provides futures, and asynchronous variants of the EcmaScript 5 array functions (forEach, map, etc.). News The latest cool feature is TypeScript support. See https://github.com/Sage/streamlinejs/wiki/TypeScript-support for details. Streamline 1.0 was a major revamp as a Babel Plugin. Streamline 2.0 was a smaller step from Babel 5 to Babel 6. See https://github.com/Sage/streamlinejs/wiki/Babel-upgrade for details. Installation NPM, of course: npm install streamline -g The -g option installs streamline globally. You can also install it locally (without -g) but then the _node and _coffee commands will not be in your default PATH. Note: If you encounter a permission error when installing on UNIX systems, you should retry with sudo. Warning: you may get errors during install because fibers is now installed as an optional package and it may fail to build. But this package is optional and streamline itself should install fine. Hello World Streamline modules have ._js or ._coffee extensions and you run them with _node or _coffee. Example: $ cat > hello._js console.log('hello ...'); setTimeout(_, 1000); console.log('... world'); ^D $ _node hello You can also create standalone shell utilities. See this example. Compiling and writing loaders You can also set up your code so that it can be run directly with node or coffee. You have two options here: The first one is to compile your source. The recommanded way is with babel's CLI (see babel-plugin-streamline). But you can still use streamline's CLI (_node -c myfile._js or _coffee -c myfile._coffee) The second one is to create a loader which will register require hooks for the ._js and ._coffee extensions. See this example. Compiling will give you the fastest startup time because node will directly load the compiled *.js files but the registration API has a cache option which comes close. The recommandation is to use the loader during development but deploy precompiled files. Runtime dependencies The runtime library is provided as a separate streamline-runtime package. If you deploy precompiled files you only need streamline-runtime. If your application/library uses a loader you will need to deploy both streamline-runtime and streamline with it. Browser-side use You have two options to use streamline in the browser: You can transform and bundle your files with browserify. See how the build.js script builds the `test/browser/*-test.js files for an example. You can also transform the code in the browser with the transform API. All the necessary JS code is available as a single lib/browser/transform.js file. See the streamlineMe example. Generation options Streamline can transform the code for several target runtimes: callbacks. The transformed code will be pure ES5 code. It should be compatible with all JavaScript engines. fibers. The transformed code will take advantage of the fibers library. This option is only available server-side. generators. The transformed code will take advantage of JavaScript generators. It will run in node.js 0.12 (with the --harmony flag), in node.js 4.0 (without any special flag) and in latest browsers. await. The transformed code will take advantage of ES7 async/await. The choice of a target runtime should be driven by benchmarks: The fibers mode gives superior development experience (because it uses real stacks for each fiber so you can step over async calls). It is also very efficient in production if your code traverses many layers of asynchronous calls. The callbacks transform is obtained by chaining the generators transform and the regenerator transform. It is less efficent than the generators transform and we recommend that you use generators if generators are supported by your target JavaScript engine and that you only use callbacks if you target a legacy JavaScript engine. The await mode is experimental at this stage. It relies on an emulation as async/await is not yet available natively in JavaScript engines. You can control the target runtime with the --runtime (callbacks|fibers|generators|await) CLI option, or with the runtime API option. Interoperability with standard node.js code You can call standard node functions from streamline code. For example the fs.readFile function: function lineCount(path, _) { return fs.readFile(path, "utf8", _).split('\n').length; } You can also call streamline
Read the full README on GitHub

What Hacker News says

10 sources
DonPellegrino·Feb 4, 2014Recommendation phrase
I'd like to mention my favorite tool to deal with Callback Hell: Streamline, a JavaScript (and CoffeeScript) language extension that can compile to either 1) callback spaghetti 2) Node-fibers or 3) generator code. It basically writes the mess for you. It lets you focus on the higher order concepts and provides configurable parallel array operations as well as many other convenient features. The callback "error parameter" is thrown as an exception to be caught with a basic try/catch. I highly recommend that any Node and JS enthusiast give it a try. https://github.com/sage/streamlinejs
In Managing Node.js Callback Hell with Promises, Generators and Other Approaches
Yes, there are numerous libraries that do this. For instance, Tamejs is now rolled into CoffeeScript, creating IcedCoffeeScript. I didn't think CoffeeScript could get better, but it does. In addition, there is: Q (implementation of the CommonJS Promises spec) https://github.com/kriskowal/q Streamline.js https://github.com/Sage/streamlinejs Await.js (New, inspired by Tame/IcedCS) https://github.com/greim/await.js jQuery.Deferred http://api.jquery.com/category/deferred-object/ ...And less current libs like Node-promises and FuturesJS. Here's a comparison from last year: http://www.infoq.com/articles/surviving-asynchronous-program... And IcedCS's debut on HN: http://news.ycombinator.com/item?id=3522839 In JS devs seem to like to reinvent the wheel. I'd love to see the community rally around one of these solutions, instead of creating new
Read the rest
half-finished ones and abandoning them. I'm partial to IcedCS because it's the least verbose, and it also works as a lib outside of CS. The Promises spec has been (partially) implemented by jQuery and I'm sure is here to stay. Elm's syntax won't easily translate to any existing solution I'm aware of. It is a nice research project, but I will be sticking with established, well-tested methods instead of risking my business on another half-finished wheel.
In Escape from Callback Hell: Callbacks are the modern goto
Node.js actually has two problems that I think will be very major issues for it in the long run: - it's based on JavaScript, which is a crappy language (despite how nice V8 is) - (OP's point) the async style is horrible for readability, which puts a tremendous toll on productivity (though many will deny it). There are libraries like async (https://github.com/caolan/async) and streamline (https://github.com/Sage/streamlinejs) which try to eliminate #2. They are band-aids: the language itself must support asynchronous execution without callbacks. Node has many advantages that make it really nice - V8 is awesome because of an interesting case of technological path dependence; the standard library has a lot of modules that take great advantage of asynchronous I/O; the standard library is very high quality; the community is great - but I think
Read the rest
the two issues above really leave room for another project to take the good parts and not the bad ones, and steal Node's thunder. It could be Go or Python (with some badly needed extra work on coroutines, concurrency, performance/adoption of pypy, etc), or something new.
In Why I think Node.JS is a terrible platform

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.