diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index e51d544d5..57e5eeb6f 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -39,6 +39,7 @@ All definitions files include a header with the author and editors, so at some p
* [Box2DWeb](http://code.google.com/p/box2dweb/) (by [Josh Baldwin](https://github.com/jbaldwin/))
* [Breeze](http://www.breezejs.com/) (by [Boris Yankov](https://github.com/borisyankov))
* [Browser Harness](https://github.com/scriby/browser-harness) (by [Chris Scribner](https://github.com/scriby))
+* [bucks](https://github.com/CyberAgent/bucks.js) (by [Shunsuke Ohtani](https://github.com/zaneli))
* [CasperJS](http://casperjs.org) (by [Jed Hunsaker](https://github.com/jedhunsaker))
* [Cheerio](https://github.com/MatthewMueller/cheerio) (by [Bret Little](https://github.com/blittle))
* [Chosen](http://harvesthq.github.com/chosen/) (by [Boris Yankov](https://github.com/borisyankov))
diff --git a/bucks/bucks-test.ts b/bucks/bucks-test.ts
new file mode 100644
index 000000000..5ebbd882c
--- /dev/null
+++ b/bucks/bucks-test.ts
@@ -0,0 +1,222 @@
+///
+
+function add_and_end() {
+ //
+ // new Bucks object
+ //
+ var b = new Bucks();
+
+ //
+ // Add and add several tasks.
+ //
+ b.add(function f1(err, res) {
+
+ return 'a';
+
+ }).add(function f2(err, res, next) {
+
+ // res => 'a'
+ return next(null, 3);
+
+ }).add(function f3(err, res, next) {
+
+ // res => 3
+ return next(new Error('error after 3'));
+
+ }).add(function f4(err, res, next) {
+
+ // err => 'error after 3'
+ return next(null, "recover 4");
+
+ }).add(function f5(err, res) {
+
+ // res => 'recover 4'
+ throw new Error('error in f5');
+
+ }).add(function f6(err, res) {
+
+ // err => 'error in f5'
+ throw err;
+
+ }).add(function f7(err, res) {
+
+ // err => 'error in f5'
+ // ignore and return
+ return "recover 7";
+
+ }).add(function f8(err, res, next) {
+
+ // res => 'recover 7';
+ throw new Error('error in f8');
+
+ }).add(function f9(err, res, next) {
+
+ // err => 'Error in f8'
+ // ignore error
+ return next(null, 'result of 9');
+
+ }).end(function last(err, results) {
+
+ // all of results
+ // are obtained in #end
+
+ // err => null
+
+ // results => [
+ // 'a',
+ // null,
+ // null,
+ // 'recover 4',
+ // null,
+ // null,
+ // 'recover 7',
+ // null,
+ // 'result of 9'
+ // ];
+ });
+}
+
+function then() {
+ var b = new Bucks();
+ b.then(function start() {
+ return 'start';
+ }).then(function second(res, next) {
+ // res => 'start'
+ return next(null, 'second')
+ }).end();
+}
+
+function delay() {
+ var b = new Bucks();
+ b.add(function (){ /** program */ })
+ .delay(1 * 1000) // 1ms
+ .add(function() { /** program */})
+ .end();
+}
+
+function error() {
+ var b = new Bucks();
+ b.then(function start() {
+ throw new Error('error in start');
+ return 'start';
+ }).error(function onError(e, next) {
+ // e => 'error in start'
+ return next();
+ }).end();
+}
+
+function final_errorback_in_end() {
+ //
+ // last error back
+ //
+ var b = new Bucks();
+ b.empty(
+ // add empty task (#end with no task cause error)
+ ).end(function last(err, res) {
+ // error in last callback
+ throw new Error('error in end');
+ }, function finalErrorback(err) {
+ // catch uncaught error in last callback
+ // err => 'error in end'
+ });
+}
+
+function uncaught_error() {
+ try {
+ var b = new Bucks();
+ b.then(function () {
+ throw new Error('error');
+ }).end();
+ } catch(e) {
+ // e => 'error'
+ }
+}
+
+function waterfall() {
+ var t1: Bucks.Task = function t1(err, res) {
+ return 't1';
+ };
+ var t2: Bucks.Task = function t2(err, res) {
+ return 't2';
+ };
+
+ new Bucks().waterfall([t1, t2]).end(function finish(err, ress) {
+ // ress => ['t1', 't2']
+ });
+
+ // same as
+ new Bucks().add(t1).add(t2).end(function finish(err, ress) {
+ // ress => ['t1', 't2']
+ });
+}
+
+function parallel() {
+ var b = new Bucks();
+
+ b.parallel([
+ function task1(err, res) {
+ return "task1";
+ },
+ function task2(err, res, next) {
+ return next(null, "task2");
+ },
+ function task3(err, res, next) {
+ return next(new Error('passed error in task3'));
+ },
+ function task4(err, res, next) {
+ throw new Error('thrown error in task4');
+ }
+ ]).add(function getResults(err, res, next) {
+ // res => {
+ // err: [
+ // null,
+ // null,
+ // [Error: passed error in task3],
+ // [Error: thrown error in task4]
+ // ],
+ // res: [
+ // 'task1',
+ // 'task2',
+ // null,
+ // null
+ // ]
+ // }
+ next();
+ }).end();
+}
+
+function onError() {
+ var onError = function (e: Error, bucks: Bucks.Bucks) {
+ console.log("Custom onError");
+ };
+
+ // Bucks.onError!!
+ Bucks.onError(onError);
+ var b0 = new Bucks();
+ b0
+ .add(function(err, next) {
+ throw new Error('b0');
+ })
+ .end()
+ ;
+}
+
+function dispose() {
+ var b0 = new Bucks();
+
+ b0.dispose = function dispose () {
+ // delete b0.dummy;
+ }
+
+ b0
+ .add(function(err, next) {
+ // b0.dummy = "dummy";
+ next();
+ })
+ .end(null, null)
+ ;
+}
+
+function debug() {
+ Bucks.DEBUG = true;
+}
diff --git a/bucks/bucks.d.ts b/bucks/bucks.d.ts
new file mode 100644
index 000000000..cac3c7121
--- /dev/null
+++ b/bucks/bucks.d.ts
@@ -0,0 +1,113 @@
+// Type definitions for bucks.js 0.8.3
+// Project: https://github.com/CyberAgent/bucks.js
+// Definitions by: Shunsuke Ohtani
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare module Bucks {
+
+ interface BucksStatic {
+
+ /**
+ * bucks.js version.
+ */
+ VERSION: string;
+
+ /**
+ * If set `true`, uncaught errors are logged.
+ */
+ DEBUG: boolean;
+
+ /**
+ * Running bucks objects.
+ */
+ running: Bucks[];
+
+ /**
+ * Not yet called `end` bucks object.
+ */
+ living: Bucks[];
+
+ /**
+ * Create bucks object.
+ */
+ new(): Bucks;
+
+ /**
+ * Catch all errors.
+ * @param onError Function called after catching error
+ */
+ onError(onError: (err:Error, bucks:Bucks)=>any): void;
+ }
+
+ interface Bucks {
+
+ /**
+ * Add a task.
+ * @param task Function added async chain
+ */
+ add(task: TaskWithNext): Bucks;
+
+ /**
+ * Add a task called only in case of success.
+ * @param onSuccess Function called only in case of success
+ */
+ then(onSuccess: (res:any, next?:Task)=>any): Bucks;
+
+ /**
+ * Add a empty task.
+ */
+ empty(): Bucks;
+
+ /**
+ * Add a task called only in case of error.
+ * @param onError Function called only in case of error
+ */
+ error(onError: (err:Error, next?:Task)=>any): Bucks;
+
+ /**
+ * Add tasks in asynchronous way and join their results.
+ * @param tasks Functions called in asynchronous way and join their results
+ */
+ parallel(tasks: TaskWithNext[]): Bucks;
+
+ /**
+ * Add tasks in asynchronous way and join their results.
+ * @param tasks Functions added async chain
+ */
+ waterfall(tasks: TaskWithNext[]): Bucks;
+
+ /**
+ * Add delay execution.
+ * @param ms number millisecond for delaying
+ */
+ delay(ms: number): Bucks;
+
+ /**
+ * Called when destroy async chain.
+ */
+ dispose(): void;
+
+ /**
+ * Destroy this object and call last callback function.
+ * @param err If specify err and no callback, throw to execute failure callback
+ */
+ destroy(err?: Error): Bucks;
+
+ /**
+ * Complete creating async chain and start executing.
+ * @param callback Last callback function
+ * @param errback Handler for occurring error in last callback function
+ */
+ end(callback?: Task, errback?: (err:Error)=>any): void;
+ }
+
+ interface TaskWithNext {
+ (err?: Error, res?: any, next?: Task): any;
+ }
+
+ interface Task {
+ (err?: Error, res?: any): any;
+ }
+}
+
+declare var Bucks: Bucks.BucksStatic;