diff --git a/js-cookie/js-cookie-tests.ts b/js-cookie/js-cookie-tests.ts
new file mode 100644
index 0000000000..819f42903a
--- /dev/null
+++ b/js-cookie/js-cookie-tests.ts
@@ -0,0 +1,68 @@
+///
+
+// Create a cookie, valid across the entire site
+Cookies.set('name', 'value');
+
+// Create a cookie that expires 7 days from now, valid across the entire site
+Cookies.set('name', 'value', { expires: 7 });
+
+// Create an expiring cookie, valid to the path of the current page
+Cookies.set('name', 'value', { expires: 7, path: '' });
+
+// Read cookie
+Cookies.get('name'); // => 'value'
+Cookies.get('nothing'); // => undefined
+
+// Read all available cookies
+Cookies.get(); // => { name: 'value' }
+
+// Delete cookie
+Cookies.remove('name');
+
+// Delete a cookie valid to the path of the current page
+Cookies.set('name', 'value', { path: '' });
+Cookies.remove('name'); // fail!
+Cookies.remove('name', { path: '' }); // removed!
+
+// Assign the js-cookie api to a different variable
+// and restore the original "window.Cookies"
+var Cookies2 = Cookies.noConflict();
+Cookies2.set('name', 'value');
+
+// When creating a cookie you can pass an Array or Object Literal
+// instead of a string in the value. If you do so, js-cookie will
+// store the string representation of the object according to JSON.stringify
+Cookies.set('name', { foo: 'bar' });
+
+// When reading a cookie with the Cookies.getJSON api, you receive
+// the parsed representation of the string stored in the cookie
+// according to JSON.parse
+Cookies.getJSON('name'); // => { foo: 'bar' }
+
+// Define the domain where the cookie is available
+Cookies.set('name', 'value', { domain: 'sub.domain.com' });
+Cookies.get('name'); // => undefined (need to read at 'sub.domain.com')
+
+// Indicate that the cookie transmission requires (https)
+Cookies.set('name', 'value', { secure: true });
+Cookies.get('name'); // => 'value'
+Cookies.remove('name', { secure: true });
+
+document.cookie = 'escaped=%u5317';
+document.cookie = 'default=%E5%8C%97';
+var cookies = Cookies.withConverter(function (value, name) {
+ if ( name === 'escaped' ) {
+ return decodeURIComponent(value);
+ }
+});
+
+cookies.get('escaped'); // 北
+cookies.get('default'); // 北
+cookies.get(); // { escaped: '北', default: '北' }
+
+// To remove, set or declare defaults to the path of the
+// current page, you just need to declare it as empty:
+Cookies.defaults.path = '';
+
+// Deleting the property will fallback to the path: / internally:
+delete Cookies.defaults.path;
diff --git a/js-cookie/js-cookie.d.ts b/js-cookie/js-cookie.d.ts
new file mode 100644
index 0000000000..e8b8098c8f
--- /dev/null
+++ b/js-cookie/js-cookie.d.ts
@@ -0,0 +1,73 @@
+// Type definitions for js-cookie v2.0
+// Project: https://github.com/js-cookie/js-cookie
+// Definitions by: Theodore Brown
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare module Cookies {
+ interface CookieOptions {
+ expires?: number | Date;
+ path?: string;
+ domain?: string;
+ secure?: boolean;
+ }
+
+ interface CookiesStatic {
+ /**
+ * Allows default cookie options to be accessed, changed, or reset
+ */
+ defaults: CookieOptions;
+
+ /**
+ * Create a cookie
+ */
+ set(name: string, value: string | any, options?: CookieOptions): void;
+
+ /**
+ * Read cookie
+ */
+ get(name: string): string;
+
+ /**
+ * Read all available cookies
+ */
+ get(): {[key: string]: string};
+
+ /**
+ * Returns the parsed representation of the string
+ * stored in the cookie according to JSON.parse
+ */
+ getJSON(name: string): any;
+
+ /**
+ * Returns the parsed representation of
+ * all cookies according to JSON.parse
+ */
+ getJSON(): {[key: string]: any};
+
+ /**
+ * Delete cookie
+ */
+ remove(name: string, options?: CookieOptions): void;
+
+ /**
+ * If there is any danger of a conflict with the namespace Cookies,
+ * the noConflict method will allow you to define a new namespace
+ * and preserve the original one. This is especially useful when
+ * running the script on third party sites e.g. as part of a widget
+ * or SDK. Note: The noConflict method is not necessary when using
+ * AMD or CommonJS, thus it is not exposed in those environments.
+ */
+ noConflict(): CookiesStatic;
+
+ /**
+ * Create a new instance of the api that overrides the default
+ * decoding implementation. All methods that rely in a proper
+ * decoding to work, such as Cookies.remove() and Cookies.get(),
+ * will run the converter first for each cookie. The returned
+ * string will be used as the cookie value.
+ */
+ withConverter(converter: (value: string, name: string) => string): CookiesStatic;
+ }
+}
+
+declare var Cookies: Cookies.CookiesStatic;