diff --git a/README.md b/README.md
index 41011c4..f116ae6 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # Disclaimer
 
 In general, I would suggest using cookie sessions for web applications.
-But still, you may have a case when you have to use JWT tokens and store them in the local storage,
+But still, you may have a case when you have to use JWT/Non-JWT tokens and store them in the local storage,
 here this library might be useful.
 React Native is also a good reason for using such a library.
 
@@ -32,7 +32,7 @@ is valid.
 This library has typings for TypeScript code, but nothing prevents you from just
 remove types from the examples and use as a JavaScript code.
 
-### Access and Refresh tokens
+### Access and Refresh JWT tokens
 
 Let's assume you have a backend that uses `accessToken` and `refreshToken` to auth
 users and provides services `/login`, `/register`, and `/update-token`. All services
@@ -50,7 +50,10 @@ The first step you need to do is to create an instance of an `authProvider`.
 ```typescript
 import { createAuthProvider } from 'react-token-auth';
 
-type Session = { accessToken: string; refreshToken: string };
+type Session = { 
+    accessToken: string
+    refreshToken: string
+};
 
 export const { useAuth, authFetch, login, logout } = createAuthProvider<Session>({
     getAccessToken: session => session.accessToken,
@@ -144,6 +147,35 @@ export const getUser = (userId: string) => (dispatch: Dispatch) => {
 Also if the token already saved in the `localStorage`, it
 will be restored after refreshing the page.
 
+
+### Non-JWT tokens
+By default, the access_token expiration time is determined by the JWT token, but you can provide the expiration time yourself.
+
+For example, the session expiration time can be stored in the session object.
+
+To do this, you just need to override `getExpirationTime` in the configuration:
+```typescript
+import { createAuthProvider } from 'react-token-auth';
+
+type Session = { 
+    accessToken: string
+    refreshToken: string
+    expirationTime: number
+};
+
+export const { useAuth, authFetch, login, logout } = createAuthProvider<Session>({
+    getAccessToken: session => session.accessToken,
+    getExpirationTime: session => session.expirationTime,
+    storage: localStorage,
+    onUpdateToken: token =>
+        fetch('/update-token', {
+            method: 'POST',
+            body: token.refreshToken,
+        }).then(r => r.json()),
+});
+```
+
+
 ## API
 
 ### `createAuthProvider<Session>(config: IAuthProviderConfig<Session>)` -> `IAuthProvider<Session>`
@@ -151,6 +183,7 @@ will be restored after refreshing the page.
 #### `IAuthProviderConfig<Session>`
 
 - `getAccessToken?: (session: Session) => TokenString` - function which allows to extract access token from the whole session object
+- `getExpirationTime?: (session: Session) => Maybe<number>` - function which allows to extract expiration time from the whole session object. Default time from JWT token. 
 - `storageKey?: string = 'REACT_TOKEN_AUTH_KEY'` - key that will be used to store value in local storage
 - `onUpdateToken?: (session: Session) => Promise<Maybe<Session>>` - function to update access token when it is expired
 - `onHydratation?: (session: Maybe<Session>) => void` - function to process your tokens when `useAuth` is called.
@@ -172,6 +205,7 @@ will be restored after refreshing the page.
 #### `IAsyncAuthProviderConfig<Session>`
 
 - `getAccessToken?: (session: Session) => TokenString` - function which allows to extract access token from the whole session object
+- `getExpirationTime?: (session: Session) => Maybe<number>` - function which allows to extract expiration time from the whole session object. Default time from JWT token.
 - `storageKey?: string = 'REACT_TOKEN_AUTH_KEY'` - key that will be used to store value in local storage
 - `onUpdateToken?: (session: Session) => Promise<Maybe<Session>>` - function to update access token when it is expired
 - `onHydratation?: (session: Maybe<Session>) => void` - function to process your tokens when `useAuth` is called.
diff --git a/jest.config.js b/jest.config.js
deleted file mode 100644
index 91a2d2c..0000000
--- a/jest.config.js
+++ /dev/null
@@ -1,4 +0,0 @@
-module.exports = {
-  preset: 'ts-jest',
-  testEnvironment: 'node',
-};
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index e5b35d4..0150367 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,13 +1,18 @@
 {
   "name": "react-token-auth",
-  "version": "1.1.9",
+  "version": "2.4.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "react-token-auth",
-      "version": "1.1.9",
+      "version": "2.4.0",
       "license": "ISC",
+      "dependencies": {
+        "@types/buffer-from": "^1.1.0",
+        "buffer-from": "^1.1.2",
+        "tslog": "^4.7.1"
+      },
       "devDependencies": {
         "@types/jest": "^26.0.24",
         "@types/react": "^16.9.17",
@@ -1261,6 +1266,14 @@
         "@babel/types": "^7.3.0"
       }
     },
+    "node_modules/@types/buffer-from": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@types/buffer-from/-/buffer-from-1.1.0.tgz",
+      "integrity": "sha512-BLFpLBcN+RPKUsFxqRkMiwqTOOdi+TrKr5OpLJ9qCnUdSxS6S80+QRX/mIhfR66u0Ykc4QTkReaejOM2ILh+9Q==",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/graceful-fs": {
       "version": "4.1.5",
       "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
@@ -1307,8 +1320,7 @@
     "node_modules/@types/node": {
       "version": "16.11.4",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz",
-      "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==",
-      "dev": true
+      "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ=="
     },
     "node_modules/@types/normalize-package-data": {
       "version": "2.4.1",
@@ -1837,10 +1849,9 @@
       }
     },
     "node_modules/buffer-from": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
-      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
-      "dev": true
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
     },
     "node_modules/builtin-modules": {
       "version": "1.1.1",
@@ -7294,6 +7305,17 @@
         "mkdirp": "bin/cmd.js"
       }
     },
+    "node_modules/tslog": {
+      "version": "4.7.1",
+      "resolved": "https://registry.npmjs.org/tslog/-/tslog-4.7.1.tgz",
+      "integrity": "sha512-Ez90j4FKCUp9bBlgPq96aYDUbXRIOxz6Vxn/4Iw2/IiVxLB5wsUVkWfeK4oqdRMoW8qBVJz9oIT+ysjfyIRufw==",
+      "engines": {
+        "node": ">=16"
+      },
+      "funding": {
+        "url": "https://github.com/fullstack-build/tslog?sponsor=1"
+      }
+    },
     "node_modules/tsutils": {
       "version": "2.29.0",
       "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
@@ -8713,6 +8735,14 @@
         "@babel/types": "^7.3.0"
       }
     },
+    "@types/buffer-from": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@types/buffer-from/-/buffer-from-1.1.0.tgz",
+      "integrity": "sha512-BLFpLBcN+RPKUsFxqRkMiwqTOOdi+TrKr5OpLJ9qCnUdSxS6S80+QRX/mIhfR66u0Ykc4QTkReaejOM2ILh+9Q==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/graceful-fs": {
       "version": "4.1.5",
       "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
@@ -8759,8 +8789,7 @@
     "@types/node": {
       "version": "16.11.4",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz",
-      "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==",
-      "dev": true
+      "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ=="
     },
     "@types/normalize-package-data": {
       "version": "2.4.1",
@@ -9173,10 +9202,9 @@
       }
     },
     "buffer-from": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
-      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
-      "dev": true
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
     },
     "builtin-modules": {
       "version": "1.1.1",
@@ -13392,6 +13420,11 @@
       "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==",
       "dev": true
     },
+    "tslog": {
+      "version": "4.7.1",
+      "resolved": "https://registry.npmjs.org/tslog/-/tslog-4.7.1.tgz",
+      "integrity": "sha512-Ez90j4FKCUp9bBlgPq96aYDUbXRIOxz6Vxn/4Iw2/IiVxLB5wsUVkWfeK4oqdRMoW8qBVJz9oIT+ysjfyIRufw=="
+    },
     "tsutils": {
       "version": "2.29.0",
       "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
diff --git a/package.json b/package.json
index 4684659..170d273 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "react-token-auth",
-  "version": "2.3.8",
+  "version": "2.4.0",
   "description": "React Token Auth",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
@@ -40,5 +40,10 @@
   },
   "files": [
     "lib/**/*"
-  ]
+  ],
+  "dependencies": {
+    "@types/buffer-from": "^1.1.0",
+    "buffer-from": "^1.1.2",
+    "tslog": "^4.7.1"
+  }
 }
diff --git a/src/__tests__/isTokenExpired.test.ts b/src/__tests__/isTokenExpired.test.ts
index 799d1a8..429c8f5 100644
--- a/src/__tests__/isTokenExpired.test.ts
+++ b/src/__tests__/isTokenExpired.test.ts
@@ -1,34 +1,52 @@
-import { isTokenExpired } from '../isTokenExpired';
+import { isTokenExpired, jwtExp } from '../isTokenExpired';
 import { createJWTTokenWithExp, getExpiredJWTToken, getNonExpiredJWTToken } from '../test-utils/jwt';
 
-describe('isTokenExpired', () => {
+describe('isTokenExpired-jwt', () => {
     it('expired token', () => {
         const token = getExpiredJWTToken();
 
-        expect(isTokenExpired(token)).toBeTruthy();
+        expect(isTokenExpired(jwtExp(token))).toBeTruthy();
     });
 
     it('valid token', () => {
         const token = getNonExpiredJWTToken();
 
-        expect(isTokenExpired(token)).toBeFalsy();
+        expect(isTokenExpired(jwtExp(token))).toBeFalsy();
     });
 
     it('token expires in 1 second', () => {
         const token = createJWTTokenWithExp(Math.floor(Date.now() / 1000) + 1);
 
-        expect(isTokenExpired(token, 5000)).toBeTruthy();
+        expect(isTokenExpired(jwtExp(token), 5000)).toBeTruthy();
     });
 
     it('token expired 1 second ago', () => {
         const token = createJWTTokenWithExp(Math.floor(Date.now() / 1000) - 1);
 
-        expect(isTokenExpired(token, 5000)).toBeTruthy();
+        expect(isTokenExpired(jwtExp(token), 5000)).toBeTruthy();
     });
 
     it('hardcoded token is expired', () => {
         const token =
             'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6IkpzYWRrZmphZGpraGZAcXdlcXdlcyIsInN1YiI6IjE1IiwiaWF0IjoxNjM3NzUxMjM5LCJleHAiOjE2Mzc3NTEyOTl9.ZjcVgbVvoZrIZHzjIckYgFwY5rnlyxlHGvGNHg_CRRk';
-        expect(isTokenExpired(token, 5000)).toBeTruthy();
+        expect(isTokenExpired(jwtExp(token), 5000)).toBeTruthy();
+    });
+});
+
+describe('isTokenExpired-custom-time', () => {
+    it('expired token', () => {
+        expect(isTokenExpired(1000)).toBeTruthy();
+    });
+
+    it('valid token', () => {
+        expect(isTokenExpired(Date.now() + 5000 * 1000)).toBeFalsy();
+    });
+
+    it('token expires in 1 second', () => {
+        expect(isTokenExpired(Date.now() + 1, 5000)).toBeTruthy();
+    });
+
+    it('token expired 1 second ago', () => {
+        expect(isTokenExpired(Date.now() - 1, 5000)).toBeTruthy();
     });
 });
diff --git a/src/createAsyncAuthProvider.ts b/src/createAsyncAuthProvider.ts
index be38003..9860543 100644
--- a/src/createAsyncAuthProvider.ts
+++ b/src/createAsyncAuthProvider.ts
@@ -1,6 +1,6 @@
 import { createListenersContainer } from './createListenersContainer';
 import { createAsyncTokenProvider } from './createTokenProvider';
-import { isTokenExpired } from './isTokenExpired';
+import { isTokenExpired, jwtExp } from './isTokenExpired';
 import { createLogger } from './logger';
 import { createTokenUpdater } from './tokenUpdater';
 import { Getter, IAsyncAuthStorage, Maybe, TokenString } from './types';
@@ -11,6 +11,7 @@ import { extractAccessToken } from './utils/extractAccessToken';
 
 export interface IAsyncAuthProviderConfig<Session> {
     getAccessToken?: (session: Session) => TokenString;
+    getExpirationTime?: (session: Session) => Maybe<number>;
     storageKey?: string;
     onUpdateToken?: (session: Session) => Promise<Maybe<Session>>;
     onHydratation?: (session: Maybe<Session>) => void;
@@ -39,6 +40,7 @@ export const createAsyncAuthProvider = <Session>({
     getAccessToken,
     expirationThresholdMillisec = 5000,
     debug = false,
+    getExpirationTime,
 }: IAsyncAuthProviderConfig<Session>): IAsyncAuthProvider<Session> => {
     const logger = createLogger(debug);
     const listenersContainer = createListenersContainer();
@@ -52,7 +54,7 @@ export const createAsyncAuthProvider = <Session>({
 
     let _session: Maybe<Session> = null;
     const updateSession = async (session: Maybe<Session>) => {
-        logger.log('updateSession', 'session', session);
+        logger?.debug('updateSession', 'session', session);
         await tokenProvider.setToken(session);
         _session = session;
         listenersContainer.notify();
@@ -64,8 +66,7 @@ export const createAsyncAuthProvider = <Session>({
         .then(() => {
             initiationPromise = null;
         })
-        // tslint:disable-next-line:no-console
-        .catch(console.error);
+        .catch(logger?.warn);
 
     const waitInit = () => initiationPromise;
 
@@ -77,20 +78,23 @@ export const createAsyncAuthProvider = <Session>({
 
     const getSession = async () => {
         const accessToken = extractAccessToken(getSessionState(), getAccessToken);
-        logger.log('getSession', 'accessToken', accessToken);
-        logger.log('getSession', 'tokenUpdater', tokenUpdater);
-        if (accessToken) {
-            logger.log(
+        logger?.debug('getSession', 'accessToken', accessToken);
+        logger?.debug('getSession', 'tokenUpdater', tokenUpdater);
+        if (_session && accessToken) {
+            const getExpTime = getExpirationTime || (() => jwtExp(accessToken));
+            logger?.debug(
                 'getSession',
-                'isTokenExpired(accessToken, expirationThresholdMillisec)',
-                isTokenExpired(accessToken, expirationThresholdMillisec, logger),
+                'isTokenExpired(getExpTime(_session), expirationThresholdMillisec)',
+                isTokenExpired(getExpTime(_session), expirationThresholdMillisec, logger),
             );
-        }
 
-        if (_session && tokenUpdater && accessToken && isTokenExpired(accessToken, expirationThresholdMillisec)) {
-            const updatedSession = await tokenUpdater.updateToken(_session);
-            logger.log('getSession', 'updatedSession', accessToken);
-            await updateSession(updatedSession);
+            if (tokenUpdater) {
+                if (isTokenExpired(getExpTime(_session), expirationThresholdMillisec)) {
+                    const updatedSession = await tokenUpdater.updateToken(_session);
+                    logger?.debug('getSession', 'updatedSession', accessToken);
+                    await updateSession(updatedSession);
+                }
+            }
         }
 
         return getSessionState();
diff --git a/src/createAuthProvider.ts b/src/createAuthProvider.ts
index dc8629b..25411ca 100644
--- a/src/createAuthProvider.ts
+++ b/src/createAuthProvider.ts
@@ -1,6 +1,6 @@
 import { createListenersContainer } from './createListenersContainer';
 import { createTokenProvider } from './createTokenProvider';
-import { isTokenExpired } from './isTokenExpired';
+import { isTokenExpired, jwtExp } from './isTokenExpired';
 import { createTokenUpdater } from './tokenUpdater';
 import { Getter, IAuthStorage, Maybe, TokenString } from './types';
 import { createUseAuth } from './useAuth';
@@ -10,6 +10,7 @@ import { extractAccessToken } from './utils/extractAccessToken';
 
 export interface IAuthProviderConfig<Session> {
     getAccessToken?: (session: Session) => TokenString;
+    getExpirationTime?: (session: Session) => Maybe<number>;
     storageKey?: string;
     onUpdateToken?: (session: Session) => Promise<Maybe<Session>>;
     onHydratation?: (session: Maybe<Session>) => void;
@@ -35,6 +36,7 @@ export const createAuthProvider = <Session>({
     fetchFunction = fetch,
     getAccessToken,
     expirationThresholdMillisec = 5000,
+    getExpirationTime,
 }: IAuthProviderConfig<Session>): IAuthProvider<Session> => {
     const listenersContainer = createListenersContainer();
     const tokenProvider = createTokenProvider<Session>({
@@ -60,9 +62,12 @@ export const createAuthProvider = <Session>({
     const getSession = async () => {
         const accessToken = extractAccessToken(getSessionState(), getAccessToken);
 
-        if (_session && tokenUpdater && accessToken && isTokenExpired(accessToken, expirationThresholdMillisec)) {
-            const updatedSession = await tokenUpdater.updateToken(_session);
-            updateSession(updatedSession);
+        if (_session && tokenUpdater && accessToken) {
+            const getExpTime = getExpirationTime || (() => jwtExp(accessToken));
+            if (isTokenExpired(getExpTime(_session), expirationThresholdMillisec)) {
+                const updatedSession = await tokenUpdater.updateToken(_session);
+                updateSession(updatedSession);
+            }
         }
 
         return getSessionState();
diff --git a/src/isTokenExpired.ts b/src/isTokenExpired.ts
index 3246545..60fdf52 100644
--- a/src/isTokenExpired.ts
+++ b/src/isTokenExpired.ts
@@ -1,42 +1,38 @@
-import { SimpleLogger } from './logger';
-import { Maybe, TokenString } from './types';
-import { Base64 } from './utils/base64';
+import { Maybe } from './types';
+import {Logger} from "tslog";
+import bufferFrom from 'buffer-from';
 
-export const isTokenExpired = (token: TokenString, thresholdMillisec?: number, logger?: SimpleLogger) =>
-    isTimestampExpired(jwtExp(token, logger), thresholdMillisec, logger);
+export const isTokenExpired = (exp: Maybe<number>, thresholdMillisec?: number, logger?: Logger<any>) => {
+    logger?.debug('isTokenExpired', 'exp', exp);
+    if (!exp) {
+        return false;
+    }
 
-const jwtExp = (token: string, logger?: SimpleLogger): number | null => {
+    logger?.debug('isTokenExpired', 'Date.now()', Date.now());
+    logger?.debug('isTokenExpired', '(thresholdMillisec ?? 0', thresholdMillisec ?? 0);
+    return Date.now() > exp - (thresholdMillisec ?? 0);
+};
+
+export const jwtExp = (token: string, logger?: Logger<any>): number | null => {
     const split = token.split('.');
-    logger?.log('jwtExp', 'split', split);
+    logger?.debug('jwtExp', 'split', split);
 
     if (split.length < 2) {
         return null;
     }
 
     try {
-        const middlePart = Base64.decode(token.split('.')[1]);
-        logger?.log('jwtExp', 'middlePart', middlePart);
+        const middlePart = bufferFrom(token.split('.')[1], 'base64').toString();
+        logger?.debug('jwtExp', 'middlePart', middlePart);
         const jwt = JSON.parse(middlePart);
-        logger?.log('jwtExp', 'jwt', jwt);
+        logger?.debug('jwtExp', 'jwt', jwt);
         if (jwt && jwt.exp && Number.isFinite(jwt.exp)) {
             return jwt.exp * 1000;
         } else {
             return null;
         }
     } catch (e) {
-        // tslint:disable-next-line:no-console
-        console.warn(e);
+        logger?.warn(e);
         return null;
     }
 };
-
-const isTimestampExpired = (exp: Maybe<number>, thresholdMillisec?: number, logger?: SimpleLogger) => {
-    logger?.log('isTimestampExpired', 'exp', exp);
-    if (!exp) {
-        return false;
-    }
-
-    logger?.log('isTimestampExpired', 'Date.now()', Date.now());
-    logger?.log('isTimestampExpired', '(thresholdMillisec ?? 0', thresholdMillisec ?? 0);
-    return Date.now() > exp - (thresholdMillisec ?? 0);
-};
diff --git a/src/logger.ts b/src/logger.ts
index ca59a79..ce221f0 100644
--- a/src/logger.ts
+++ b/src/logger.ts
@@ -1,15 +1,11 @@
-export interface SimpleLogger {
-    log: (name: string, message: string, ...objs: any[]) => void;
-}
+import {Logger} from "tslog";
 
-export const createLogger = (debug?: boolean): SimpleLogger => {
-    const log = (name: string, message: string, ...objs: any[]) => {
-        if (debug) {
-            // tslint:disable-next-line:no-console
-            console.log(`[react-token-auth]${name}::${message}`, ...objs.map((it) => JSON.stringify(it)));
-        }
-    };
-    return {
-        log,
-    };
+export const createLogger = (debug?: boolean): Logger<any>|undefined => {
+    if(debug) {
+        return new Logger({
+            name: "react-token-auth"
+        });
+    }
+
+    return undefined
 };
diff --git a/src/utils/base64.d.ts b/src/utils/base64.d.ts
deleted file mode 100644
index 514fc31..0000000
--- a/src/utils/base64.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const Base64: { decode: (input: string) => string };
diff --git a/src/utils/base64.js b/src/utils/base64.js
deleted file mode 100644
index 15f4c1e..0000000
--- a/src/utils/base64.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-
-/**
- * Base64 encode / decode
- * http://www.webtoolkit.info/
- **/
-var Base64 = {
-    // private property
-    _keyStr: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
-
-    // public method for encoding
-    encode: function (input) {
-        var output = '';
-        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
-        var i = 0;
-
-        input = Base64._utf8_encode(input);
-
-        while (i < input.length) {
-            chr1 = input.charCodeAt(i++);
-            chr2 = input.charCodeAt(i++);
-            chr3 = input.charCodeAt(i++);
-
-            enc1 = chr1 >> 2;
-            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
-            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
-            enc4 = chr3 & 63;
-
-            if (isNaN(chr2)) {
-                enc3 = enc4 = 64;
-            } else if (isNaN(chr3)) {
-                enc4 = 64;
-            }
-
-            output =
-                output +
-                this._keyStr.charAt(enc1) +
-                this._keyStr.charAt(enc2) +
-                this._keyStr.charAt(enc3) +
-                this._keyStr.charAt(enc4);
-        }
-        return output;
-    },
-
-    // public method for decoding
-    decode: function (input) {
-        var output = '';
-        var chr1, chr2, chr3;
-        var enc1, enc2, enc3, enc4;
-        var i = 0;
-
-        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
-
-        while (i < input.length) {
-            enc1 = this._keyStr.indexOf(input.charAt(i++));
-            enc2 = this._keyStr.indexOf(input.charAt(i++));
-            enc3 = this._keyStr.indexOf(input.charAt(i++));
-            enc4 = this._keyStr.indexOf(input.charAt(i++));
-
-            chr1 = (enc1 << 2) | (enc2 >> 4);
-            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
-            chr3 = ((enc3 & 3) << 6) | enc4;
-
-            output = output + String.fromCharCode(chr1);
-
-            if (enc3 != 64) {
-                output = output + String.fromCharCode(chr2);
-            }
-            if (enc4 != 64) {
-                output = output + String.fromCharCode(chr3);
-            }
-        }
-
-        output = Base64._utf8_decode(output);
-
-        return output;
-    },
-
-    // private method for UTF-8 encoding
-    _utf8_encode: function (string) {
-        string = string.replace(/\r\n/g, '\n');
-        var utftext = '';
-
-        for (var n = 0; n < string.length; n++) {
-            var c = string.charCodeAt(n);
-
-            if (c < 128) {
-                utftext += String.fromCharCode(c);
-            } else if (c > 127 && c < 2048) {
-                utftext += String.fromCharCode((c >> 6) | 192);
-                utftext += String.fromCharCode((c & 63) | 128);
-            } else {
-                utftext += String.fromCharCode((c >> 12) | 224);
-                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
-                utftext += String.fromCharCode((c & 63) | 128);
-            }
-        }
-        return utftext;
-    },
-
-    // private method for UTF-8 decoding
-    _utf8_decode: function (utftext) {
-        var string = '';
-        var i = 0;
-        var c1 = 0;
-        var c2 = 0;
-        var c = 0;
-
-        while (i < utftext.length) {
-            c = utftext.charCodeAt(i);
-
-            if (c < 128) {
-                string += String.fromCharCode(c);
-                i++;
-            } else if (c > 191 && c < 224) {
-                c2 = utftext.charCodeAt(i + 1);
-                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
-                i += 2;
-            } else {
-                c2 = utftext.charCodeAt(i + 1);
-                c3 = utftext.charCodeAt(i + 2);
-                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
-                i += 3;
-            }
-        }
-        return string;
-    },
-};
-
-module.exports = { Base64 };
diff --git a/tsconfig.json b/tsconfig.json
index 235aefc..272363e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -6,6 +6,7 @@
         "outDir": "./lib",
         "strict": true,
         "allowJs": true,
+        "esModuleInterop": true,
         "lib": ["dom", "es6"]
     },
     "include": ["src"],
diff --git a/tslint.json b/tslint.json
index a8571f3..2e64f96 100644
--- a/tslint.json
+++ b/tslint.json
@@ -1,3 +1,6 @@
 {
-    "extends": ["tslint:recommended", "tslint-config-prettier"]
+    "extends": ["tslint:recommended", "tslint-config-prettier"],
+    "rules": {
+        "no-console": true
+    }
 }