diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8e88a2f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/node_modules
+/tmp
\ No newline at end of file
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..3a517ea
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,3 @@
+/node_modules/
+/tmp
+/test
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..066a06b
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,3 @@
+# 1.0.0 (june 19, 2014)
+
+* Init release
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3c2d191
--- /dev/null
+++ b/README.md
@@ -0,0 +1,65 @@
+# ES6 Promise polyfill
+
+This is a polyfill of [ES6 Promise](https://github.com/domenic/promises-unwrapping). The implementation based on [Jake Archibald implementation](https://github.com/jakearchibald/es6-promise) a subset of [rsvp.js](https://github.com/tildeio/rsvp.js). If you're wanting extra features and more debugging options, check out the [full library](https://github.com/tildeio/rsvp.js).
+
+For API details and how to use promises, see the JavaScript Promises HTML5Rocks article.
+
+## Notes
+
+The main target: implementation should be conformance with browser's implementations and to be minimal as possible in size. So it's strictly polyfill of ES6 Promise specification and nothing more.
+
+It passes both [Promises/A+ test suite](https://github.com/promises-aplus/promises-tests) and [rsvp.js test suite](https://github.com/jakearchibald/es6-promise/tree/master/test). And as small as 2,6KB min (or 1KB min+gzip).
+
+The polyfill uses `setImmediate` if available, or fallback to use `setTimeout`. Use [setImmediate polyfill](https://github.com/YuzuJS/setImmediate) by @YuzuJS to rich better performance.
+
+## How to use
+
+### Browser
+
+To install:
+
+```sh
+bower install es6-promise-polyfill
+```
+
+To use:
+
+```htmpl
+
+
+```
+
+### Node.js
+
+To install:
+
+```sh
+npm install es6-promise-polyfill
+```
+
+To use:
+
+```js
+var Promise = require('es6-promise-polyfill').Promise;
+var promise = new Promise(...);
+```
+
+## Usage in IE<9
+
+`catch` is a reserved word in IE<9, meaning `promise.catch(func)` throws a syntax error. To work around this, use a string to access the property:
+
+```js
+promise['catch'](function(err) {
+ // ...
+});
+```
+
+Or use `.then` instead:
+
+```js
+promise.then(undefined, function(err) {
+ // ...
+});
+```
diff --git a/bower.json b/bower.json
new file mode 100644
index 0000000..8b28ad4
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,11 @@
+{
+ "name": "es6-promise-polyfill",
+ "version": "1.0.0",
+ "main": "promise.js",
+ "ignore": [
+ ".*",
+ "**/.*",
+ "node_modules",
+ "test"
+ ]
+}
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..314af33
--- /dev/null
+++ b/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "es6-promise-polyfill",
+ "namespace": "Promise",
+ "version": "1.0.0",
+ "author": "Roman Dvornov ",
+ "description": "A polyfill for ES6 Promise",
+ "main": "promise.js",
+ "directories": {
+ "lib": "lib"
+ },
+ "devDependencies": {
+ },
+ "scripts": {
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/lahmatiy/es6-promise-polyfill.git"
+ },
+ "bugs": {
+ "url": "https://github.com/lahmatiy/es6-promise-polyfill/issues"
+ },
+ "keywords": [
+ "promises",
+ "futures",
+ "events"
+ ]
+}
diff --git a/promise.js b/promise.js
new file mode 100644
index 0000000..c3f0295
--- /dev/null
+++ b/promise.js
@@ -0,0 +1,326 @@
+(function(global){
+
+//
+// Check for native Promise and it has correct interface
+//
+
+var NativePromise = global['Promise'];
+var nativePromiseSupported =
+ NativePromise &&
+ // Some of these methods are missing from
+ // Firefox/Chrome experimental implementations
+ 'resolve' in NativePromise &&
+ 'reject' in NativePromise &&
+ 'all' in NativePromise &&
+ 'race' in NativePromise &&
+ // Older version of the spec had a resolver object
+ // as the arg rather than a function
+ (function(){
+ var resolve;
+ new NativePromise(function(r){ resolve = r; });
+ return typeof resolve === 'function';
+ })();
+
+
+//
+// export if necessary
+//
+
+if (typeof exports !== 'undefined' && exports)
+{
+ // node.js
+ exports.Promise = Promise || NativePromise;
+}
+else
+{
+ // in browser add to global
+ if (!nativePromiseSupported)
+ global['Promise'] = Promise;
+}
+
+
+//
+// Polyfill
+//
+
+var PENDING = 'pending';
+var SEALED = 'sealed';
+var FULFILLED = 'fulfilled';
+var REJECTED = 'rejected';
+var NOOP = function(){};
+
+// async calls
+var asyncSetTimer = typeof setImmediate !== 'undefined' ? setImmediate : setTimeout;
+var asyncQueue = [];
+var asyncTimer;
+
+function asyncFlush(){
+ // run promise callbacks
+ for (var i = 0; i < asyncQueue.length; i++)
+ asyncQueue[i][0](asyncQueue[i][1]);
+
+ // reset async asyncQueue
+ asyncQueue = [];
+ asyncTimer = false;
+}
+
+function asyncCall(callback, arg){
+ asyncQueue.push([callback, arg]);
+
+ if (!asyncTimer)
+ {
+ asyncTimer = true;
+ asyncSetTimer(asyncFlush, 0);
+ }
+}
+
+
+function invokeResolver(resolver, promise) {
+ function resolvePromise(value) {
+ resolve(promise, value);
+ }
+
+ function rejectPromise(reason) {
+ reject(promise, reason);
+ }
+
+ try {
+ resolver(resolvePromise, rejectPromise);
+ } catch(e) {
+ rejectPromise(e);
+ }
+}
+
+function invokeCallback(subscriber){
+ var owner = subscriber.owner;
+ var settled = owner.state_;
+ var value = owner.data_;
+ var callback = subscriber[settled];
+ var promise = subscriber.then;
+
+ if (typeof callback === 'function')
+ {
+ settled = FULFILLED;
+ try {
+ value = callback(value);
+ } catch(e) {
+ reject(promise, e);
+ }
+ }
+
+ if (!handleThenable(promise, value))
+ {
+ if (settled === FULFILLED)
+ resolve(promise, value);
+
+ if (settled === REJECTED)
+ reject(promise, value);
+ }
+}
+
+function handleThenable(promise, value) {
+ var resolved;
+
+ try {
+ if (promise === value)
+ throw new TypeError('A promises callback cannot return that same promise.');
+
+ if (value && (typeof value === 'function' || typeof value === 'object'))
+ {
+ var then = value.then; // then should be retrived only once
+
+ if (typeof then === 'function')
+ {
+ then.call(value, function(val){
+ if (!resolved)
+ {
+ resolved = true;
+
+ if (value !== val)
+ resolve(promise, val);
+ else
+ fulfill(promise, val);
+ }
+ }, function(reason){
+ if (!resolved)
+ {
+ resolved = true;
+
+ reject(promise, reason);
+ }
+ });
+
+ return true;
+ }
+ }
+ } catch (e) {
+ if (!resolved)
+ reject(promise, e);
+
+ return true;
+ }
+
+ return false;
+}
+
+function resolve(promise, value){
+ if (promise === value || !handleThenable(promise, value))
+ fulfill(promise, value);
+}
+
+function fulfill(promise, value){
+ if (promise.state_ === PENDING)
+ {
+ promise.state_ = SEALED;
+ promise.data_ = value;
+
+ asyncCall(publishFulfillment, promise);
+ }
+}
+
+function reject(promise, reason){
+ if (promise.state_ === PENDING)
+ {
+ promise.state_ = SEALED;
+ promise.data_ = reason;
+
+ asyncCall(publishRejection, promise);
+ }
+}
+
+function publish(promise) {
+ promise.then_ = promise.then_.forEach(invokeCallback);
+}
+
+function publishFulfillment(promise){
+ promise.state_ = FULFILLED;
+ publish(promise);
+}
+
+function publishRejection(promise){
+ promise.state_ = REJECTED;
+ publish(promise);
+}
+
+/**
+* @class
+*/
+function Promise(resolver){
+ if (typeof resolver !== 'function')
+ throw new TypeError('Promise constructor takes a function argument');
+
+ if (this instanceof Promise === false)
+ throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.');
+
+ this.then_ = [];
+
+ invokeResolver(resolver, this);
+}
+
+Promise.prototype = {
+ constructor: Promise,
+
+ state_: PENDING,
+ then_: null,
+ data_: undefined,
+
+ then: function(onFulfillment, onRejection){
+ var subscriber = {
+ owner: this,
+ then: new this.constructor(NOOP),
+ fulfilled: onFulfillment,
+ rejected: onRejection
+ };
+
+ if (this.state_ === FULFILLED || this.state_ === REJECTED)
+ {
+ // already resolved, call callback async
+ asyncCall(invokeCallback, subscriber);
+ }
+ else
+ {
+ // subscribe
+ this.then_.push(subscriber);
+ }
+
+ return subscriber.then;
+ },
+
+ 'catch': function(onRejection) {
+ return this.then(null, onRejection);
+ }
+};
+
+Promise.all = function(promises){
+ var Class = this;
+
+ if (!Array.isArray(promises))
+ throw new TypeError('You must pass an array to Promise.all().');
+
+ return new Class(function(resolve, reject){
+ var results = [];
+ var remaining = 0;
+
+ function resolver(index){
+ remaining++;
+ return function(value){
+ results[index] = value;
+ if (!--remaining)
+ resolve(results);
+ };
+ }
+
+ for (var i = 0, promise; i < promises.length; i++)
+ {
+ promise = promises[i];
+
+ if (promise && typeof promise.then === 'function')
+ promise.then(resolver(i), reject);
+ else
+ results[i] = promise;
+ }
+
+ if (!remaining)
+ resolve(results);
+ });
+};
+
+Promise.race = function(promises){
+ var Class = this;
+
+ if (!Array.isArray(promises))
+ throw new TypeError('You must pass an array to Promise.race().');
+
+ return new Class(function(resolve, reject) {
+ for (var i = 0, promise; i < promises.length; i++)
+ {
+ promise = promises[i];
+
+ if (promise && typeof promise.then === 'function')
+ promise.then(resolve, reject);
+ else
+ resolve(promise);
+ }
+ });
+};
+
+Promise.resolve = function(value){
+ var Class = this;
+
+ if (value && typeof value === 'object' && value.constructor === Class)
+ return value;
+
+ return new Class(function(resolve){
+ resolve(value);
+ });
+};
+
+Promise.reject = function(reason){
+ var Class = this;
+
+ return new Class(function(resolve, reject){
+ reject(reason);
+ });
+};
+
+})(new Function('return this')());
diff --git a/promise.min.js b/promise.min.js
new file mode 100644
index 0000000..ee30fcc
--- /dev/null
+++ b/promise.min.js
@@ -0,0 +1,5 @@
+(function(t){function x(){for(var a=0;a