From 952f1cf8d03c68b83c614508f3b54801949b368d Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Mon, 12 Mar 2018 15:22:04 +0100
Subject: Use `isMetaMask` flag rather then constructor name for Metamask
 provider detection

---
 packages/website/ts/utils/utils.ts | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts
index 5fcd3f8e5..abb2598c3 100644
--- a/packages/website/ts/utils/utils.ts
+++ b/packages/website/ts/utils/utils.ts
@@ -281,10 +281,6 @@ export const utils = {
         const constructorName = provider.constructor.name;
         let parsedProviderName = constructorName;
         switch (constructorName) {
-            case 'MetamaskInpageProvider':
-                parsedProviderName = Providers.Metamask;
-                break;
-
             case 'EthereumProvider':
                 parsedProviderName = Providers.Mist;
                 break;
@@ -295,6 +291,8 @@ export const utils = {
         }
         if ((provider as any).isParity) {
             parsedProviderName = Providers.Parity;
+        } else if ((provider as any).isMetaMask) {
+            parsedProviderName = Providers.Metamask;
         }
         return parsedProviderName;
     },
-- 
cgit v1.2.3


From 745af5309d32a34e5f8c6a305f12ce31cb2379b1 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Mon, 12 Mar 2018 16:04:01 +0100
Subject: Add missing prettier devDep

---
 packages/0x.js/package.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json
index 4a4d6d2c8..53ddfd258 100644
--- a/packages/0x.js/package.json
+++ b/packages/0x.js/package.json
@@ -66,6 +66,7 @@
         "npm-run-all": "^4.1.2",
         "nyc": "^11.0.1",
         "opn-cli": "^3.1.0",
+        "prettier": "^1.11.1",
         "request": "^2.81.0",
         "request-promise-native": "^1.0.5",
         "shx": "^0.2.2",
-- 
cgit v1.2.3


From ef6aa9f41b9f21d033034c51e8880ec9d70b6b40 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Mon, 12 Mar 2018 22:13:24 +0100
Subject: Convert 0x.js scripts to TS, move the prepublishUtils script to
 `dev-utils` and also convert it to TS.

---
 .gitignore                                     |  3 +
 package.json                                   |  6 +-
 packages/0x.js/monorepo_scripts/globals.d.ts   | 12 ++++
 packages/0x.js/monorepo_scripts/postpublish.ts | 44 +++++++++++++
 packages/0x.js/monorepo_scripts/stagedocs.ts   | 30 +++++++++
 packages/0x.js/package.json                    |  3 +-
 packages/0x.js/tsconfig_monorepo.json          |  9 +++
 packages/dev-utils/CHANGELOG.md                |  4 ++
 packages/dev-utils/package.json                |  2 +
 packages/dev-utils/src/globals.d.ts            |  7 +++
 packages/dev-utils/src/index.ts                |  1 +
 packages/dev-utils/src/postpublish_utils.ts    | 86 ++++++++++++++++++++++++++
 packages/dev-utils/src/utils.ts                |  5 ++
 13 files changed, 206 insertions(+), 6 deletions(-)
 create mode 100644 packages/0x.js/monorepo_scripts/globals.d.ts
 create mode 100644 packages/0x.js/monorepo_scripts/postpublish.ts
 create mode 100644 packages/0x.js/monorepo_scripts/stagedocs.ts
 create mode 100644 packages/0x.js/tsconfig_monorepo.json
 create mode 100644 packages/dev-utils/src/postpublish_utils.ts
 create mode 100644 packages/dev-utils/src/utils.ts

diff --git a/.gitignore b/.gitignore
index 7d27493cc..c5de0f498 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,3 +75,6 @@ bin/
 
 # generated contract artifacts
 packages/contracts/src/artifacts
+
+# Monorepo scripts
+packages/0x.js/scripts
diff --git a/package.json b/package.json
index b8ce29c4a..b1e1bf626 100644
--- a/package.json
+++ b/package.json
@@ -16,12 +16,8 @@
         "mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
     },
     "devDependencies": {
-        "@0xproject/utils": "^0.4.1",
-        "async-child-process": "^1.1.1",
         "ethereumjs-testrpc": "^6.0.3",
         "lerna": "^2.5.1",
-        "prettier": "^1.11.1",
-        "publish-release": "0xproject/publish-release",
-        "semver-sort": "^0.0.4"
+        "prettier": "^1.11.1"
     }
 }
diff --git a/packages/0x.js/monorepo_scripts/globals.d.ts b/packages/0x.js/monorepo_scripts/globals.d.ts
new file mode 100644
index 000000000..bbfbdaa6a
--- /dev/null
+++ b/packages/0x.js/monorepo_scripts/globals.d.ts
@@ -0,0 +1,12 @@
+declare module 'async-child-process';
+declare module 'publish-release';
+
+// semver-sort declarations
+declare module 'semver-sort' {
+    const desc: (versions: string[]) => string[];
+}
+
+declare module '*.json' {
+    const value: any;
+    export default value;
+}
diff --git a/packages/0x.js/monorepo_scripts/postpublish.ts b/packages/0x.js/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..13ab013be
--- /dev/null
+++ b/packages/0x.js/monorepo_scripts/postpublish.ts
@@ -0,0 +1,44 @@
+import { postpublishUtils } from '@0xproject/dev-utils';
+import { execAsync } from 'async-child-process';
+import * as _ from 'lodash';
+
+import * as packageJSON from '../package.json';
+import * as tsConfig from '../tsconfig.json';
+
+const cwd = `${__dirname}/..`;
+const subPackageName = (packageJSON as any).name;
+// Include any external packages that are part of the 0x.js public interface
+// to this array so that TypeDoc picks it up and adds it to the Docs JSON
+// So far, we only have @0xproject/types as part of 0x.js's public interface.
+const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts'];
+const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
+const projectFiles = fileIncludesAdjusted.join(' ');
+const S3BucketPath = 's3://0xjs-docs-jsons/';
+
+(async () => {
+    const tagAndVersion = await postpublishUtils.getLatestTagAndVersionAsync(subPackageName);
+    const tag = tagAndVersion.tag;
+    const version = tagAndVersion.version;
+
+    const releaseName = postpublishUtils.getReleaseName(subPackageName, version);
+    const assets = [`${__dirname}/../_bundles/index.js`, `${__dirname}/../_bundles/index.min.js`];
+    const release = await postpublishUtils.publishReleaseNotesAsync(tag, releaseName, assets);
+
+    // tslint:disable-next-line:no-console
+    console.log('POSTPUBLISH: Release successful, generating docs...');
+    const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
+
+    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
+        cwd,
+    });
+    if (!_.isEmpty(result.stderr)) {
+        throw new Error(result.stderr);
+    }
+    const fileName = `v${version}.json`;
+    // tslint:disable-next-line:no-console
+    console.log(`POSTPUBLISH: Doc generation successful, uploading docs... as ${fileName}`);
+    const s3Url = S3BucketPath + fileName;
+    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
+        cwd,
+    });
+})().catch(console.error);
diff --git a/packages/0x.js/monorepo_scripts/stagedocs.ts b/packages/0x.js/monorepo_scripts/stagedocs.ts
new file mode 100644
index 000000000..a62d8a014
--- /dev/null
+++ b/packages/0x.js/monorepo_scripts/stagedocs.ts
@@ -0,0 +1,30 @@
+import { postpublishUtils } from '@0xproject/dev-utils';
+import { execAsync } from 'async-child-process';
+import * as _ from 'lodash';
+
+import * as tsConfig from '../tsconfig.json';
+
+const cwd = __dirname + '/..';
+const S3BucketPath = 's3://staging-0xjs-docs-jsons/';
+// Include any external packages that are part of the 0x.js public interface
+// to this array so that TypeDoc picks it up and adds it to the Docs JSON
+// So far, we only have @0xproject/types as part of 0x.js's public interface.
+const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts'];
+const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
+const projectFiles = fileIncludesAdjusted.join(' ');
+const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
+const version = process.env.DOCS_VERSION;
+
+(async () => {
+    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
+        cwd,
+    });
+    if (!_.isEmpty(result.stderr)) {
+        throw new Error(result.stderr);
+    }
+    const fileName = `v${version}.json`;
+    const s3Url = S3BucketPath + fileName;
+    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
+        cwd,
+    });
+})().catch(console.error);
diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json
index 53ddfd258..54f9ba1ad 100644
--- a/packages/0x.js/package.json
+++ b/packages/0x.js/package.json
@@ -14,7 +14,7 @@
     "scripts": {
         "build:watch": "tsc -w",
         "prebuild": "run-s clean generate_contract_wrappers",
-        "build": "run-p build:umd:prod build:commonjs; exit 0;",
+        "build": "run-p build:scripts build:umd:prod build:commonjs; exit 0;",
         "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES",
         "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
         "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'",
@@ -27,6 +27,7 @@
         "clean": "shx rm -rf _bundles lib test_temp",
         "build:umd:prod": "NODE_ENV=production webpack",
         "build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts;",
+        "build:scripts": "tsc --p ./tsconfig_monorepo.json",
         "test:commonjs": "run-s build:commonjs run_mocha",
         "run_mocha": "mocha lib/test/**/*_test.js --timeout 10000 --bail --exit"
     },
diff --git a/packages/0x.js/tsconfig_monorepo.json b/packages/0x.js/tsconfig_monorepo.json
new file mode 100644
index 000000000..7e9609659
--- /dev/null
+++ b/packages/0x.js/tsconfig_monorepo.json
@@ -0,0 +1,9 @@
+{
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "scripts",
+        "noImplicitThis": false,
+        "rootDir": "./monorepo_scripts"
+    },
+    "include": ["./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+}
diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md
index ecc5546ae..6840a6a69 100644
--- a/packages/dev-utils/CHANGELOG.md
+++ b/packages/dev-utils/CHANGELOG.md
@@ -1,5 +1,9 @@
 # CHANGELOG
 
+## v0.2.1 - _TBD_
+
+    * Add postpublish utils
+
 ## v0.2.0 - _February 16, 2018_
 
     * Remove subproviders (#392)
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
index fbbcb182f..491ebd95f 100644
--- a/packages/dev-utils/package.json
+++ b/packages/dev-utils/package.json
@@ -43,7 +43,9 @@
         "@0xproject/utils": "^0.4.1",
         "ethereumjs-util": "^5.1.2",
         "lodash": "^4.17.4",
+        "publish-release": "0xproject/publish-release",
         "request-promise-native": "^1.0.5",
+        "semver-sort": "^0.0.4",
         "web3": "^0.20.0",
         "web3-provider-engine": "^13.0.1"
     },
diff --git a/packages/dev-utils/src/globals.d.ts b/packages/dev-utils/src/globals.d.ts
index 7b132ee28..9c8a1dc02 100644
--- a/packages/dev-utils/src/globals.d.ts
+++ b/packages/dev-utils/src/globals.d.ts
@@ -1,2 +1,9 @@
 declare module 'web3-provider-engine';
 declare module 'web3-provider-engine/subproviders/rpc';
+declare module 'async-child-process';
+declare module 'publish-release';
+
+// semver-sort declarations
+declare module 'semver-sort' {
+    const desc: (versions: string[]) => string[];
+}
diff --git a/packages/dev-utils/src/index.ts b/packages/dev-utils/src/index.ts
index e899ac206..cc3e668a1 100644
--- a/packages/dev-utils/src/index.ts
+++ b/packages/dev-utils/src/index.ts
@@ -2,3 +2,4 @@ export { RPC } from './rpc';
 export { BlockchainLifecycle } from './blockchain_lifecycle';
 export { web3Factory } from './web3_factory';
 export { constants as devConstants } from './constants';
+export { postpublishUtils } from './postpublish_utils';
diff --git a/packages/dev-utils/src/postpublish_utils.ts b/packages/dev-utils/src/postpublish_utils.ts
new file mode 100644
index 000000000..35d046e26
--- /dev/null
+++ b/packages/dev-utils/src/postpublish_utils.ts
@@ -0,0 +1,86 @@
+import { promisify } from '@0xproject/utils';
+import { execAsync } from 'async-child-process';
+import * as _ from 'lodash';
+import * as publishRelease from 'publish-release';
+import semverSort = require('semver-sort');
+
+import { utils } from './utils';
+
+const publishReleaseAsync = promisify(publishRelease);
+const githubPersonalAccessToken = process.env.GITHUB_PERSONAL_ACCESS_TOKEN_0X_JS;
+const generatedDocsDirectoryName = 'generated_docs';
+
+export interface TagAndVersion {
+    tag: string;
+    version: string;
+}
+
+export const postpublishUtils = {
+    getLatestTagAndVersionAsync(subPackageName: string): Promise<TagAndVersion> {
+        const subPackagePrefix = `${subPackageName}@`;
+        const gitTagsCommand = `git tag -l "${subPackagePrefix}*"`;
+        return execAsync(gitTagsCommand).then((result: any) => {
+            if (!_.isEmpty(result.stderr)) {
+                throw new Error(result.stderr);
+            }
+            const tags = result.stdout.trim().split('\n');
+            const versions = tags.map((tag: string) => {
+                return tag.slice(subPackagePrefix.length);
+            });
+            const sortedVersions = semverSort.desc(versions);
+            const latestVersion = sortedVersions[0];
+            const latestTag = subPackagePrefix + latestVersion;
+            return {
+                tag: latestTag,
+                version: latestVersion,
+            };
+        });
+    },
+    publishReleaseNotesAsync(tag: string, releaseName: string, assets: string[]) {
+        utils.log('POSTPUBLISH: Releasing ', releaseName, '...');
+        return publishReleaseAsync({
+            token: githubPersonalAccessToken,
+            owner: '0xProject',
+            repo: '0x.js',
+            tag,
+            name: releaseName,
+            notes: 'N/A',
+            draft: false,
+            prerelease: false,
+            reuseRelease: true,
+            reuseDraftOnly: false,
+            assets,
+        });
+    },
+    getReleaseName(subPackageName: string, version: string): string {
+        const releaseName = `${subPackageName} v${version}`;
+        return releaseName;
+    },
+    async standardPostPublishAsync(subPackageName: string): Promise<void> {
+        const result: TagAndVersion = await this.getLatestTagAndVersionAsync(subPackageName);
+        const releaseName = this.getReleaseName(subPackageName, result.version);
+        const assets: string[] = [];
+        await this.publishReleaseNotesAsync(result.tag, releaseName, assets);
+    },
+    adjustFileIncludePaths(fileIncludes: string[], cwd: string): string[] {
+        const fileIncludesAdjusted = _.map(fileIncludes, fileInclude => {
+            let path;
+            if (_.startsWith(fileInclude, '../')) {
+                path = `${cwd}/../${fileInclude}`;
+            } else if (_.startsWith(fileInclude, './')) {
+                path = `${cwd}/../${fileInclude.substr(2)}`;
+            } else {
+                path = `${cwd}/${fileInclude}`;
+            }
+
+            // HACK: tsconfig.json needs wildcard directory endings as `/**/*`
+            // but TypeDoc needs it as `/**` in order to pick up files at the root
+            if (_.endsWith(path, '/**/*')) {
+                path = path.slice(0, -2);
+            }
+            return path;
+        });
+        return fileIncludesAdjusted;
+    },
+    generatedDocsDirectoryName,
+};
diff --git a/packages/dev-utils/src/utils.ts b/packages/dev-utils/src/utils.ts
new file mode 100644
index 000000000..5423cabd9
--- /dev/null
+++ b/packages/dev-utils/src/utils.ts
@@ -0,0 +1,5 @@
+export const utils = {
+    log(...args: any[]): void {
+        console.log(...args); // tslint:disable-line:no-console
+    },
+};
-- 
cgit v1.2.3


From 7ac646ff94bfa996abab6fca5000a06acb66a898 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 10:25:10 +0100
Subject: Move monorepo_scripts into src dir removing the need for a separate
 globals.d.ts and tsconfig files

---
 packages/0x.js/monorepo_scripts/globals.d.ts       | 12 ---
 packages/0x.js/monorepo_scripts/postpublish.ts     | 44 -----------
 packages/0x.js/monorepo_scripts/stagedocs.ts       | 30 --------
 packages/0x.js/package.json                        |  5 +-
 packages/0x.js/scripts/postpublish.js              | 47 ------------
 packages/0x.js/scripts/stagedocs.js                | 31 --------
 packages/0x.js/src/globals.d.ts                    |  7 ++
 packages/0x.js/src/monorepo_scripts/postpublish.ts | 44 +++++++++++
 packages/0x.js/src/monorepo_scripts/stagedocs.ts   | 30 ++++++++
 packages/0x.js/tsconfig_monorepo.json              |  9 ---
 scripts/postpublish_utils.js                       | 86 ----------------------
 11 files changed, 83 insertions(+), 262 deletions(-)
 delete mode 100644 packages/0x.js/monorepo_scripts/globals.d.ts
 delete mode 100644 packages/0x.js/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/0x.js/monorepo_scripts/stagedocs.ts
 delete mode 100644 packages/0x.js/scripts/postpublish.js
 delete mode 100644 packages/0x.js/scripts/stagedocs.js
 create mode 100644 packages/0x.js/src/monorepo_scripts/postpublish.ts
 create mode 100644 packages/0x.js/src/monorepo_scripts/stagedocs.ts
 delete mode 100644 packages/0x.js/tsconfig_monorepo.json
 delete mode 100644 scripts/postpublish_utils.js

diff --git a/packages/0x.js/monorepo_scripts/globals.d.ts b/packages/0x.js/monorepo_scripts/globals.d.ts
deleted file mode 100644
index bbfbdaa6a..000000000
--- a/packages/0x.js/monorepo_scripts/globals.d.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-declare module 'async-child-process';
-declare module 'publish-release';
-
-// semver-sort declarations
-declare module 'semver-sort' {
-    const desc: (versions: string[]) => string[];
-}
-
-declare module '*.json' {
-    const value: any;
-    export default value;
-}
diff --git a/packages/0x.js/monorepo_scripts/postpublish.ts b/packages/0x.js/monorepo_scripts/postpublish.ts
deleted file mode 100644
index 13ab013be..000000000
--- a/packages/0x.js/monorepo_scripts/postpublish.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { postpublishUtils } from '@0xproject/dev-utils';
-import { execAsync } from 'async-child-process';
-import * as _ from 'lodash';
-
-import * as packageJSON from '../package.json';
-import * as tsConfig from '../tsconfig.json';
-
-const cwd = `${__dirname}/..`;
-const subPackageName = (packageJSON as any).name;
-// Include any external packages that are part of the 0x.js public interface
-// to this array so that TypeDoc picks it up and adds it to the Docs JSON
-// So far, we only have @0xproject/types as part of 0x.js's public interface.
-const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts'];
-const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
-const projectFiles = fileIncludesAdjusted.join(' ');
-const S3BucketPath = 's3://0xjs-docs-jsons/';
-
-(async () => {
-    const tagAndVersion = await postpublishUtils.getLatestTagAndVersionAsync(subPackageName);
-    const tag = tagAndVersion.tag;
-    const version = tagAndVersion.version;
-
-    const releaseName = postpublishUtils.getReleaseName(subPackageName, version);
-    const assets = [`${__dirname}/../_bundles/index.js`, `${__dirname}/../_bundles/index.min.js`];
-    const release = await postpublishUtils.publishReleaseNotesAsync(tag, releaseName, assets);
-
-    // tslint:disable-next-line:no-console
-    console.log('POSTPUBLISH: Release successful, generating docs...');
-    const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
-
-    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
-        cwd,
-    });
-    if (!_.isEmpty(result.stderr)) {
-        throw new Error(result.stderr);
-    }
-    const fileName = `v${version}.json`;
-    // tslint:disable-next-line:no-console
-    console.log(`POSTPUBLISH: Doc generation successful, uploading docs... as ${fileName}`);
-    const s3Url = S3BucketPath + fileName;
-    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
-        cwd,
-    });
-})().catch(console.error);
diff --git a/packages/0x.js/monorepo_scripts/stagedocs.ts b/packages/0x.js/monorepo_scripts/stagedocs.ts
deleted file mode 100644
index a62d8a014..000000000
--- a/packages/0x.js/monorepo_scripts/stagedocs.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { postpublishUtils } from '@0xproject/dev-utils';
-import { execAsync } from 'async-child-process';
-import * as _ from 'lodash';
-
-import * as tsConfig from '../tsconfig.json';
-
-const cwd = __dirname + '/..';
-const S3BucketPath = 's3://staging-0xjs-docs-jsons/';
-// Include any external packages that are part of the 0x.js public interface
-// to this array so that TypeDoc picks it up and adds it to the Docs JSON
-// So far, we only have @0xproject/types as part of 0x.js's public interface.
-const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts'];
-const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
-const projectFiles = fileIncludesAdjusted.join(' ');
-const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
-const version = process.env.DOCS_VERSION;
-
-(async () => {
-    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
-        cwd,
-    });
-    if (!_.isEmpty(result.stderr)) {
-        throw new Error(result.stderr);
-    }
-    const fileName = `v${version}.json`;
-    const s3Url = S3BucketPath + fileName;
-    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
-        cwd,
-    });
-})().catch(console.error);
diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json
index 54f9ba1ad..16537ba4d 100644
--- a/packages/0x.js/package.json
+++ b/packages/0x.js/package.json
@@ -14,7 +14,7 @@
     "scripts": {
         "build:watch": "tsc -w",
         "prebuild": "run-s clean generate_contract_wrappers",
-        "build": "run-p build:scripts build:umd:prod build:commonjs; exit 0;",
+        "build": "run-p build:umd:prod build:commonjs; exit 0;",
         "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES",
         "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
         "generate_contract_wrappers": "node ../abi-gen/lib/index.js --abis 'src/artifacts/@(Exchange|Token|TokenTransferProxy|EtherToken|TokenRegistry|DummyToken).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/contract_wrappers/generated --backend ethers && prettier --write 'src/contract_wrappers/generated/**.ts'",
@@ -26,8 +26,7 @@
         "update_contracts": "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../0x.js/src/artifacts; done;",
         "clean": "shx rm -rf _bundles lib test_temp",
         "build:umd:prod": "NODE_ENV=production webpack",
-        "build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts;",
-        "build:scripts": "tsc --p ./tsconfig_monorepo.json",
+        "build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
         "test:commonjs": "run-s build:commonjs run_mocha",
         "run_mocha": "mocha lib/test/**/*_test.js --timeout 10000 --bail --exit"
     },
diff --git a/packages/0x.js/scripts/postpublish.js b/packages/0x.js/scripts/postpublish.js
deleted file mode 100644
index 1a9ab73ea..000000000
--- a/packages/0x.js/scripts/postpublish.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const execAsync = require('async-child-process').execAsync;
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-const tsConfig = require('../tsconfig.json');
-
-const cwd = __dirname + '/..';
-const subPackageName = packageJSON.name;
-// Include any external packages that are part of the 0x.js public interface
-// to this array so that TypeDoc picks it up and adds it to the Docs JSON
-// So far, we only have @0xproject/types as part of 0x.js's public interface.
-const fileIncludes = [...tsConfig.include, '../types/src/index.ts'];
-const fileIncludesAdjusted = postpublish_utils.adjustFileIncludePaths(fileIncludes, __dirname);
-const projectFiles = fileIncludesAdjusted.join(' ');
-const S3BucketPath = 's3://0xjs-docs-jsons/';
-
-let tag;
-let version;
-postpublish_utils
-    .getLatestTagAndVersionAsync(subPackageName)
-    .then(function(result) {
-        tag = result.tag;
-        version = result.version;
-        const releaseName = postpublish_utils.getReleaseName(subPackageName, version);
-        const assets = [__dirname + '/../_bundles/index.js', __dirname + '/../_bundles/index.min.js'];
-        return postpublish_utils.publishReleaseNotesAsync(tag, releaseName, assets);
-    })
-    .then(function(release) {
-        console.log('POSTPUBLISH: Release successful, generating docs...');
-        const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json';
-        return execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_FILES="' + projectFiles + '" yarn docs:json', {
-            cwd,
-        });
-    })
-    .then(function(result) {
-        if (result.stderr !== '') {
-            throw new Error(result.stderr);
-        }
-        const fileName = 'v' + version + '.json';
-        console.log('POSTPUBLISH: Doc generation successful, uploading docs... as ', fileName);
-        const s3Url = S3BucketPath + fileName;
-        return execAsync('S3_URL=' + s3Url + ' yarn upload_docs_json', {
-            cwd,
-        });
-    })
-    .catch(function(err) {
-        throw err;
-    });
diff --git a/packages/0x.js/scripts/stagedocs.js b/packages/0x.js/scripts/stagedocs.js
deleted file mode 100644
index f0ba55205..000000000
--- a/packages/0x.js/scripts/stagedocs.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const execAsync = require('async-child-process').execAsync;
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const tsConfig = require('../tsconfig.json');
-
-const cwd = __dirname + '/..';
-const S3BucketPath = 's3://staging-0xjs-docs-jsons/';
-// Include any external packages that are part of the 0x.js public interface
-// to this array so that TypeDoc picks it up and adds it to the Docs JSON
-// So far, we only have @0xproject/types as part of 0x.js's public interface.
-const fileIncludes = [...tsConfig.include, '../types/src/index.ts'];
-const fileIncludesAdjusted = postpublish_utils.adjustFileIncludePaths(fileIncludes, __dirname);
-const projectFiles = fileIncludesAdjusted.join(' ');
-const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json';
-const version = process.env.DOCS_VERSION;
-
-execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_FILES="' + projectFiles + '" yarn docs:json', {
-    cwd,
-})
-    .then(function(result) {
-        if (result.stderr !== '') {
-            throw new Error(result.stderr);
-        }
-        const fileName = 'v' + version + '.json';
-        const s3Url = S3BucketPath + fileName;
-        return execAsync('S3_URL=' + s3Url + ' yarn upload_docs_json', {
-            cwd,
-        });
-    })
-    .catch(function(err) {
-        console.log(err);
-    });
diff --git a/packages/0x.js/src/globals.d.ts b/packages/0x.js/src/globals.d.ts
index 0e103d057..f37ac7cb0 100644
--- a/packages/0x.js/src/globals.d.ts
+++ b/packages/0x.js/src/globals.d.ts
@@ -4,6 +4,13 @@ declare module 'dirty-chai';
 declare module 'request-promise-native';
 declare module 'web3-provider-engine';
 declare module 'web3-provider-engine/subproviders/rpc';
+declare module 'async-child-process';
+declare module 'publish-release';
+
+// semver-sort declarations
+declare module 'semver-sort' {
+    const desc: (versions: string[]) => string[];
+}
 
 // HACK: In order to merge the bignumber declaration added by chai-bignumber to the chai Assertion
 // interface we must use `namespace` as the Chai definitelyTyped definition does. Since we otherwise
diff --git a/packages/0x.js/src/monorepo_scripts/postpublish.ts b/packages/0x.js/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..13ab013be
--- /dev/null
+++ b/packages/0x.js/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,44 @@
+import { postpublishUtils } from '@0xproject/dev-utils';
+import { execAsync } from 'async-child-process';
+import * as _ from 'lodash';
+
+import * as packageJSON from '../package.json';
+import * as tsConfig from '../tsconfig.json';
+
+const cwd = `${__dirname}/..`;
+const subPackageName = (packageJSON as any).name;
+// Include any external packages that are part of the 0x.js public interface
+// to this array so that TypeDoc picks it up and adds it to the Docs JSON
+// So far, we only have @0xproject/types as part of 0x.js's public interface.
+const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts'];
+const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
+const projectFiles = fileIncludesAdjusted.join(' ');
+const S3BucketPath = 's3://0xjs-docs-jsons/';
+
+(async () => {
+    const tagAndVersion = await postpublishUtils.getLatestTagAndVersionAsync(subPackageName);
+    const tag = tagAndVersion.tag;
+    const version = tagAndVersion.version;
+
+    const releaseName = postpublishUtils.getReleaseName(subPackageName, version);
+    const assets = [`${__dirname}/../_bundles/index.js`, `${__dirname}/../_bundles/index.min.js`];
+    const release = await postpublishUtils.publishReleaseNotesAsync(tag, releaseName, assets);
+
+    // tslint:disable-next-line:no-console
+    console.log('POSTPUBLISH: Release successful, generating docs...');
+    const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
+
+    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
+        cwd,
+    });
+    if (!_.isEmpty(result.stderr)) {
+        throw new Error(result.stderr);
+    }
+    const fileName = `v${version}.json`;
+    // tslint:disable-next-line:no-console
+    console.log(`POSTPUBLISH: Doc generation successful, uploading docs... as ${fileName}`);
+    const s3Url = S3BucketPath + fileName;
+    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
+        cwd,
+    });
+})().catch(console.error);
diff --git a/packages/0x.js/src/monorepo_scripts/stagedocs.ts b/packages/0x.js/src/monorepo_scripts/stagedocs.ts
new file mode 100644
index 000000000..a62d8a014
--- /dev/null
+++ b/packages/0x.js/src/monorepo_scripts/stagedocs.ts
@@ -0,0 +1,30 @@
+import { postpublishUtils } from '@0xproject/dev-utils';
+import { execAsync } from 'async-child-process';
+import * as _ from 'lodash';
+
+import * as tsConfig from '../tsconfig.json';
+
+const cwd = __dirname + '/..';
+const S3BucketPath = 's3://staging-0xjs-docs-jsons/';
+// Include any external packages that are part of the 0x.js public interface
+// to this array so that TypeDoc picks it up and adds it to the Docs JSON
+// So far, we only have @0xproject/types as part of 0x.js's public interface.
+const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts'];
+const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
+const projectFiles = fileIncludesAdjusted.join(' ');
+const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
+const version = process.env.DOCS_VERSION;
+
+(async () => {
+    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
+        cwd,
+    });
+    if (!_.isEmpty(result.stderr)) {
+        throw new Error(result.stderr);
+    }
+    const fileName = `v${version}.json`;
+    const s3Url = S3BucketPath + fileName;
+    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
+        cwd,
+    });
+})().catch(console.error);
diff --git a/packages/0x.js/tsconfig_monorepo.json b/packages/0x.js/tsconfig_monorepo.json
deleted file mode 100644
index 7e9609659..000000000
--- a/packages/0x.js/tsconfig_monorepo.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-    "extends": "../../tsconfig",
-    "compilerOptions": {
-        "outDir": "scripts",
-        "noImplicitThis": false,
-        "rootDir": "./monorepo_scripts"
-    },
-    "include": ["./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
-}
diff --git a/scripts/postpublish_utils.js b/scripts/postpublish_utils.js
deleted file mode 100644
index 0a8c6f94d..000000000
--- a/scripts/postpublish_utils.js
+++ /dev/null
@@ -1,86 +0,0 @@
-const _ = require('lodash');
-const execAsync = require('async-child-process').execAsync;
-const semverSort = require('semver-sort');
-const publishRelease = require('publish-release');
-const promisify = require('@0xproject/utils').promisify;
-
-const publishReleaseAsync = promisify(publishRelease);
-const githubPersonalAccessToken = process.env.GITHUB_PERSONAL_ACCESS_TOKEN_0X_JS;
-const generatedDocsDirectoryName = 'generated_docs';
-
-module.exports = {
-    getLatestTagAndVersionAsync: function(subPackageName) {
-        const subPackagePrefix = subPackageName + '@';
-        const gitTagsCommand = 'git tag -l "' + subPackagePrefix + '*"';
-        return execAsync(gitTagsCommand).then(function(result) {
-            if (result.stderr !== '') {
-                throw new Error(result.stderr);
-            }
-            const tags = result.stdout.trim().split('\n');
-            const versions = tags.map(function(tag) {
-                return tag.slice(subPackagePrefix.length);
-            });
-            const sortedVersions = semverSort.desc(versions);
-            const latestVersion = sortedVersions[0];
-            const latestTag = subPackagePrefix + latestVersion;
-            return {
-                tag: latestTag,
-                version: latestVersion,
-            };
-        });
-    },
-    publishReleaseNotesAsync: function(tag, releaseName, assets) {
-        console.log('POSTPUBLISH: Releasing ', releaseName, '...');
-        return publishReleaseAsync({
-            token: githubPersonalAccessToken,
-            owner: '0xProject',
-            repo: '0x.js',
-            tag: tag,
-            name: releaseName,
-            notes: 'N/A',
-            draft: false,
-            prerelease: false,
-            reuseRelease: true,
-            reuseDraftOnly: false,
-            assets: assets,
-        });
-    },
-    getReleaseName(subPackageName, version) {
-        const releaseName = subPackageName + ' v' + version;
-        return releaseName;
-    },
-    standardPostPublishAsync: function(subPackageName) {
-        return this.getLatestTagAndVersionAsync(subPackageName)
-            .then(
-                function(result) {
-                    const releaseName = this.getReleaseName(subPackageName, result.version);
-                    const assets = [];
-                    return this.publishReleaseNotesAsync(result.tag, releaseName, assets);
-                }.bind(this)
-            )
-            .catch(function(err) {
-                throw err;
-            });
-    },
-    adjustFileIncludePaths: function(fileIncludes, cwd) {
-        const fileIncludesAdjusted = _.map(fileIncludes, fileInclude => {
-            let path;
-            if (_.startsWith(fileInclude, '../')) {
-                path = cwd + '/../' + fileInclude;
-            } else if (_.startsWith(fileInclude, './')) {
-                path = cwd + '/../' + fileInclude.substr(2);
-            } else {
-                path = cwd + '/' + fileInclude;
-            }
-
-            // HACK: tsconfig.json needs wildcard directory endings as `/**/*`
-            // but TypeDoc needs it as `/**` in order to pick up files at the root
-            if (_.endsWith(path, '/**/*')) {
-                path = path.slice(0, -2);
-            }
-            return path;
-        });
-        return fileIncludesAdjusted;
-    },
-    generatedDocsDirectoryName,
-};
-- 
cgit v1.2.3


From 92a4e7728844816b79b1892308dadc342fed6853 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 10:42:06 +0100
Subject: Make git-ignore generic for all package scripts

---
 .gitignore | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index c5de0f498..7c5c72809 100644
--- a/.gitignore
+++ b/.gitignore
@@ -77,4 +77,4 @@ bin/
 packages/contracts/src/artifacts
 
 # Monorepo scripts
-packages/0x.js/scripts
+packages/**/scripts/
-- 
cgit v1.2.3


From b93b66edfb050b58f76f6066261fe3074a1df5fc Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 10:42:14 +0100
Subject: Add missing dep

---
 packages/0x.js/package.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json
index 16537ba4d..f6210e768 100644
--- a/packages/0x.js/package.json
+++ b/packages/0x.js/package.json
@@ -52,6 +52,7 @@
         "@types/node": "^8.0.53",
         "@types/sinon": "^2.2.2",
         "@types/uuid": "^3.4.2",
+        "async-child-process": "^1.1.1",
         "awesome-typescript-loader": "^3.1.3",
         "chai": "^4.0.1",
         "chai-as-promised": "^7.1.0",
-- 
cgit v1.2.3


From 355aac2a1a119fd78c629031e1d90debdf6ed1ee Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 10:42:33 +0100
Subject: Move abi-gen scripts to src

---
 packages/abi-gen/package.json                        | 4 +++-
 packages/abi-gen/scripts/postpublish.js              | 5 -----
 packages/abi-gen/src/globals.d.ts                    | 7 +++++++
 packages/abi-gen/src/monorepo_scripts/postpublish.ts | 6 ++++++
 4 files changed, 16 insertions(+), 6 deletions(-)
 delete mode 100644 packages/abi-gen/scripts/postpublish.js
 create mode 100644 packages/abi-gen/src/monorepo_scripts/postpublish.ts

diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json
index 1045b34e0..039083674 100644
--- a/packages/abi-gen/package.json
+++ b/packages/abi-gen/package.json
@@ -8,7 +8,7 @@
         "build:watch": "tsc -w",
         "lint": "tslint --project . 'src/**/*.ts'",
         "clean": "shx rm -rf lib",
-        "build": "tsc"
+        "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts"
     },
     "bin": {
         "abi-gen": "lib/index.js"
@@ -35,11 +35,13 @@
     },
     "devDependencies": {
         "@0xproject/tslint-config": "^0.4.10",
+        "@0xproject/dev-utils": "^0.2.1",
         "@types/glob": "^5.0.33",
         "@types/handlebars": "^4.0.36",
         "@types/mkdirp": "^0.5.1",
         "@types/node": "^8.0.53",
         "@types/yargs": "^10.0.0",
+        "copyfiles": "^1.2.0",
         "npm-run-all": "^4.1.2",
         "shx": "^0.2.2",
         "tslint": "5.8.0",
diff --git a/packages/abi-gen/scripts/postpublish.js b/packages/abi-gen/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/abi-gen/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/abi-gen/src/globals.d.ts b/packages/abi-gen/src/globals.d.ts
index 39df3f852..d267a4106 100644
--- a/packages/abi-gen/src/globals.d.ts
+++ b/packages/abi-gen/src/globals.d.ts
@@ -2,3 +2,10 @@ declare function toSnakeCase(str: string): string;
 declare module 'to-snake-case' {
     export = toSnakeCase;
 }
+
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/abi-gen/src/monorepo_scripts/postpublish.ts b/packages/abi-gen/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..63790a011
--- /dev/null
+++ b/packages/abi-gen/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/dev-utils';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
-- 
cgit v1.2.3


From df1968157c13a7bbe2e512cbc924190a414e6738 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 10:59:53 +0100
Subject: Fix gitignore

---
 .gitignore | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 7c5c72809..1b5d40348 100644
--- a/.gitignore
+++ b/.gitignore
@@ -77,4 +77,4 @@ bin/
 packages/contracts/src/artifacts
 
 # Monorepo scripts
-packages/**/scripts/
+packages/*/scripts/
-- 
cgit v1.2.3


From ca25b816fabe15ce1ebc539c0316beba813683b8 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 15:29:12 +0100
Subject: move scripts to monorepro-scripts

---
 README.md                                          |   2 +-
 packages/0x.js/package.json                        |   3 +-
 packages/0x.js/src/monorepo_scripts/postpublish.ts |   2 +-
 packages/0x.js/src/monorepo_scripts/stagedocs.ts   |   2 +-
 packages/abi-gen/package.json                      |   3 +-
 .../abi-gen/src/monorepo_scripts/postpublish.ts    |   2 +-
 packages/assert/package.json                       |   6 +-
 packages/assert/scripts/postpublish.js             |   5 -
 packages/assert/src/globals.d.ts                   |   7 +
 .../assert/src/monorepo_scripts/postpublish.ts     |   6 +
 packages/base-contract/package.json                |   6 +-
 packages/base-contract/src/globals.d.ts            |   6 +
 .../src/monorepo_scripts/postpublish.ts            |   6 +
 .../monorepo_scripts/globals.d.ts                  |   6 +
 .../monorepo_scripts/postpublish.ts                |   6 +
 .../package.json                                   |   9 +
 .../scripts/postpublish.js                         |   5 -
 .../tsconfig.json                                  |   7 +
 .../monorepo_scripts/globals.d.ts                  |   6 +
 .../monorepo_scripts/postpublish.ts                |   6 +
 packages/chai-typescript-typings/package.json      |   9 +
 .../chai-typescript-typings/scripts/postpublish.js |   5 -
 packages/chai-typescript-typings/tsconfig.json     |   7 +
 packages/connect/package.json                      |   6 +-
 packages/connect/scripts/postpublish.js            |  45 ---
 packages/connect/scripts/stagedocs.js              |  30 --
 packages/connect/src/globals.d.ts                  |   1 +
 .../connect/src/monorepo_scripts/postpublish.ts    |  43 +++
 packages/connect/src/monorepo_scripts/stagedocs.ts |  29 ++
 packages/deployer/package.json                     |   5 +-
 packages/deployer/scripts/postpublish.js           |   5 -
 packages/deployer/src/globals.d.ts                 |   7 +
 .../deployer/src/monorepo_scripts/postpublish.ts   |   6 +
 packages/dev-utils/.npmignore                      |   5 -
 packages/dev-utils/package.json                    |   8 +-
 packages/dev-utils/scripts/postpublish.js          |   5 -
 packages/dev-utils/src/globals.d.ts                |  10 +-
 .../dev-utils/src/monorepo_scripts/postpublish.ts  |   6 +
 packages/dev-utils/src/postpublish_utils.ts        |  86 -----
 packages/dev-utils/src/utils.ts                    |   5 -
 packages/dev-utils/test/.npmignore                 |   5 +
 .../monorepo_scripts/globals.d.ts                  |   6 +
 .../monorepo_scripts/postpublish.ts                |   6 +
 packages/ethers-typescript-typings/package.json    |   7 +-
 .../scripts/postpublish.js                         |   5 -
 packages/ethers-typescript-typings/tsconfig.json   |   7 +
 packages/json-schemas/package.json                 |   6 +-
 packages/json-schemas/scripts/postpublish.js       |   5 -
 packages/json-schemas/src/globals.d.ts             |   7 +
 .../src/monorepo_scripts/postpublish.ts            |   6 +
 packages/monorepo-scripts/package.json             |   7 +-
 packages/monorepo-scripts/src/globals.d.ts         |   8 +
 packages/monorepo-scripts/src/index.ts             |   1 +
 packages/monorepo-scripts/src/postpublish_utils.ts |  86 +++++
 packages/monorepo-scripts/src/utils.ts             |   5 +
 packages/react-docs-example/package.json           |   1 +
 packages/react-docs-example/ts/globals.d.ts        |   6 -
 packages/react-docs/package.json                   | 103 +++---
 packages/react-docs/scripts/postpublish.js         |   5 -
 packages/react-docs/src/components/badge.tsx       |  56 +++
 packages/react-docs/src/components/comment.tsx     |  23 ++
 packages/react-docs/src/components/custom_enum.tsx |  33 ++
 .../react-docs/src/components/documentation.tsx    | 375 +++++++++++++++++++++
 packages/react-docs/src/components/enum.tsx        |  23 ++
 .../react-docs/src/components/event_definition.tsx |  84 +++++
 packages/react-docs/src/components/interface.tsx   |  63 ++++
 .../react-docs/src/components/method_block.tsx     | 150 +++++++++
 .../react-docs/src/components/method_signature.tsx | 128 +++++++
 packages/react-docs/src/components/source_link.tsx |  23 ++
 packages/react-docs/src/components/type.tsx        | 227 +++++++++++++
 .../react-docs/src/components/type_definition.tsx  | 131 +++++++
 packages/react-docs/src/docs_info.ts               | 123 +++++++
 packages/react-docs/src/globals.d.ts               |  14 +
 packages/react-docs/src/index.ts                   |  20 ++
 .../react-docs/src/monorepo_scripts/postpublish.ts |   6 +
 packages/react-docs/src/ts/components/badge.tsx    |  56 ---
 packages/react-docs/src/ts/components/comment.tsx  |  23 --
 .../react-docs/src/ts/components/custom_enum.tsx   |  33 --
 .../react-docs/src/ts/components/documentation.tsx | 375 ---------------------
 packages/react-docs/src/ts/components/enum.tsx     |  23 --
 .../src/ts/components/event_definition.tsx         |  84 -----
 .../react-docs/src/ts/components/interface.tsx     |  63 ----
 .../react-docs/src/ts/components/method_block.tsx  | 150 ---------
 .../src/ts/components/method_signature.tsx         | 128 -------
 .../react-docs/src/ts/components/source_link.tsx   |  23 --
 packages/react-docs/src/ts/components/type.tsx     | 227 -------------
 .../src/ts/components/type_definition.tsx          | 131 -------
 packages/react-docs/src/ts/docs_info.ts            | 123 -------
 packages/react-docs/src/ts/globals.d.ts            |  14 -
 packages/react-docs/src/ts/index.ts                |  20 --
 packages/react-docs/src/ts/types.ts                | 272 ---------------
 packages/react-docs/src/ts/utils/constants.ts      |   9 -
 packages/react-docs/src/ts/utils/doxity_utils.ts   | 175 ----------
 packages/react-docs/src/ts/utils/typedoc_utils.ts  | 370 --------------------
 packages/react-docs/src/ts/utils/utils.ts          |  10 -
 packages/react-docs/src/types.ts                   | 272 +++++++++++++++
 packages/react-docs/src/utils/constants.ts         |   9 +
 packages/react-docs/src/utils/doxity_utils.ts      | 175 ++++++++++
 packages/react-docs/src/utils/typedoc_utils.ts     | 370 ++++++++++++++++++++
 packages/react-docs/src/utils/utils.ts             |  10 +
 packages/react-docs/tsconfig.json                  |   2 +-
 packages/react-shared/package.json                 |  99 +++---
 packages/react-shared/scripts/postpublish.js       |   5 -
 .../react-shared/src/components/anchor_title.tsx   |  87 +++++
 .../src/components/markdown_code_block.tsx         |  25 ++
 .../src/components/markdown_link_block.tsx         |  47 +++
 .../src/components/markdown_section.tsx            |  94 ++++++
 .../src/components/nested_sidebar_menu.tsx         | 158 +++++++++
 .../react-shared/src/components/section_header.tsx |  73 ++++
 .../src/components/version_drop_down.tsx           |  39 +++
 packages/react-shared/src/globals.d.ts             |  14 +
 packages/react-shared/src/index.ts                 |  12 +
 .../src/monorepo_scripts/postpublish.ts            |   6 +
 .../src/ts/components/anchor_title.tsx             |  87 -----
 .../src/ts/components/markdown_code_block.tsx      |  25 --
 .../src/ts/components/markdown_link_block.tsx      |  47 ---
 .../src/ts/components/markdown_section.tsx         |  94 ------
 .../src/ts/components/nested_sidebar_menu.tsx      | 158 ---------
 .../src/ts/components/section_header.tsx           |  73 ----
 .../src/ts/components/version_drop_down.tsx        |  39 ---
 packages/react-shared/src/ts/globals.d.ts          |   7 -
 packages/react-shared/src/ts/index.ts              |  12 -
 packages/react-shared/src/ts/types.ts              |  25 --
 packages/react-shared/src/ts/utils/colors.ts       |  48 ---
 packages/react-shared/src/ts/utils/constants.ts    |  20 --
 packages/react-shared/src/ts/utils/utils.ts        |  45 ---
 packages/react-shared/src/types.ts                 |  25 ++
 packages/react-shared/src/utils/colors.ts          |  48 +++
 packages/react-shared/src/utils/constants.ts       |  20 ++
 packages/react-shared/src/utils/utils.ts           |  45 +++
 packages/sra-report/package.json                   |   6 +-
 packages/sra-report/scripts/postpublish.js         |   5 -
 .../sra-report/src/monorepo_scripts/postpublish.ts |   6 +
 packages/subproviders/package.json                 |   6 +-
 packages/subproviders/scripts/postpublish.js       |   5 -
 packages/subproviders/src/globals.d.ts             |   7 +
 .../src/monorepo_scripts/postpublish.ts            |   6 +
 .../tslint-config/monorepo_scripts/globals.d.ts    |   6 +
 .../tslint-config/monorepo_scripts/postpublish.ts  |   6 +
 packages/tslint-config/package.json                |   6 +-
 packages/tslint-config/scripts/postpublish.js      |   5 -
 packages/tslint-config/tsconfig.json               |   2 +-
 packages/types/package.json                        |   6 +-
 packages/types/scripts/postpublish.js              |   5 -
 packages/types/src/globals.d.ts                    |   6 +
 packages/types/src/monorepo_scripts/postpublish.ts |   6 +
 packages/utils/package.json                        |   6 +-
 packages/utils/scripts/postpublish.js              |   5 -
 packages/utils/src/globals.d.ts                    |   6 +
 packages/utils/src/monorepo_scripts/postpublish.ts |   6 +
 .../monorepo_scripts/globals.d.ts                  |   6 +
 .../monorepo_scripts/postpublish.ts                |   6 +
 packages/web3-typescript-typings/package.json      |   7 +-
 .../web3-typescript-typings/scripts/postpublish.js |   5 -
 packages/web3-typescript-typings/tsconfig.json     |   7 +
 packages/web3-wrapper/package.json                 |   6 +-
 packages/web3-wrapper/scripts/postpublish.js       |   5 -
 packages/web3-wrapper/src/globals.d.ts             |   6 +
 .../src/monorepo_scripts/postpublish.ts            |   6 +
 159 files changed, 3588 insertions(+), 3387 deletions(-)
 delete mode 100644 packages/assert/scripts/postpublish.js
 create mode 100644 packages/assert/src/monorepo_scripts/postpublish.ts
 create mode 100644 packages/base-contract/src/globals.d.ts
 create mode 100644 packages/base-contract/src/monorepo_scripts/postpublish.ts
 create mode 100644 packages/chai-as-promised-typescript-typings/monorepo_scripts/globals.d.ts
 create mode 100644 packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/chai-as-promised-typescript-typings/scripts/postpublish.js
 create mode 100644 packages/chai-as-promised-typescript-typings/tsconfig.json
 create mode 100644 packages/chai-typescript-typings/monorepo_scripts/globals.d.ts
 create mode 100644 packages/chai-typescript-typings/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/chai-typescript-typings/scripts/postpublish.js
 create mode 100644 packages/chai-typescript-typings/tsconfig.json
 delete mode 100644 packages/connect/scripts/postpublish.js
 delete mode 100644 packages/connect/scripts/stagedocs.js
 create mode 100644 packages/connect/src/monorepo_scripts/postpublish.ts
 create mode 100644 packages/connect/src/monorepo_scripts/stagedocs.ts
 delete mode 100644 packages/deployer/scripts/postpublish.js
 create mode 100644 packages/deployer/src/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/dev-utils/.npmignore
 delete mode 100644 packages/dev-utils/scripts/postpublish.js
 create mode 100644 packages/dev-utils/src/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/dev-utils/src/postpublish_utils.ts
 delete mode 100644 packages/dev-utils/src/utils.ts
 create mode 100644 packages/dev-utils/test/.npmignore
 create mode 100644 packages/ethers-typescript-typings/monorepo_scripts/globals.d.ts
 create mode 100644 packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/ethers-typescript-typings/scripts/postpublish.js
 create mode 100644 packages/ethers-typescript-typings/tsconfig.json
 delete mode 100644 packages/json-schemas/scripts/postpublish.js
 create mode 100644 packages/json-schemas/src/monorepo_scripts/postpublish.ts
 create mode 100644 packages/monorepo-scripts/src/globals.d.ts
 create mode 100644 packages/monorepo-scripts/src/index.ts
 create mode 100644 packages/monorepo-scripts/src/postpublish_utils.ts
 create mode 100644 packages/monorepo-scripts/src/utils.ts
 delete mode 100644 packages/react-docs-example/ts/globals.d.ts
 delete mode 100644 packages/react-docs/scripts/postpublish.js
 create mode 100644 packages/react-docs/src/components/badge.tsx
 create mode 100644 packages/react-docs/src/components/comment.tsx
 create mode 100644 packages/react-docs/src/components/custom_enum.tsx
 create mode 100644 packages/react-docs/src/components/documentation.tsx
 create mode 100644 packages/react-docs/src/components/enum.tsx
 create mode 100644 packages/react-docs/src/components/event_definition.tsx
 create mode 100644 packages/react-docs/src/components/interface.tsx
 create mode 100644 packages/react-docs/src/components/method_block.tsx
 create mode 100644 packages/react-docs/src/components/method_signature.tsx
 create mode 100644 packages/react-docs/src/components/source_link.tsx
 create mode 100644 packages/react-docs/src/components/type.tsx
 create mode 100644 packages/react-docs/src/components/type_definition.tsx
 create mode 100644 packages/react-docs/src/docs_info.ts
 create mode 100644 packages/react-docs/src/globals.d.ts
 create mode 100644 packages/react-docs/src/index.ts
 create mode 100644 packages/react-docs/src/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/react-docs/src/ts/components/badge.tsx
 delete mode 100644 packages/react-docs/src/ts/components/comment.tsx
 delete mode 100644 packages/react-docs/src/ts/components/custom_enum.tsx
 delete mode 100644 packages/react-docs/src/ts/components/documentation.tsx
 delete mode 100644 packages/react-docs/src/ts/components/enum.tsx
 delete mode 100644 packages/react-docs/src/ts/components/event_definition.tsx
 delete mode 100644 packages/react-docs/src/ts/components/interface.tsx
 delete mode 100644 packages/react-docs/src/ts/components/method_block.tsx
 delete mode 100644 packages/react-docs/src/ts/components/method_signature.tsx
 delete mode 100644 packages/react-docs/src/ts/components/source_link.tsx
 delete mode 100644 packages/react-docs/src/ts/components/type.tsx
 delete mode 100644 packages/react-docs/src/ts/components/type_definition.tsx
 delete mode 100644 packages/react-docs/src/ts/docs_info.ts
 delete mode 100644 packages/react-docs/src/ts/globals.d.ts
 delete mode 100644 packages/react-docs/src/ts/index.ts
 delete mode 100644 packages/react-docs/src/ts/types.ts
 delete mode 100644 packages/react-docs/src/ts/utils/constants.ts
 delete mode 100644 packages/react-docs/src/ts/utils/doxity_utils.ts
 delete mode 100644 packages/react-docs/src/ts/utils/typedoc_utils.ts
 delete mode 100644 packages/react-docs/src/ts/utils/utils.ts
 create mode 100644 packages/react-docs/src/types.ts
 create mode 100644 packages/react-docs/src/utils/constants.ts
 create mode 100644 packages/react-docs/src/utils/doxity_utils.ts
 create mode 100644 packages/react-docs/src/utils/typedoc_utils.ts
 create mode 100644 packages/react-docs/src/utils/utils.ts
 delete mode 100644 packages/react-shared/scripts/postpublish.js
 create mode 100644 packages/react-shared/src/components/anchor_title.tsx
 create mode 100644 packages/react-shared/src/components/markdown_code_block.tsx
 create mode 100644 packages/react-shared/src/components/markdown_link_block.tsx
 create mode 100644 packages/react-shared/src/components/markdown_section.tsx
 create mode 100644 packages/react-shared/src/components/nested_sidebar_menu.tsx
 create mode 100644 packages/react-shared/src/components/section_header.tsx
 create mode 100644 packages/react-shared/src/components/version_drop_down.tsx
 create mode 100644 packages/react-shared/src/globals.d.ts
 create mode 100644 packages/react-shared/src/index.ts
 create mode 100644 packages/react-shared/src/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/react-shared/src/ts/components/anchor_title.tsx
 delete mode 100644 packages/react-shared/src/ts/components/markdown_code_block.tsx
 delete mode 100644 packages/react-shared/src/ts/components/markdown_link_block.tsx
 delete mode 100644 packages/react-shared/src/ts/components/markdown_section.tsx
 delete mode 100644 packages/react-shared/src/ts/components/nested_sidebar_menu.tsx
 delete mode 100644 packages/react-shared/src/ts/components/section_header.tsx
 delete mode 100644 packages/react-shared/src/ts/components/version_drop_down.tsx
 delete mode 100644 packages/react-shared/src/ts/globals.d.ts
 delete mode 100644 packages/react-shared/src/ts/index.ts
 delete mode 100644 packages/react-shared/src/ts/types.ts
 delete mode 100644 packages/react-shared/src/ts/utils/colors.ts
 delete mode 100644 packages/react-shared/src/ts/utils/constants.ts
 delete mode 100644 packages/react-shared/src/ts/utils/utils.ts
 create mode 100644 packages/react-shared/src/types.ts
 create mode 100644 packages/react-shared/src/utils/colors.ts
 create mode 100644 packages/react-shared/src/utils/constants.ts
 create mode 100644 packages/react-shared/src/utils/utils.ts
 delete mode 100644 packages/sra-report/scripts/postpublish.js
 create mode 100644 packages/sra-report/src/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/subproviders/scripts/postpublish.js
 create mode 100644 packages/subproviders/src/monorepo_scripts/postpublish.ts
 create mode 100644 packages/tslint-config/monorepo_scripts/globals.d.ts
 create mode 100644 packages/tslint-config/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/tslint-config/scripts/postpublish.js
 delete mode 100644 packages/types/scripts/postpublish.js
 create mode 100644 packages/types/src/globals.d.ts
 create mode 100644 packages/types/src/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/utils/scripts/postpublish.js
 create mode 100644 packages/utils/src/globals.d.ts
 create mode 100644 packages/utils/src/monorepo_scripts/postpublish.ts
 create mode 100644 packages/web3-typescript-typings/monorepo_scripts/globals.d.ts
 create mode 100644 packages/web3-typescript-typings/monorepo_scripts/postpublish.ts
 delete mode 100644 packages/web3-typescript-typings/scripts/postpublish.js
 create mode 100644 packages/web3-typescript-typings/tsconfig.json
 delete mode 100644 packages/web3-wrapper/scripts/postpublish.js
 create mode 100644 packages/web3-wrapper/src/globals.d.ts
 create mode 100644 packages/web3-wrapper/src/monorepo_scripts/postpublish.ts

diff --git a/README.md b/README.md
index ee3932531..ba1caa7a6 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,7 @@ This repository is a monorepo including the 0x protocol smart contracts and nume
 | [`@0xproject/dev-utils`](/packages/dev-utils)                                          | [![npm](https://img.shields.io/npm/v/@0xproject/dev-utils.svg)](https://www.npmjs.com/package/@0xproject/dev-utils)                               | Dev utils to be shared across 0x projects and packages                      |
 | [`ethers-typescript-typings`](/packages/ethers-typescript-typings)                     | [![npm](https://img.shields.io/npm/v/@0xproject/deployer.svg)](https://www.npmjs.com/package/ethers-typescript-typings)                           | [Ethers.js](https://github.com/ethers-io/ethers.js/) typescript typings     |
 | [`@0xproject/json-schemas`](/packages/json-schemas)                                    | [![npm](https://img.shields.io/npm/v/@0xproject/json-schemas.svg)](https://www.npmjs.com/package/@0xproject/json-schemas)                         | 0x-related json schemas                                                     |
+| [`@0xproject/monorepo-scripts`](/packages/monorepo-scripts)                            | [![npm](https://img.shields.io/npm/v/@0xproject/monorepo-scripts.svg)](https://www.npmjs.com/package/@0xproject/monorepo-scripts)                 | Scripts for managing a monorepo                                             |
 | [`@0xproject/react-docs`](/packages/react-docs)                                        | [![npm](https://img.shields.io/npm/v/@0xproject/react-docs.svg)](https://www.npmjs.com/package/@0xproject/react-docs)                             | React documentation component for rendering TypeDoc & Doxity generated JSON |
 | [`@0xproject/react-shared`](/packages/react-shared)                                    | [![npm](https://img.shields.io/npm/v/@0xproject/react-shared.svg)](https://www.npmjs.com/package/@0xproject/react-shared)                         | 0x shared react components                                                  |
 | [`@0xproject/sra-report`](/packages/sra-report)                                        | [![npm](https://img.shields.io/npm/v/@0xproject/sra-report.svg)](https://www.npmjs.com/package/@0xproject/sra-report)                             | Generate reports for standard relayer API compliance                        |
@@ -47,7 +48,6 @@ This repository is a monorepo including the 0x protocol smart contracts and nume
 | --------------------------------------------------------------- | ---------------------------------------------------------------- |
 | [`@0xproject/contracts`](/packages/contracts)                   | 0x solidity smart contracts & tests                              |
 | [`@0xproject/react-docs-example`](/packages/react-docs-example) | Example documentation site created with `@0xproject/react-docs`  |
-| [`@0xproject/monorepo-scripts`](/packages/monorepo-scripts)     | Shared monorepo scripts                                          |
 | [`@0xproject/testnet-faucets`](/packages/testnet-faucets)       | A faucet micro-service that dispenses test ERC20 tokens or Ether |
 | [`@0xproject/website`](/packages/website)                       | 0x website & Portal DApp                                         |
 
diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json
index f6210e768..ec55bf1af 100644
--- a/packages/0x.js/package.json
+++ b/packages/0x.js/package.json
@@ -24,7 +24,7 @@
         "test:coverage": "nyc npm run test --all",
         "report_test_coverage": "nyc report --reporter=text-lcov | coveralls",
         "update_contracts": "for i in ${npm_package_config_artifacts}; do copyfiles -u 4 ../contracts/build/contracts/$i.json ../0x.js/src/artifacts; done;",
-        "clean": "shx rm -rf _bundles lib test_temp",
+        "clean": "shx rm -rf _bundles lib test_temp scripts",
         "build:umd:prod": "NODE_ENV=production webpack",
         "build:commonjs": "tsc && copyfiles -u 2 './src/artifacts/**/*.json' ./lib/src/artifacts && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
         "test:commonjs": "run-s build:commonjs run_mocha",
@@ -44,6 +44,7 @@
     "devDependencies": {
         "@0xproject/abi-gen": "^0.2.5",
         "@0xproject/dev-utils": "^0.2.1",
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "@types/bintrees": "^1.0.2",
         "@types/jsonschema": "^1.1.1",
diff --git a/packages/0x.js/src/monorepo_scripts/postpublish.ts b/packages/0x.js/src/monorepo_scripts/postpublish.ts
index 13ab013be..8e2692c93 100644
--- a/packages/0x.js/src/monorepo_scripts/postpublish.ts
+++ b/packages/0x.js/src/monorepo_scripts/postpublish.ts
@@ -1,4 +1,4 @@
-import { postpublishUtils } from '@0xproject/dev-utils';
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import { execAsync } from 'async-child-process';
 import * as _ from 'lodash';
 
diff --git a/packages/0x.js/src/monorepo_scripts/stagedocs.ts b/packages/0x.js/src/monorepo_scripts/stagedocs.ts
index a62d8a014..20355c52c 100644
--- a/packages/0x.js/src/monorepo_scripts/stagedocs.ts
+++ b/packages/0x.js/src/monorepo_scripts/stagedocs.ts
@@ -1,4 +1,4 @@
-import { postpublishUtils } from '@0xproject/dev-utils';
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import { execAsync } from 'async-child-process';
 import * as _ from 'lodash';
 
diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json
index 039083674..ffae67e22 100644
--- a/packages/abi-gen/package.json
+++ b/packages/abi-gen/package.json
@@ -7,7 +7,7 @@
     "scripts": {
         "build:watch": "tsc -w",
         "lint": "tslint --project . 'src/**/*.ts'",
-        "clean": "shx rm -rf lib",
+        "clean": "shx rm -rf lib scripts",
         "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts"
     },
     "bin": {
@@ -34,6 +34,7 @@
         "yargs": "^10.0.3"
     },
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "@0xproject/dev-utils": "^0.2.1",
         "@types/glob": "^5.0.33",
diff --git a/packages/abi-gen/src/monorepo_scripts/postpublish.ts b/packages/abi-gen/src/monorepo_scripts/postpublish.ts
index 63790a011..d5fcff9d0 100644
--- a/packages/abi-gen/src/monorepo_scripts/postpublish.ts
+++ b/packages/abi-gen/src/monorepo_scripts/postpublish.ts
@@ -1,4 +1,4 @@
-import { postpublishUtils } from '@0xproject/dev-utils';
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
 
diff --git a/packages/assert/package.json b/packages/assert/package.json
index 49b0f3390..be5f4902d 100644
--- a/packages/assert/package.json
+++ b/packages/assert/package.json
@@ -6,8 +6,8 @@
     "types": "lib/src/index.d.ts",
     "scripts": {
         "build:watch": "tsc -w",
-        "build": "tsc",
-        "clean": "shx rm -rf _bundles lib test_temp",
+        "build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
+        "clean": "shx rm -rf _bundles lib test_temp scripts",
         "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
         "run_mocha": "mocha lib/test/**/*_test.js",
         "prepublishOnly": "run-p build",
@@ -24,12 +24,14 @@
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/assert/README.md",
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "@types/lodash": "^4.14.86",
         "@types/mocha": "^2.2.42",
         "@types/valid-url": "^1.0.2",
         "chai": "^4.0.1",
         "chai-typescript-typings": "^0.0.4",
+        "copyfiles": "^1.2.0",
         "dirty-chai": "^2.0.1",
         "mocha": "^4.0.1",
         "npm-run-all": "^4.1.2",
diff --git a/packages/assert/scripts/postpublish.js b/packages/assert/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/assert/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/assert/src/globals.d.ts b/packages/assert/src/globals.d.ts
index 91ed2021e..5476b6bd8 100644
--- a/packages/assert/src/globals.d.ts
+++ b/packages/assert/src/globals.d.ts
@@ -1 +1,8 @@
 declare module 'dirty-chai';
+
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/assert/src/monorepo_scripts/postpublish.ts b/packages/assert/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/assert/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/base-contract/package.json b/packages/base-contract/package.json
index 6b4fc9a8e..cfb336106 100644
--- a/packages/base-contract/package.json
+++ b/packages/base-contract/package.json
@@ -6,8 +6,8 @@
     "types": "lib/index.d.ts",
     "scripts": {
         "build:watch": "tsc -w",
-        "build": "tsc",
-        "clean": "shx rm -rf lib",
+        "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
+        "clean": "shx rm -rf lib scripts",
         "lint": "tslint --project . 'src/**/*.ts'"
     },
     "license": "Apache-2.0",
@@ -20,8 +20,10 @@
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/base-contract/README.md",
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "@types/lodash": "^4.14.86",
+        "copyfiles": "^1.2.0",
         "npm-run-all": "^4.1.2",
         "shx": "^0.2.2",
         "tslint": "5.8.0",
diff --git a/packages/base-contract/src/globals.d.ts b/packages/base-contract/src/globals.d.ts
new file mode 100644
index 000000000..94e63a32d
--- /dev/null
+++ b/packages/base-contract/src/globals.d.ts
@@ -0,0 +1,6 @@
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/base-contract/src/monorepo_scripts/postpublish.ts b/packages/base-contract/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/base-contract/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/chai-as-promised-typescript-typings/monorepo_scripts/globals.d.ts b/packages/chai-as-promised-typescript-typings/monorepo_scripts/globals.d.ts
new file mode 100644
index 000000000..94e63a32d
--- /dev/null
+++ b/packages/chai-as-promised-typescript-typings/monorepo_scripts/globals.d.ts
@@ -0,0 +1,6 @@
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts b/packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/chai-as-promised-typescript-typings/package.json b/packages/chai-as-promised-typescript-typings/package.json
index 98fc63b38..d22f45d28 100644
--- a/packages/chai-as-promised-typescript-typings/package.json
+++ b/packages/chai-as-promised-typescript-typings/package.json
@@ -4,6 +4,10 @@
     "description": "Typescript type definitions for chai-as-promised",
     "main": "index.d.ts",
     "types": "index.d.ts",
+    "scripts": {
+        "build": "tsc && copyfiles -u 1 './lib/**/*' ./scripts",
+        "clean": "shx rm -rf scripts"
+    },
     "repository": {
         "type": "git",
         "url": "git+https://github.com/0xProject/0x-monorepo.git"
@@ -20,6 +24,11 @@
     "dependencies": {
         "chai-typescript-typings": "^0.0.4"
     },
+    "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
+        "copyfiles": "^1.2.0",
+        "shx": "^0.2.2"
+    },
     "publishConfig": {
       "access": "public"
     }
diff --git a/packages/chai-as-promised-typescript-typings/scripts/postpublish.js b/packages/chai-as-promised-typescript-typings/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/chai-as-promised-typescript-typings/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/chai-as-promised-typescript-typings/tsconfig.json b/packages/chai-as-promised-typescript-typings/tsconfig.json
new file mode 100644
index 000000000..2599d1b7c
--- /dev/null
+++ b/packages/chai-as-promised-typescript-typings/tsconfig.json
@@ -0,0 +1,7 @@
+{
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+}
diff --git a/packages/chai-typescript-typings/monorepo_scripts/globals.d.ts b/packages/chai-typescript-typings/monorepo_scripts/globals.d.ts
new file mode 100644
index 000000000..94e63a32d
--- /dev/null
+++ b/packages/chai-typescript-typings/monorepo_scripts/globals.d.ts
@@ -0,0 +1,6 @@
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/chai-typescript-typings/monorepo_scripts/postpublish.ts b/packages/chai-typescript-typings/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/chai-typescript-typings/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/chai-typescript-typings/package.json b/packages/chai-typescript-typings/package.json
index a07694ed0..e8981b8cd 100644
--- a/packages/chai-typescript-typings/package.json
+++ b/packages/chai-typescript-typings/package.json
@@ -4,6 +4,10 @@
     "description": "Typescript type definitions for chai",
     "main": "index.d.ts",
     "types": "index.d.ts",
+    "scripts": {
+        "build": "tsc && copyfiles -u 1 './lib/**/*' ./scripts",
+        "clean": "shx rm -rf scripts"
+    },
     "repository": {
         "type": "git",
         "url": "git+https://github.com/0xProject/0x-monorepo.git"
@@ -13,6 +17,11 @@
         "url": "https://github.com/0xProject/0x-monorepo/issues"
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/chai-typescript-typings#readme",
+    "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
+        "copyfiles": "^1.2.0",
+        "shx": "^0.2.2"
+    },
     "publishConfig": {
       "access": "public"
     }
diff --git a/packages/chai-typescript-typings/scripts/postpublish.js b/packages/chai-typescript-typings/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/chai-typescript-typings/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/chai-typescript-typings/tsconfig.json b/packages/chai-typescript-typings/tsconfig.json
new file mode 100644
index 000000000..2599d1b7c
--- /dev/null
+++ b/packages/chai-typescript-typings/tsconfig.json
@@ -0,0 +1,7 @@
+{
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+}
diff --git a/packages/connect/package.json b/packages/connect/package.json
index c8714a93a..0c4db7f60 100644
--- a/packages/connect/package.json
+++ b/packages/connect/package.json
@@ -13,8 +13,8 @@
     "types": "lib/src/index.d.ts",
     "scripts": {
         "build:watch": "tsc -w",
-        "build": "tsc",
-        "clean": "shx rm -rf _bundles lib test_temp",
+        "build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
+        "clean": "shx rm -rf _bundles lib test_temp scripts",
         "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES",
         "upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json",
         "copy_test_fixtures": "copyfiles -u 2 './test/fixtures/**/*.json' ./lib/test/fixtures",
@@ -46,12 +46,14 @@
         "websocket": "^1.0.25"
     },
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "@types/fetch-mock": "^5.12.1",
         "@types/lodash": "^4.14.86",
         "@types/mocha": "^2.2.42",
         "@types/query-string": "^5.0.1",
         "@types/websocket": "^0.0.34",
+        "async-child-process": "^1.1.1",
         "chai": "^4.0.1",
         "chai-as-promised": "^7.1.0",
         "chai-as-promised-typescript-typings": "^0.0.10",
diff --git a/packages/connect/scripts/postpublish.js b/packages/connect/scripts/postpublish.js
deleted file mode 100644
index e447615f9..000000000
--- a/packages/connect/scripts/postpublish.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const execAsync = require('async-child-process').execAsync;
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-const tsConfig = require('../tsconfig.json');
-
-const cwd = __dirname + '/..';
-const subPackageName = packageJSON.name;
-const S3BucketPath = 's3://connect-docs-jsons/';
-// Include any external packages that are part of the @0xproject/connect public interface
-// to this array so that TypeDoc picks it up and adds it to the Docs JSON
-const fileIncludes = [...tsConfig.include];
-const fileIncludesAdjusted = postpublish_utils.adjustFileIncludePaths(fileIncludes, __dirname);
-const projectFiles = fileIncludesAdjusted.join(' ');
-
-let tag;
-let version;
-postpublish_utils
-    .getLatestTagAndVersionAsync(subPackageName)
-    .then(function(result) {
-        tag = result.tag;
-        version = result.version;
-        const releaseName = postpublish_utils.getReleaseName(subPackageName, version);
-        return postpublish_utils.publishReleaseNotesAsync(tag, releaseName);
-    })
-    .then(function(release) {
-        console.log('POSTPUBLISH: Release successful, generating docs...');
-        const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json';
-        return execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_FILES="' + projectFiles + '" yarn docs:json', {
-            cwd,
-        });
-    })
-    .then(function(result) {
-        if (result.stderr !== '') {
-            throw new Error(result.stderr);
-        }
-        const fileName = 'v' + version + '.json';
-        console.log('POSTPUBLISH: Doc generation successful, uploading docs... as ', fileName);
-        const s3Url = S3BucketPath + fileName;
-        return execAsync('S3_URL=' + s3Url + ' yarn upload_docs_json', {
-            cwd,
-        });
-    })
-    .catch(function(err) {
-        throw err;
-    });
diff --git a/packages/connect/scripts/stagedocs.js b/packages/connect/scripts/stagedocs.js
deleted file mode 100644
index 58272ab86..000000000
--- a/packages/connect/scripts/stagedocs.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const execAsync = require('async-child-process').execAsync;
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const tsConfig = require('../tsconfig.json');
-
-const cwd = __dirname + '/..';
-const S3BucketPath = 's3://staging-connect-docs-jsons/';
-const jsonFilePath = __dirname + '/../' + postpublish_utils.generatedDocsDirectoryName + '/index.json';
-const version = process.env.DOCS_VERSION;
-// Include any external packages that are part of the @0xproject/connect public interface
-// to this array so that TypeDoc picks it up and adds it to the Docs JSON
-const fileIncludes = [...tsConfig.include];
-const fileIncludesAdjusted = postpublish_utils.adjustFileIncludePaths(fileIncludes, __dirname);
-const projectFiles = fileIncludesAdjusted.join(' ');
-
-execAsync('JSON_FILE_PATH=' + jsonFilePath + ' PROJECT_FILES="' + projectFiles + '" yarn docs:json', {
-    cwd,
-})
-    .then(function(result) {
-        if (result.stderr !== '') {
-            throw new Error(result.stderr);
-        }
-        const fileName = 'v' + version + '.json';
-        const s3Url = S3BucketPath + fileName;
-        return execAsync('S3_URL=' + s3Url + ' yarn upload_docs_json', {
-            cwd,
-        });
-    })
-    .catch(function(err) {
-        console.log(err);
-    });
diff --git a/packages/connect/src/globals.d.ts b/packages/connect/src/globals.d.ts
index 078e189cd..cb71dcdd1 100644
--- a/packages/connect/src/globals.d.ts
+++ b/packages/connect/src/globals.d.ts
@@ -1,3 +1,4 @@
+declare module 'async-child-process';
 declare module 'dirty-chai';
 
 declare module '*.json' {
diff --git a/packages/connect/src/monorepo_scripts/postpublish.ts b/packages/connect/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..4cb8bf071
--- /dev/null
+++ b/packages/connect/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,43 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+import { execAsync } from 'async-child-process';
+import * as _ from 'lodash';
+
+import * as packageJSON from '../package.json';
+import * as tsConfig from '../tsconfig.json';
+
+const cwd = `${__dirname}/..`;
+const subPackageName = (packageJSON as any).name;
+// Include any external packages that are part of the @0xproject/connect public interface
+// to this array so that TypeDoc picks it up and adds it to the Docs JSON
+const fileIncludes = [...(tsConfig as any).include];
+const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
+const projectFiles = fileIncludesAdjusted.join(' ');
+const S3BucketPath = 's3://connect-docs-jsons/';
+
+(async () => {
+    const tagAndVersion = await postpublishUtils.getLatestTagAndVersionAsync(subPackageName);
+    const tag = tagAndVersion.tag;
+    const version = tagAndVersion.version;
+
+    const releaseName = postpublishUtils.getReleaseName(subPackageName, version);
+    const assets = [`${__dirname}/../_bundles/index.js`, `${__dirname}/../_bundles/index.min.js`];
+    const release = await postpublishUtils.publishReleaseNotesAsync(tag, releaseName, assets);
+
+    // tslint:disable-next-line:no-console
+    console.log('POSTPUBLISH: Release successful, generating docs...');
+    const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
+
+    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
+        cwd,
+    });
+    if (!_.isEmpty(result.stderr)) {
+        throw new Error(result.stderr);
+    }
+    const fileName = `v${version}.json`;
+    // tslint:disable-next-line:no-console
+    console.log(`POSTPUBLISH: Doc generation successful, uploading docs... as ${fileName}`);
+    const s3Url = S3BucketPath + fileName;
+    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
+        cwd,
+    });
+})().catch(console.error);
diff --git a/packages/connect/src/monorepo_scripts/stagedocs.ts b/packages/connect/src/monorepo_scripts/stagedocs.ts
new file mode 100644
index 000000000..ae0383ed7
--- /dev/null
+++ b/packages/connect/src/monorepo_scripts/stagedocs.ts
@@ -0,0 +1,29 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+import { execAsync } from 'async-child-process';
+import * as _ from 'lodash';
+
+import * as tsConfig from '../tsconfig.json';
+
+const cwd = __dirname + '/..';
+const S3BucketPath = 's3://staging-connect-docs-jsons/';
+// Include any external packages that are part of the @0xproject/connect public interface
+// to this array so that TypeDoc picks it up and adds it to the Docs JSON
+const fileIncludes = [...(tsConfig as any).include];
+const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
+const projectFiles = fileIncludesAdjusted.join(' ');
+const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
+const version = process.env.DOCS_VERSION;
+
+(async () => {
+    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
+        cwd,
+    });
+    if (!_.isEmpty(result.stderr)) {
+        throw new Error(result.stderr);
+    }
+    const fileName = `v${version}.json`;
+    const s3Url = S3BucketPath + fileName;
+    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
+        cwd,
+    });
+})().catch(console.error);
diff --git a/packages/deployer/package.json b/packages/deployer/package.json
index a705f1ac0..650997e78 100644
--- a/packages/deployer/package.json
+++ b/packages/deployer/package.json
@@ -6,10 +6,10 @@
     "types": "lib/src/index.d.ts",
     "scripts": {
         "build:watch": "tsc -w",
-        "build": "yarn clean && copyfiles 'test/fixtures/contracts/**/*' src/solc/solc_bin/* ./lib && tsc",
+        "build": "yarn clean && copyfiles 'test/fixtures/contracts/**/*' src/solc/solc_bin/* ./lib && tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
         "test": "npm run build; mocha lib/test/*_test.js",
         "compile": "npm run build; node lib/src/cli.js compile",
-        "clean": "shx rm -rf ./lib",
+        "clean": "shx rm -rf lib scripts",
         "migrate": "npm run build; node lib/src/cli.js migrate",
         "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
         "test:circleci": "yarn test"
@@ -28,6 +28,7 @@
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/deployer/README.md",
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "chai": "^4.0.1",
         "copyfiles": "^1.2.0",
diff --git a/packages/deployer/scripts/postpublish.js b/packages/deployer/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/deployer/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/deployer/src/globals.d.ts b/packages/deployer/src/globals.d.ts
index 2e04d83ea..ec671ab63 100644
--- a/packages/deployer/src/globals.d.ts
+++ b/packages/deployer/src/globals.d.ts
@@ -9,3 +9,10 @@ declare module 'web3-eth-abi' {
     // tslint:disable-next-line:completed-docs
     export function encodeParameters(typesArray: string[], parameters: any[]): string;
 }
+
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/deployer/src/monorepo_scripts/postpublish.ts b/packages/deployer/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/deployer/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/dev-utils/.npmignore b/packages/dev-utils/.npmignore
deleted file mode 100644
index 87bc30436..000000000
--- a/packages/dev-utils/.npmignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.*
-yarn-error.log
-/src/
-/scripts/
-tsconfig.json
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
index 491ebd95f..8912a7330 100644
--- a/packages/dev-utils/package.json
+++ b/packages/dev-utils/package.json
@@ -6,11 +6,11 @@
     "types": "lib/src/index.d.ts",
     "scripts": {
         "build:watch": "tsc -w",
-        "build": "tsc",
+        "build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
         "test": "run-s clean build run_mocha",
         "test:circleci": "yarn test",
         "run_mocha": "mocha lib/test/**/*_test.js --bail --exit",
-        "clean": "shx rm -rf lib",
+        "clean": "shx rm -rf lib scripts",
         "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'"
     },
     "license": "Apache-2.0",
@@ -23,12 +23,14 @@
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/dev-utils/README.md",
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "@0xproject/web3-wrapper": "^0.2.1",
         "@types/lodash": "^4.14.86",
         "@types/mocha": "^2.2.42",
         "chai": "^4.0.1",
         "chai-typescript-typings": "^0.0.4",
+        "copyfiles": "^1.2.0",
         "mocha": "^4.0.1",
         "npm-run-all": "^4.1.2",
         "shx": "^0.2.2",
@@ -43,9 +45,7 @@
         "@0xproject/utils": "^0.4.1",
         "ethereumjs-util": "^5.1.2",
         "lodash": "^4.17.4",
-        "publish-release": "0xproject/publish-release",
         "request-promise-native": "^1.0.5",
-        "semver-sort": "^0.0.4",
         "web3": "^0.20.0",
         "web3-provider-engine": "^13.0.1"
     },
diff --git a/packages/dev-utils/scripts/postpublish.js b/packages/dev-utils/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/dev-utils/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/dev-utils/src/globals.d.ts b/packages/dev-utils/src/globals.d.ts
index 9c8a1dc02..894e56c58 100644
--- a/packages/dev-utils/src/globals.d.ts
+++ b/packages/dev-utils/src/globals.d.ts
@@ -1,9 +1,9 @@
 declare module 'web3-provider-engine';
 declare module 'web3-provider-engine/subproviders/rpc';
-declare module 'async-child-process';
-declare module 'publish-release';
 
-// semver-sort declarations
-declare module 'semver-sort' {
-    const desc: (versions: string[]) => string[];
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
 }
diff --git a/packages/dev-utils/src/monorepo_scripts/postpublish.ts b/packages/dev-utils/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..6bd94e71d
--- /dev/null
+++ b/packages/dev-utils/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '../postpublish_utils';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/dev-utils/src/postpublish_utils.ts b/packages/dev-utils/src/postpublish_utils.ts
deleted file mode 100644
index 35d046e26..000000000
--- a/packages/dev-utils/src/postpublish_utils.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { promisify } from '@0xproject/utils';
-import { execAsync } from 'async-child-process';
-import * as _ from 'lodash';
-import * as publishRelease from 'publish-release';
-import semverSort = require('semver-sort');
-
-import { utils } from './utils';
-
-const publishReleaseAsync = promisify(publishRelease);
-const githubPersonalAccessToken = process.env.GITHUB_PERSONAL_ACCESS_TOKEN_0X_JS;
-const generatedDocsDirectoryName = 'generated_docs';
-
-export interface TagAndVersion {
-    tag: string;
-    version: string;
-}
-
-export const postpublishUtils = {
-    getLatestTagAndVersionAsync(subPackageName: string): Promise<TagAndVersion> {
-        const subPackagePrefix = `${subPackageName}@`;
-        const gitTagsCommand = `git tag -l "${subPackagePrefix}*"`;
-        return execAsync(gitTagsCommand).then((result: any) => {
-            if (!_.isEmpty(result.stderr)) {
-                throw new Error(result.stderr);
-            }
-            const tags = result.stdout.trim().split('\n');
-            const versions = tags.map((tag: string) => {
-                return tag.slice(subPackagePrefix.length);
-            });
-            const sortedVersions = semverSort.desc(versions);
-            const latestVersion = sortedVersions[0];
-            const latestTag = subPackagePrefix + latestVersion;
-            return {
-                tag: latestTag,
-                version: latestVersion,
-            };
-        });
-    },
-    publishReleaseNotesAsync(tag: string, releaseName: string, assets: string[]) {
-        utils.log('POSTPUBLISH: Releasing ', releaseName, '...');
-        return publishReleaseAsync({
-            token: githubPersonalAccessToken,
-            owner: '0xProject',
-            repo: '0x.js',
-            tag,
-            name: releaseName,
-            notes: 'N/A',
-            draft: false,
-            prerelease: false,
-            reuseRelease: true,
-            reuseDraftOnly: false,
-            assets,
-        });
-    },
-    getReleaseName(subPackageName: string, version: string): string {
-        const releaseName = `${subPackageName} v${version}`;
-        return releaseName;
-    },
-    async standardPostPublishAsync(subPackageName: string): Promise<void> {
-        const result: TagAndVersion = await this.getLatestTagAndVersionAsync(subPackageName);
-        const releaseName = this.getReleaseName(subPackageName, result.version);
-        const assets: string[] = [];
-        await this.publishReleaseNotesAsync(result.tag, releaseName, assets);
-    },
-    adjustFileIncludePaths(fileIncludes: string[], cwd: string): string[] {
-        const fileIncludesAdjusted = _.map(fileIncludes, fileInclude => {
-            let path;
-            if (_.startsWith(fileInclude, '../')) {
-                path = `${cwd}/../${fileInclude}`;
-            } else if (_.startsWith(fileInclude, './')) {
-                path = `${cwd}/../${fileInclude.substr(2)}`;
-            } else {
-                path = `${cwd}/${fileInclude}`;
-            }
-
-            // HACK: tsconfig.json needs wildcard directory endings as `/**/*`
-            // but TypeDoc needs it as `/**` in order to pick up files at the root
-            if (_.endsWith(path, '/**/*')) {
-                path = path.slice(0, -2);
-            }
-            return path;
-        });
-        return fileIncludesAdjusted;
-    },
-    generatedDocsDirectoryName,
-};
diff --git a/packages/dev-utils/src/utils.ts b/packages/dev-utils/src/utils.ts
deleted file mode 100644
index 5423cabd9..000000000
--- a/packages/dev-utils/src/utils.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export const utils = {
-    log(...args: any[]): void {
-        console.log(...args); // tslint:disable-line:no-console
-    },
-};
diff --git a/packages/dev-utils/test/.npmignore b/packages/dev-utils/test/.npmignore
new file mode 100644
index 000000000..87bc30436
--- /dev/null
+++ b/packages/dev-utils/test/.npmignore
@@ -0,0 +1,5 @@
+.*
+yarn-error.log
+/src/
+/scripts/
+tsconfig.json
diff --git a/packages/ethers-typescript-typings/monorepo_scripts/globals.d.ts b/packages/ethers-typescript-typings/monorepo_scripts/globals.d.ts
new file mode 100644
index 000000000..94e63a32d
--- /dev/null
+++ b/packages/ethers-typescript-typings/monorepo_scripts/globals.d.ts
@@ -0,0 +1,6 @@
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts b/packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/ethers-typescript-typings/package.json b/packages/ethers-typescript-typings/package.json
index 6d7601794..1e349fa93 100644
--- a/packages/ethers-typescript-typings/package.json
+++ b/packages/ethers-typescript-typings/package.json
@@ -5,7 +5,9 @@
     "main": "index.d.ts",
     "types": "index.d.ts",
     "scripts": {
-        "lint": "tslint index.d.ts"
+        "lint": "tslint index.d.ts",
+        "build": "tsc && copyfiles -u 1 './lib/**/*' ./scripts",
+        "clean": "shx rm -rf scripts"
     },
     "repository": {
         "type": "git",
@@ -21,6 +23,9 @@
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/ethers-typescript-typings#readme",
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
+        "copyfiles": "^1.2.0",
+        "shx": "^0.2.2",
         "tslint": "5.8.0",
         "tslint-config-0xproject": "^0.0.2",
         "typescript": "2.7.1"
diff --git a/packages/ethers-typescript-typings/scripts/postpublish.js b/packages/ethers-typescript-typings/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/ethers-typescript-typings/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/ethers-typescript-typings/tsconfig.json b/packages/ethers-typescript-typings/tsconfig.json
new file mode 100644
index 000000000..2599d1b7c
--- /dev/null
+++ b/packages/ethers-typescript-typings/tsconfig.json
@@ -0,0 +1,7 @@
+{
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+}
diff --git a/packages/json-schemas/package.json b/packages/json-schemas/package.json
index 8d82511b4..e775130cb 100644
--- a/packages/json-schemas/package.json
+++ b/packages/json-schemas/package.json
@@ -10,8 +10,8 @@
         "test": "run-s clean build run_mocha",
         "test:circleci": "yarn test",
         "run_mocha": "mocha lib/test/**/*_test.js",
-        "clean": "shx rm -rf _bundles lib test_temp",
-        "build": "tsc"
+        "clean": "shx rm -rf _bundles lib test_temp scripts",
+        "build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts"
     },
     "repository": {
         "type": "git",
@@ -28,6 +28,7 @@
         "lodash.values": "^4.3.0"
     },
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "@0xproject/utils": "^0.4.1",
         "@types/lodash.foreach": "^4.5.3",
@@ -35,6 +36,7 @@
         "@types/mocha": "^2.2.42",
         "chai": "^4.0.1",
         "chai-typescript-typings": "^0.0.4",
+        "copyfiles": "^1.2.0",
         "dirty-chai": "^2.0.1",
         "lodash.foreach": "^4.5.0",
         "mocha": "^4.0.1",
diff --git a/packages/json-schemas/scripts/postpublish.js b/packages/json-schemas/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/json-schemas/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/json-schemas/src/globals.d.ts b/packages/json-schemas/src/globals.d.ts
index 91ed2021e..5476b6bd8 100644
--- a/packages/json-schemas/src/globals.d.ts
+++ b/packages/json-schemas/src/globals.d.ts
@@ -1 +1,8 @@
 declare module 'dirty-chai';
+
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/json-schemas/src/monorepo_scripts/postpublish.ts b/packages/json-schemas/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/json-schemas/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json
index c9bbe0c6a..09a632c07 100644
--- a/packages/monorepo-scripts/package.json
+++ b/packages/monorepo-scripts/package.json
@@ -1,7 +1,6 @@
 {
     "name": "@0xproject/monorepo-scripts",
     "version": "0.1.12",
-    "private": true,
     "description": "Helper scripts for the monorepo",
     "scripts": {
         "build:watch": "tsc -w",
@@ -28,8 +27,12 @@
         "typescript": "2.7.1"
     },
     "dependencies": {
+        "es6-promisify": "^5.0.0",
+        "async-child-process": "^1.1.1",
+        "publish-release": "0xproject/publish-release",
         "chalk": "^2.3.0",
         "glob": "^7.1.2",
-        "lodash": "^4.17.4"
+        "lodash": "^4.17.4",
+        "semver-sort": "^0.0.4"
     }
 }
diff --git a/packages/monorepo-scripts/src/globals.d.ts b/packages/monorepo-scripts/src/globals.d.ts
new file mode 100644
index 000000000..757ae4097
--- /dev/null
+++ b/packages/monorepo-scripts/src/globals.d.ts
@@ -0,0 +1,8 @@
+declare module 'async-child-process';
+declare module 'publish-release';
+declare module 'es6-promisify';
+
+// semver-sort declarations
+declare module 'semver-sort' {
+    const desc: (versions: string[]) => string[];
+}
diff --git a/packages/monorepo-scripts/src/index.ts b/packages/monorepo-scripts/src/index.ts
new file mode 100644
index 000000000..95c96ebe8
--- /dev/null
+++ b/packages/monorepo-scripts/src/index.ts
@@ -0,0 +1 @@
+export { postpublishUtils } from './postpublish_utils';
diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts
new file mode 100644
index 000000000..2f27e15cb
--- /dev/null
+++ b/packages/monorepo-scripts/src/postpublish_utils.ts
@@ -0,0 +1,86 @@
+import * as promisify from 'es6-promisify';
+import { execAsync } from 'async-child-process';
+import * as _ from 'lodash';
+import * as publishRelease from 'publish-release';
+import semverSort = require('semver-sort');
+
+import { utils } from './utils';
+
+const publishReleaseAsync = promisify(publishRelease);
+const githubPersonalAccessToken = process.env.GITHUB_PERSONAL_ACCESS_TOKEN_0X_JS;
+const generatedDocsDirectoryName = 'generated_docs';
+
+export interface TagAndVersion {
+    tag: string;
+    version: string;
+}
+
+export const postpublishUtils = {
+    getLatestTagAndVersionAsync(subPackageName: string): Promise<TagAndVersion> {
+        const subPackagePrefix = `${subPackageName}@`;
+        const gitTagsCommand = `git tag -l "${subPackagePrefix}*"`;
+        return execAsync(gitTagsCommand).then((result: any) => {
+            if (!_.isEmpty(result.stderr)) {
+                throw new Error(result.stderr);
+            }
+            const tags = result.stdout.trim().split('\n');
+            const versions = tags.map((tag: string) => {
+                return tag.slice(subPackagePrefix.length);
+            });
+            const sortedVersions = semverSort.desc(versions);
+            const latestVersion = sortedVersions[0];
+            const latestTag = subPackagePrefix + latestVersion;
+            return {
+                tag: latestTag,
+                version: latestVersion,
+            };
+        });
+    },
+    publishReleaseNotesAsync(tag: string, releaseName: string, assets: string[]) {
+        utils.log('POSTPUBLISH: Releasing ', releaseName, '...');
+        return publishReleaseAsync({
+            token: githubPersonalAccessToken,
+            owner: '0xProject',
+            repo: '0x.js',
+            tag,
+            name: releaseName,
+            notes: 'N/A',
+            draft: false,
+            prerelease: false,
+            reuseRelease: true,
+            reuseDraftOnly: false,
+            assets,
+        });
+    },
+    getReleaseName(subPackageName: string, version: string): string {
+        const releaseName = `${subPackageName} v${version}`;
+        return releaseName;
+    },
+    async standardPostPublishAsync(subPackageName: string): Promise<void> {
+        const result: TagAndVersion = await this.getLatestTagAndVersionAsync(subPackageName);
+        const releaseName = this.getReleaseName(subPackageName, result.version);
+        const assets: string[] = [];
+        await this.publishReleaseNotesAsync(result.tag, releaseName, assets);
+    },
+    adjustFileIncludePaths(fileIncludes: string[], cwd: string): string[] {
+        const fileIncludesAdjusted = _.map(fileIncludes, fileInclude => {
+            let path;
+            if (_.startsWith(fileInclude, '../')) {
+                path = `${cwd}/../${fileInclude}`;
+            } else if (_.startsWith(fileInclude, './')) {
+                path = `${cwd}/../${fileInclude.substr(2)}`;
+            } else {
+                path = `${cwd}/${fileInclude}`;
+            }
+
+            // HACK: tsconfig.json needs wildcard directory endings as `/**/*`
+            // but TypeDoc needs it as `/**` in order to pick up files at the root
+            if (_.endsWith(path, '/**/*')) {
+                path = path.slice(0, -2);
+            }
+            return path;
+        });
+        return fileIncludesAdjusted;
+    },
+    generatedDocsDirectoryName,
+};
diff --git a/packages/monorepo-scripts/src/utils.ts b/packages/monorepo-scripts/src/utils.ts
new file mode 100644
index 000000000..5423cabd9
--- /dev/null
+++ b/packages/monorepo-scripts/src/utils.ts
@@ -0,0 +1,5 @@
+export const utils = {
+    log(...args: any[]): void {
+        console.log(...args); // tslint:disable-line:no-console
+    },
+};
diff --git a/packages/react-docs-example/package.json b/packages/react-docs-example/package.json
index 5469677d4..95a617de7 100644
--- a/packages/react-docs-example/package.json
+++ b/packages/react-docs-example/package.json
@@ -34,6 +34,7 @@
         "@types/lodash": "^4.14.86",
         "@types/node": "^8.0.53",
         "awesome-typescript-loader": "^3.1.3",
+        "copyfiles": "^1.2.0",
         "css-loader": "^0.28.9",
         "json-loader": "^0.5.4",
         "less": "^2.7.2",
diff --git a/packages/react-docs-example/ts/globals.d.ts b/packages/react-docs-example/ts/globals.d.ts
deleted file mode 100644
index 94e63a32d..000000000
--- a/packages/react-docs-example/ts/globals.d.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-declare module '*.json' {
-    const json: any;
-    /* tslint:disable */
-    export default json;
-    /* tslint:enable */
-}
diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json
index eb76fe47e..a3e6b55d8 100644
--- a/packages/react-docs/package.json
+++ b/packages/react-docs/package.json
@@ -1,52 +1,55 @@
 {
-  "name": "@0xproject/react-docs",
-  "version": "0.0.1",
-  "description": "React documentation component for rendering TypeDoc & Doxity generated JSON",
-  "main": "lib/index.js",
-  "types": "lib/index.d.ts",
-  "scripts": {
-    "lint": "tslint --project . 'src/ts/**/*.ts' 'src/ts/**/*.tsx'",
-    "build": "tsc",
-    "build:watch": "tsc -w",
-    "clean": "shx rm -rf lib"
-  },
-  "author": "Fabio Berger",
-  "license": "Apache-2.0",
-  "bugs": {
-      "url": "https://github.com/0xProject/0x-monorepo/issues"
-  },
-  "homepage": "https://github.com/0xProject/0x-monorepo/packages/react-docs/README.md",
-  "repository": {
-      "type": "git",
-      "url": "https://github.com/0xProject/0x-monorepo.git"
-  },
-  "devDependencies": {
-    "@0xproject/tslint-config": "^0.4.9",
-    "@types/lodash": "^4.14.86",
-    "@types/material-ui": "0.18.0",
-    "@types/node": "^8.0.53",
-    "@types/react": "^15.0.15",
-    "@types/react-dom": "^0.14.23",
-    "@types/react-scroll": "0.0.31",
-    "@types/react-tap-event-plugin": "0.0.30",
-    "shx": "^0.2.2",
-    "tslint": "^5.9.1",
-    "typescript": "2.7.1"
-  },
-  "dependencies": {
-    "@0xproject/react-shared": "^0.0.1",
-    "basscss": "^8.0.3",
-    "compare-versions": "^3.0.1",
-    "lodash": "^4.17.4",
-    "material-ui": "^0.17.1",
-    "react": "15.6.1",
-    "react-dom": "15.6.1",
-    "react-markdown": "^3.2.2",
-    "react-scroll": "^1.5.2",
-    "react-tap-event-plugin": "^2.0.1",
-    "react-tooltip": "^3.2.7"
-  },
-  "publishConfig": {
-    "access": "public"
-  }
+    "name": "@0xproject/react-docs",
+    "version": "0.0.1",
+    "description": "React documentation component for rendering TypeDoc & Doxity generated JSON",
+    "main": "lib/index.js",
+    "types": "lib/index.d.ts",
+    "scripts": {
+        "lint": "tslint --project . 'src/**/*.ts' 'src/**/*.tsx'",
+        "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
+        "build:watch": "tsc -w",
+        "clean": "shx rm -rf lib scripts"
+    },
+    "author": "Fabio Berger",
+    "license": "Apache-2.0",
+    "bugs": {
+        "url": "https://github.com/0xProject/0x-monorepo/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x-monorepo/packages/react-docs/README.md",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x-monorepo.git"
+    },
+    "devDependencies": {
+        "@0xproject/dev-utils": "^0.2.1",
+        "@0xproject/monorepo-scripts": "^0.1.12",
+        "@0xproject/tslint-config": "^0.4.9",
+        "@types/lodash": "^4.14.86",
+        "@types/material-ui": "0.18.0",
+        "@types/node": "^8.0.53",
+        "@types/react": "^15.0.15",
+        "@types/react-dom": "^0.14.23",
+        "@types/react-scroll": "0.0.31",
+        "@types/react-tap-event-plugin": "0.0.30",
+        "copyfiles": "^1.2.0",
+        "shx": "^0.2.2",
+        "tslint": "^5.9.1",
+        "typescript": "2.7.1"
+    },
+    "dependencies": {
+        "@0xproject/react-shared": "^0.0.1",
+        "basscss": "^8.0.3",
+        "compare-versions": "^3.0.1",
+        "lodash": "^4.17.4",
+        "material-ui": "^0.17.1",
+        "react": "15.6.1",
+        "react-dom": "15.6.1",
+        "react-markdown": "^3.2.2",
+        "react-scroll": "^1.5.2",
+        "react-tap-event-plugin": "^2.0.1",
+        "react-tooltip": "^3.2.7"
+    },
+    "publishConfig": {
+        "access": "public"
+    }
 }
diff --git a/packages/react-docs/scripts/postpublish.js b/packages/react-docs/scripts/postpublish.js
deleted file mode 100644
index 639656c7e..000000000
--- a/packages/react-docs/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
diff --git a/packages/react-docs/src/components/badge.tsx b/packages/react-docs/src/components/badge.tsx
new file mode 100644
index 000000000..b342f2dca
--- /dev/null
+++ b/packages/react-docs/src/components/badge.tsx
@@ -0,0 +1,56 @@
+import { Styles } from '@0xproject/react-shared';
+import * as _ from 'lodash';
+import * as React from 'react';
+
+const styles: Styles = {
+    badge: {
+        width: 50,
+        fontSize: 11,
+        height: 10,
+        borderRadius: 5,
+        lineHeight: 0.9,
+        fontFamily: 'Roboto Mono',
+        marginLeft: 3,
+        marginRight: 3,
+    },
+};
+
+export interface BadgeProps {
+    title: string;
+    backgroundColor: string;
+}
+
+export interface BadgeState {
+    isHovering: boolean;
+}
+
+export class Badge extends React.Component<BadgeProps, BadgeState> {
+    constructor(props: BadgeProps) {
+        super(props);
+        this.state = {
+            isHovering: false,
+        };
+    }
+    public render() {
+        const badgeStyle = {
+            ...styles.badge,
+            backgroundColor: this.props.backgroundColor,
+            opacity: this.state.isHovering ? 0.7 : 1,
+        };
+        return (
+            <div
+                className="p1 center"
+                style={badgeStyle}
+                onMouseOver={this._setHoverState.bind(this, true)}
+                onMouseOut={this._setHoverState.bind(this, false)}
+            >
+                {this.props.title}
+            </div>
+        );
+    }
+    private _setHoverState(isHovering: boolean) {
+        this.setState({
+            isHovering,
+        });
+    }
+}
diff --git a/packages/react-docs/src/components/comment.tsx b/packages/react-docs/src/components/comment.tsx
new file mode 100644
index 000000000..0d63d4d31
--- /dev/null
+++ b/packages/react-docs/src/components/comment.tsx
@@ -0,0 +1,23 @@
+import { MarkdownCodeBlock } from '@0xproject/react-shared';
+import * as _ from 'lodash';
+import * as React from 'react';
+import * as ReactMarkdown from 'react-markdown';
+
+export interface CommentProps {
+    comment: string;
+    className?: string;
+}
+
+const defaultProps = {
+    className: '',
+};
+
+export const Comment: React.SFC<CommentProps> = (props: CommentProps) => {
+    return (
+        <div className={`${props.className} comment`}>
+            <ReactMarkdown source={props.comment} renderers={{ code: MarkdownCodeBlock }} />
+        </div>
+    );
+};
+
+Comment.defaultProps = defaultProps;
diff --git a/packages/react-docs/src/components/custom_enum.tsx b/packages/react-docs/src/components/custom_enum.tsx
new file mode 100644
index 000000000..deb33ff1d
--- /dev/null
+++ b/packages/react-docs/src/components/custom_enum.tsx
@@ -0,0 +1,33 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { CustomType } from '../types';
+import { utils } from '../utils/utils';
+
+const STRING_ENUM_CODE_PREFIX = ' strEnum(';
+
+export interface CustomEnumProps {
+    type: CustomType;
+}
+
+// This component renders custom string enums that was a work-around for versions of
+// TypeScript <2.4.0 that did not support them natively. We keep it around to support
+// older versions of 0x.js <0.9.0
+export function CustomEnum(props: CustomEnumProps) {
+    const type = props.type;
+    if (!_.startsWith(type.defaultValue, STRING_ENUM_CODE_PREFIX)) {
+        utils.consoleLog('We do not yet support `Variable` types that are not strEnums');
+        return null;
+    }
+    // Remove the prefix and postfix, leaving only the strEnum values without quotes.
+    const enumValues = type.defaultValue.slice(10, -3).replace(/'/g, '');
+    return (
+        <span>
+            {`{`}
+            {'\t'}
+            {enumValues}
+            <br />
+            {`}`}
+        </span>
+    );
+}
diff --git a/packages/react-docs/src/components/documentation.tsx b/packages/react-docs/src/components/documentation.tsx
new file mode 100644
index 000000000..b46358159
--- /dev/null
+++ b/packages/react-docs/src/components/documentation.tsx
@@ -0,0 +1,375 @@
+import {
+    colors,
+    constants as sharedConstants,
+    EtherscanLinkSuffixes,
+    MarkdownSection,
+    MenuSubsectionsBySection,
+    NestedSidebarMenu,
+    Networks,
+    SectionHeader,
+    Styles,
+    utils as sharedUtils,
+} from '@0xproject/react-shared';
+import * as _ from 'lodash';
+import CircularProgress from 'material-ui/CircularProgress';
+import * as React from 'react';
+import { scroller } from 'react-scroll';
+
+import { DocsInfo } from '../docs_info';
+import {
+    AddressByContractName,
+    DocAgnosticFormat,
+    DoxityDocObj,
+    Event,
+    Property,
+    SolidityMethod,
+    SupportedDocJson,
+    TypeDefinitionByName,
+    TypescriptMethod,
+} from '../types';
+import { constants } from '../utils/constants';
+import { utils } from '../utils/utils';
+
+import { Badge } from './badge';
+import { Comment } from './comment';
+import { EventDefinition } from './event_definition';
+import { MethodBlock } from './method_block';
+import { SourceLink } from './source_link';
+import { Type } from './type';
+import { TypeDefinition } from './type_definition';
+
+const networkNameToColor: { [network: string]: string } = {
+    [Networks.Kovan]: colors.purple,
+    [Networks.Ropsten]: colors.red,
+    [Networks.Mainnet]: colors.turquois,
+    [Networks.Rinkeby]: colors.darkYellow,
+};
+
+export interface DocumentationProps {
+    selectedVersion: string;
+    availableVersions: string[];
+    docsInfo: DocsInfo;
+    sourceUrl: string;
+    onVersionSelected: (semver: string) => void;
+    docAgnosticFormat?: DocAgnosticFormat;
+    sidebarHeader?: React.ReactNode;
+    topBarHeight?: number;
+}
+
+export interface DocumentationState {
+    isHoveringSidebar: boolean;
+}
+
+export class Documentation extends React.Component<DocumentationProps, DocumentationState> {
+    public static defaultProps: Partial<DocumentationProps> = {
+        topBarHeight: 0,
+    };
+    constructor(props: DocumentationProps) {
+        super(props);
+        this.state = {
+            isHoveringSidebar: false,
+        };
+    }
+    public componentDidMount() {
+        window.addEventListener('hashchange', this._onHashChanged.bind(this), false);
+    }
+    public componentWillUnmount() {
+        window.removeEventListener('hashchange', this._onHashChanged.bind(this), false);
+    }
+    public componentDidUpdate(prevProps: DocumentationProps, prevState: DocumentationState) {
+        if (!_.isEqual(prevProps.docAgnosticFormat, this.props.docAgnosticFormat)) {
+            const hash = window.location.hash.slice(1);
+            sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID);
+        }
+    }
+    public render() {
+        const styles: Styles = {
+            mainContainers: {
+                position: 'absolute',
+                top: 1,
+                left: 0,
+                bottom: 0,
+                right: 0,
+                overflowZ: 'hidden',
+                overflowY: 'scroll',
+                minHeight: `calc(100vh - ${this.props.topBarHeight}px)`,
+                WebkitOverflowScrolling: 'touch',
+            },
+            menuContainer: {
+                borderColor: colors.grey300,
+                maxWidth: 330,
+                marginLeft: 20,
+            },
+        };
+        const menuSubsectionsBySection = this.props.docsInfo.getMenuSubsectionsBySection(this.props.docAgnosticFormat);
+        return (
+            <div>
+                {_.isUndefined(this.props.docAgnosticFormat) ? (
+                    this._renderLoading(styles.mainContainers)
+                ) : (
+                    <div style={{ width: '100%', height: '100%', backgroundColor: colors.gray40 }}>
+                        <div
+                            className="mx-auto max-width-4 flex"
+                            style={{ color: colors.grey800, height: `calc(100vh - ${this.props.topBarHeight}px)` }}
+                        >
+                            <div
+                                className="relative sm-hide xs-hide"
+                                style={{ width: '36%', height: `calc(100vh - ${this.props.topBarHeight}px)` }}
+                            >
+                                <div
+                                    className="border-right absolute"
+                                    style={{
+                                        ...styles.menuContainer,
+                                        ...styles.mainContainers,
+                                        height: `calc(100vh - ${this.props.topBarHeight}px)`,
+                                        overflow: this.state.isHoveringSidebar ? 'auto' : 'hidden',
+                                    }}
+                                    onMouseEnter={this._onSidebarHover.bind(this)}
+                                    onMouseLeave={this._onSidebarHoverOff.bind(this)}
+                                >
+                                    <NestedSidebarMenu
+                                        selectedVersion={this.props.selectedVersion}
+                                        versions={this.props.availableVersions}
+                                        sidebarHeader={this.props.sidebarHeader}
+                                        topLevelMenu={this.props.docsInfo.getMenu(this.props.selectedVersion)}
+                                        menuSubsectionsBySection={menuSubsectionsBySection}
+                                        onVersionSelected={this.props.onVersionSelected}
+                                    />
+                                </div>
+                            </div>
+                            <div
+                                className="relative col lg-col-9 md-col-9 sm-col-12 col-12"
+                                style={{ backgroundColor: colors.white }}
+                            >
+                                <div
+                                    id={sharedConstants.SCROLL_CONTAINER_ID}
+                                    style={styles.mainContainers}
+                                    className="absolute px1"
+                                >
+                                    <div id={sharedConstants.SCROLL_TOP_ID} />
+                                    {this._renderDocumentation()}
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                )}
+            </div>
+        );
+    }
+    private _renderLoading(mainContainersStyles: React.CSSProperties) {
+        return (
+            <div className="col col-12" style={mainContainersStyles}>
+                <div
+                    className="relative sm-px2 sm-pt2 sm-m1"
+                    style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
+                >
+                    <div className="center pb2">
+                        <CircularProgress size={40} thickness={5} />
+                    </div>
+                    <div className="center pt2" style={{ paddingBottom: 11 }}>
+                        Loading documentation...
+                    </div>
+                </div>
+            </div>
+        );
+    }
+    private _renderDocumentation(): React.ReactNode {
+        const subMenus = _.values(this.props.docsInfo.getMenu());
+        const orderedSectionNames = _.flatten(subMenus);
+
+        const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.props.docAgnosticFormat);
+        const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName));
+
+        return renderedSections;
+    }
+    private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode {
+        const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdown[sectionName];
+        if (!_.isUndefined(markdownFileIfExists)) {
+            return (
+                <MarkdownSection
+                    key={`markdown-section-${sectionName}`}
+                    sectionName={sectionName}
+                    markdownContent={markdownFileIfExists}
+                />
+            );
+        }
+
+        const docSection = this.props.docAgnosticFormat[sectionName];
+        if (_.isUndefined(docSection)) {
+            return null;
+        }
+
+        const sortedTypes = _.sortBy(docSection.types, 'name');
+        const typeDefs = _.map(sortedTypes, customType => {
+            return (
+                <TypeDefinition
+                    sectionName={sectionName}
+                    key={`type-${customType.name}`}
+                    customType={customType}
+                    docsInfo={this.props.docsInfo}
+                />
+            );
+        });
+
+        const sortedProperties = _.sortBy(docSection.properties, 'name');
+        const propertyDefs = _.map(sortedProperties, this._renderProperty.bind(this, sectionName));
+
+        const sortedMethods = _.sortBy(docSection.methods, 'name');
+        const methodDefs = _.map(sortedMethods, method => {
+            const isConstructor = false;
+            return this._renderMethodBlocks(method, sectionName, isConstructor, typeDefinitionByName);
+        });
+
+        const sortedEvents = _.sortBy(docSection.events, 'name');
+        const eventDefs = _.map(sortedEvents, (event: Event, i: number) => {
+            return (
+                <EventDefinition
+                    key={`event-${event.name}-${i}`}
+                    event={event}
+                    sectionName={sectionName}
+                    docsInfo={this.props.docsInfo}
+                />
+            );
+        });
+        const headerStyle: React.CSSProperties = {
+            fontWeight: 100,
+        };
+        return (
+            <div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
+                <div className="flex pb2">
+                    <div style={{ marginRight: 7 }}>
+                        <SectionHeader sectionName={sectionName} />
+                    </div>
+                    {this._renderNetworkBadgesIfExists(sectionName)}
+                </div>
+                {docSection.comment && <Comment comment={docSection.comment} />}
+                {docSection.constructors.length > 0 &&
+                    this.props.docsInfo.isVisibleConstructor(sectionName) && (
+                        <div>
+                            <h2 style={headerStyle}>Constructor</h2>
+                            {this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)}
+                        </div>
+                    )}
+                {docSection.properties.length > 0 && (
+                    <div>
+                        <h2 style={headerStyle}>Properties</h2>
+                        <div>{propertyDefs}</div>
+                    </div>
+                )}
+                {docSection.methods.length > 0 && (
+                    <div>
+                        <h2 style={headerStyle}>Methods</h2>
+                        <div>{methodDefs}</div>
+                    </div>
+                )}
+                {!_.isUndefined(docSection.events) &&
+                    docSection.events.length > 0 && (
+                        <div>
+                            <h2 style={headerStyle}>Events</h2>
+                            <div>{eventDefs}</div>
+                        </div>
+                    )}
+                {!_.isUndefined(typeDefs) &&
+                    typeDefs.length > 0 && (
+                        <div>
+                            <div>{typeDefs}</div>
+                        </div>
+                    )}
+            </div>
+        );
+    }
+    private _renderNetworkBadgesIfExists(sectionName: string) {
+        if (this.props.docsInfo.type !== SupportedDocJson.Doxity) {
+            return null;
+        }
+
+        const networkToAddressByContractName = this.props.docsInfo.contractsByVersionByNetworkId[
+            this.props.selectedVersion
+        ];
+        const badges = _.map(
+            networkToAddressByContractName,
+            (addressByContractName: AddressByContractName, networkName: string) => {
+                const contractAddress = addressByContractName[sectionName];
+                if (_.isUndefined(contractAddress)) {
+                    return null;
+                }
+                const linkIfExists = sharedUtils.getEtherScanLinkIfExists(
+                    contractAddress,
+                    sharedConstants.NETWORK_ID_BY_NAME[networkName],
+                    EtherscanLinkSuffixes.Address,
+                );
+                return (
+                    <a
+                        key={`badge-${networkName}-${sectionName}`}
+                        href={linkIfExists}
+                        target="_blank"
+                        style={{ color: colors.white, textDecoration: 'none' }}
+                    >
+                        <Badge title={networkName} backgroundColor={networkNameToColor[networkName]} />
+                    </a>
+                );
+            },
+        );
+        return badges;
+    }
+    private _renderConstructors(
+        constructors: SolidityMethod[] | TypescriptMethod[],
+        sectionName: string,
+        typeDefinitionByName: TypeDefinitionByName,
+    ): React.ReactNode {
+        const constructorDefs = _.map(constructors, constructor => {
+            return this._renderMethodBlocks(constructor, sectionName, constructor.isConstructor, typeDefinitionByName);
+        });
+        return <div>{constructorDefs}</div>;
+    }
+    private _renderProperty(sectionName: string, property: Property): React.ReactNode {
+        return (
+            <div key={`property-${property.name}-${property.type.name}`} className="pb3">
+                <code className={`hljs ${constants.TYPE_TO_SYNTAX[this.props.docsInfo.type]}`}>
+                    {property.name}:
+                    <Type type={property.type} sectionName={sectionName} docsInfo={this.props.docsInfo} />
+                </code>
+                {property.source && (
+                    <SourceLink
+                        version={this.props.selectedVersion}
+                        source={property.source}
+                        sourceUrl={this.props.sourceUrl}
+                    />
+                )}
+                {property.comment && <Comment comment={property.comment} className="py2" />}
+            </div>
+        );
+    }
+    private _renderMethodBlocks(
+        method: SolidityMethod | TypescriptMethod,
+        sectionName: string,
+        isConstructor: boolean,
+        typeDefinitionByName: TypeDefinitionByName,
+    ): React.ReactNode {
+        return (
+            <MethodBlock
+                key={`method-${method.name}-${sectionName}`}
+                sectionName={sectionName}
+                method={method}
+                typeDefinitionByName={typeDefinitionByName}
+                libraryVersion={this.props.selectedVersion}
+                docsInfo={this.props.docsInfo}
+                sourceUrl={this.props.sourceUrl}
+            />
+        );
+    }
+    private _onSidebarHover(event: React.FormEvent<HTMLInputElement>) {
+        this.setState({
+            isHoveringSidebar: true,
+        });
+    }
+    private _onSidebarHoverOff() {
+        this.setState({
+            isHoveringSidebar: false,
+        });
+    }
+    private _onHashChanged(event: any) {
+        const hash = window.location.hash.slice(1);
+        sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID);
+    }
+}
diff --git a/packages/react-docs/src/components/enum.tsx b/packages/react-docs/src/components/enum.tsx
new file mode 100644
index 000000000..37f82f26e
--- /dev/null
+++ b/packages/react-docs/src/components/enum.tsx
@@ -0,0 +1,23 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { EnumValue } from '../types';
+
+export interface EnumProps {
+    values: EnumValue[];
+}
+
+export function Enum(props: EnumProps) {
+    const values = _.map(props.values, (value, i) => {
+        const defaultValueIfAny = !_.isUndefined(value.defaultValue) ? ` = ${value.defaultValue}` : '';
+        return `\n\t${value.name}${defaultValueIfAny},`;
+    });
+    return (
+        <span>
+            {`{`}
+            {values}
+            <br />
+            {`}`}
+        </span>
+    );
+}
diff --git a/packages/react-docs/src/components/event_definition.tsx b/packages/react-docs/src/components/event_definition.tsx
new file mode 100644
index 000000000..67729ac87
--- /dev/null
+++ b/packages/react-docs/src/components/event_definition.tsx
@@ -0,0 +1,84 @@
+import { AnchorTitle, colors, HeaderSizes } from '@0xproject/react-shared';
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { DocsInfo } from '../docs_info';
+import { Event, EventArg } from '../types';
+
+import { Type } from './type';
+
+export interface EventDefinitionProps {
+    event: Event;
+    sectionName: string;
+    docsInfo: DocsInfo;
+}
+
+export interface EventDefinitionState {
+    shouldShowAnchor: boolean;
+}
+
+export class EventDefinition extends React.Component<EventDefinitionProps, EventDefinitionState> {
+    constructor(props: EventDefinitionProps) {
+        super(props);
+        this.state = {
+            shouldShowAnchor: false,
+        };
+    }
+    public render() {
+        const event = this.props.event;
+        const id = `${this.props.sectionName}-${event.name}`;
+        return (
+            <div
+                id={id}
+                className="pb2"
+                style={{ overflow: 'hidden', width: '100%' }}
+                onMouseOver={this._setAnchorVisibility.bind(this, true)}
+                onMouseOut={this._setAnchorVisibility.bind(this, false)}
+            >
+                <AnchorTitle
+                    headerSize={HeaderSizes.H3}
+                    title={`Event ${event.name}`}
+                    id={id}
+                    shouldShowAnchor={this.state.shouldShowAnchor}
+                />
+                <div style={{ fontSize: 16 }}>
+                    <pre>
+                        <code className="hljs solidity">{this._renderEventCode()}</code>
+                    </pre>
+                </div>
+            </div>
+        );
+    }
+    private _renderEventCode() {
+        const indexed = <span style={{ color: colors.green }}> indexed</span>;
+        const eventArgs = _.map(this.props.event.eventArgs, (eventArg: EventArg) => {
+            const type = (
+                <Type type={eventArg.type} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
+            );
+            return (
+                <span key={`eventArg-${eventArg.name}`}>
+                    {eventArg.name}
+                    {eventArg.isIndexed ? indexed : ''}: {type},
+                </span>
+            );
+        });
+        const argList = _.reduce(eventArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
+            return [prev, '\n\t', curr];
+        });
+        return (
+            <span>
+                {`{`}
+                <br />
+                {'\t'}
+                {argList}
+                <br />
+                {`}`}
+            </span>
+        );
+    }
+    private _setAnchorVisibility(shouldShowAnchor: boolean) {
+        this.setState({
+            shouldShowAnchor,
+        });
+    }
+}
diff --git a/packages/react-docs/src/components/interface.tsx b/packages/react-docs/src/components/interface.tsx
new file mode 100644
index 000000000..01f4942ef
--- /dev/null
+++ b/packages/react-docs/src/components/interface.tsx
@@ -0,0 +1,63 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { DocsInfo } from '../docs_info';
+import { CustomType, TypeDocTypes } from '../types';
+
+import { MethodSignature } from './method_signature';
+import { Type } from './type';
+
+export interface InterfaceProps {
+    type: CustomType;
+    sectionName: string;
+    docsInfo: DocsInfo;
+}
+
+export function Interface(props: InterfaceProps) {
+    const type = props.type;
+    const properties = _.map(type.children, property => {
+        return (
+            <span key={`property-${property.name}-${property.type}-${type.name}`}>
+                {property.name}:{' '}
+                {property.type.typeDocType !== TypeDocTypes.Reflection ? (
+                    <Type type={property.type} sectionName={props.sectionName} docsInfo={props.docsInfo} />
+                ) : (
+                    <MethodSignature
+                        method={property.type.method}
+                        sectionName={props.sectionName}
+                        shouldHideMethodName={true}
+                        shouldUseArrowSyntax={true}
+                        docsInfo={props.docsInfo}
+                    />
+                )},
+            </span>
+        );
+    });
+    const hasIndexSignature = !_.isUndefined(type.indexSignature);
+    if (hasIndexSignature) {
+        const is = type.indexSignature;
+        const param = (
+            <span key={`indexSigParams-${is.keyName}-${is.keyType}-${type.name}`}>
+                {is.keyName}: <Type type={is.keyType} sectionName={props.sectionName} docsInfo={props.docsInfo} />
+            </span>
+        );
+        properties.push(
+            <span key={`indexSignature-${type.name}-${is.keyType.name}`}>
+                [{param}]: {is.valueName},
+            </span>,
+        );
+    }
+    const propertyList = _.reduce(properties, (prev: React.ReactNode, curr: React.ReactNode) => {
+        return [prev, '\n\t', curr];
+    });
+    return (
+        <span>
+            {`{`}
+            <br />
+            {'\t'}
+            {propertyList}
+            <br />
+            {`}`}
+        </span>
+    );
+}
diff --git a/packages/react-docs/src/components/method_block.tsx b/packages/react-docs/src/components/method_block.tsx
new file mode 100644
index 000000000..44a1db8af
--- /dev/null
+++ b/packages/react-docs/src/components/method_block.tsx
@@ -0,0 +1,150 @@
+import { AnchorTitle, colors, HeaderSizes, Styles } from '@0xproject/react-shared';
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { DocsInfo } from '../docs_info';
+import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptMethod } from '../types';
+import { constants } from '../utils/constants';
+import { typeDocUtils } from '../utils/typedoc_utils';
+
+import { Comment } from './comment';
+import { MethodSignature } from './method_signature';
+import { SourceLink } from './source_link';
+
+export interface MethodBlockProps {
+    method: SolidityMethod | TypescriptMethod;
+    sectionName: string;
+    libraryVersion: string;
+    typeDefinitionByName: TypeDefinitionByName;
+    docsInfo: DocsInfo;
+    sourceUrl: string;
+}
+
+export interface MethodBlockState {
+    shouldShowAnchor: boolean;
+}
+
+const styles: Styles = {
+    chip: {
+        fontSize: 13,
+        backgroundColor: colors.lightBlueA700,
+        color: colors.white,
+        height: 11,
+        borderRadius: 14,
+        lineHeight: 0.9,
+    },
+};
+
+export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockState> {
+    constructor(props: MethodBlockProps) {
+        super(props);
+        this.state = {
+            shouldShowAnchor: false,
+        };
+    }
+    public render() {
+        const method = this.props.method;
+        if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) {
+            return null;
+        }
+
+        return (
+            <div
+                id={`${this.props.sectionName}-${method.name}`}
+                style={{ overflow: 'hidden', width: '100%' }}
+                className="pb4"
+                onMouseOver={this._setAnchorVisibility.bind(this, true)}
+                onMouseOut={this._setAnchorVisibility.bind(this, false)}
+            >
+                {!method.isConstructor && (
+                    <div className="flex pb2 pt2">
+                        {(method as TypescriptMethod).isStatic && this._renderChip('Static')}
+                        {(method as SolidityMethod).isConstant && this._renderChip('Constant')}
+                        {(method as SolidityMethod).isPayable && this._renderChip('Payable')}
+                        <div style={{ lineHeight: 1.3 }}>
+                            <AnchorTitle
+                                headerSize={HeaderSizes.H3}
+                                title={method.name}
+                                id={`${this.props.sectionName}-${method.name}`}
+                                shouldShowAnchor={this.state.shouldShowAnchor}
+                            />
+                        </div>
+                    </div>
+                )}
+                <code className={`hljs ${constants.TYPE_TO_SYNTAX[this.props.docsInfo.type]}`}>
+                    <MethodSignature
+                        method={method}
+                        sectionName={this.props.sectionName}
+                        typeDefinitionByName={this.props.typeDefinitionByName}
+                        docsInfo={this.props.docsInfo}
+                    />
+                </code>
+                {(method as TypescriptMethod).source && (
+                    <SourceLink
+                        version={this.props.libraryVersion}
+                        source={(method as TypescriptMethod).source}
+                        sourceUrl={this.props.sourceUrl}
+                    />
+                )}
+                {method.comment && <Comment comment={method.comment} className="py2" />}
+                {method.parameters &&
+                    !_.isEmpty(method.parameters) && (
+                        <div>
+                            <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
+                                ARGUMENTS
+                            </h4>
+                            {this._renderParameterDescriptions(method.parameters)}
+                        </div>
+                    )}
+                {method.returnComment && (
+                    <div className="pt1 comment">
+                        <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
+                            RETURNS
+                        </h4>
+                        <Comment comment={method.returnComment} />
+                    </div>
+                )}
+            </div>
+        );
+    }
+    private _renderChip(text: string) {
+        return (
+            <div className="p1 mr1" style={styles.chip}>
+                {text}
+            </div>
+        );
+    }
+    private _renderParameterDescriptions(parameters: Parameter[]) {
+        const descriptions = _.map(parameters, parameter => {
+            const isOptional = parameter.isOptional;
+            return (
+                <div
+                    key={`param-description-${parameter.name}`}
+                    className="flex pb1 mb2"
+                    style={{ borderBottom: '1px solid #f0f4f7' }}
+                >
+                    <div className="pl2 col lg-col-4 md-col-4 sm-col-12 col-12">
+                        <div
+                            className="bold"
+                            style={{ overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }}
+                        >
+                            {parameter.name}
+                        </div>
+                        <div className="pt1" style={{ color: colors.grey, fontSize: 14 }}>
+                            {isOptional && 'optional'}
+                        </div>
+                    </div>
+                    <div className="col lg-col-8 md-col-8 sm-col-12 col-12" style={{ paddingLeft: 5 }}>
+                        {parameter.comment && <Comment comment={parameter.comment} />}
+                    </div>
+                </div>
+            );
+        });
+        return descriptions;
+    }
+    private _setAnchorVisibility(shouldShowAnchor: boolean) {
+        this.setState({
+            shouldShowAnchor,
+        });
+    }
+}
diff --git a/packages/react-docs/src/components/method_signature.tsx b/packages/react-docs/src/components/method_signature.tsx
new file mode 100644
index 000000000..1400182ea
--- /dev/null
+++ b/packages/react-docs/src/components/method_signature.tsx
@@ -0,0 +1,128 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+import * as ReactDOM from 'react-dom';
+
+import { DocsInfo } from '../docs_info';
+import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptMethod } from '../types';
+import { constants } from '../utils/constants';
+
+import { Type } from './type';
+
+export interface MethodSignatureProps {
+    method: TypescriptMethod | SolidityMethod;
+    sectionName: string;
+    shouldHideMethodName?: boolean;
+    shouldUseArrowSyntax?: boolean;
+    typeDefinitionByName?: TypeDefinitionByName;
+    docsInfo: DocsInfo;
+}
+
+const defaultProps = {
+    shouldHideMethodName: false,
+    shouldUseArrowSyntax: false,
+};
+
+export const MethodSignature: React.SFC<MethodSignatureProps> = (props: MethodSignatureProps) => {
+    const sectionName = constants.TYPES_SECTION_NAME;
+    const parameters = renderParameters(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
+    const paramStringArray: any[] = [];
+    // HACK: For now we don't put params on newlines if there are less then 2 of them.
+    // Ideally we would check the character length of the resulting method signature and
+    // if it exceeds the available space, put params on their own lines.
+    const hasMoreThenTwoParams = parameters.length > 2;
+    _.each(parameters, (param: React.ReactNode, i: number) => {
+        const finalParam = hasMoreThenTwoParams ? (
+            <span className="pl2" key={`param-${i}`}>
+                {param}
+            </span>
+        ) : (
+            param
+        );
+        paramStringArray.push(finalParam);
+        const comma = hasMoreThenTwoParams ? (
+            <span key={`param-comma-${i}`}>
+                , <br />
+            </span>
+        ) : (
+            ', '
+        );
+        paramStringArray.push(comma);
+    });
+    if (!hasMoreThenTwoParams) {
+        paramStringArray.pop();
+    }
+    const methodName = props.shouldHideMethodName ? '' : props.method.name;
+    const typeParameterIfExists = _.isUndefined((props.method as TypescriptMethod).typeParameter)
+        ? undefined
+        : renderTypeParameter(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
+    return (
+        <span style={{ fontSize: 15 }}>
+            {props.method.callPath}
+            {methodName}
+            {typeParameterIfExists}({hasMoreThenTwoParams && <br />}
+            {paramStringArray})
+            {props.method.returnType && (
+                <span>
+                    {props.shouldUseArrowSyntax ? ' => ' : ': '}{' '}
+                    <Type
+                        type={props.method.returnType}
+                        sectionName={sectionName}
+                        typeDefinitionByName={props.typeDefinitionByName}
+                        docsInfo={props.docsInfo}
+                    />
+                </span>
+            )}
+        </span>
+    );
+};
+
+MethodSignature.defaultProps = defaultProps;
+
+function renderParameters(
+    method: TypescriptMethod | SolidityMethod,
+    docsInfo: DocsInfo,
+    sectionName: string,
+    typeDefinitionByName?: TypeDefinitionByName,
+) {
+    const parameters = method.parameters;
+    const params = _.map(parameters, (p: Parameter) => {
+        const isOptional = p.isOptional;
+        const type = (
+            <Type
+                type={p.type}
+                sectionName={sectionName}
+                typeDefinitionByName={typeDefinitionByName}
+                docsInfo={docsInfo}
+            />
+        );
+        return (
+            <span key={`param-${p.type}-${p.name}`}>
+                {p.name}
+                {isOptional && '?'}: {type}
+            </span>
+        );
+    });
+    return params;
+}
+
+function renderTypeParameter(
+    method: TypescriptMethod,
+    docsInfo: DocsInfo,
+    sectionName: string,
+    typeDefinitionByName?: TypeDefinitionByName,
+) {
+    const typeParameter = method.typeParameter;
+    const typeParam = (
+        <span>
+            {`<${typeParameter.name} extends `}
+            <Type
+                type={typeParameter.type}
+                sectionName={sectionName}
+                typeDefinitionByName={typeDefinitionByName}
+                docsInfo={docsInfo}
+            />
+            {`>`}
+        </span>
+    );
+    return typeParam;
+}
diff --git a/packages/react-docs/src/components/source_link.tsx b/packages/react-docs/src/components/source_link.tsx
new file mode 100644
index 000000000..89956a507
--- /dev/null
+++ b/packages/react-docs/src/components/source_link.tsx
@@ -0,0 +1,23 @@
+import { colors } from '@0xproject/react-shared';
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { Source } from '../types';
+
+export interface SourceLinkProps {
+    source: Source;
+    sourceUrl: string;
+    version: string;
+}
+
+export function SourceLink(props: SourceLinkProps) {
+    const src = props.source;
+    const sourceCodeUrl = `${props.sourceUrl}/${src.fileName}#L${src.line}`;
+    return (
+        <div className="pt2" style={{ fontSize: 14 }}>
+            <a href={sourceCodeUrl} target="_blank" className="underline" style={{ color: colors.grey }}>
+                Source
+            </a>
+        </div>
+    );
+}
diff --git a/packages/react-docs/src/components/type.tsx b/packages/react-docs/src/components/type.tsx
new file mode 100644
index 000000000..56425a5df
--- /dev/null
+++ b/packages/react-docs/src/components/type.tsx
@@ -0,0 +1,227 @@
+import { colors, constants as sharedConstants, utils as sharedUtils } from '@0xproject/react-shared';
+import * as _ from 'lodash';
+import * as React from 'react';
+import { Link as ScrollLink } from 'react-scroll';
+import * as ReactTooltip from 'react-tooltip';
+
+import { DocsInfo } from '../docs_info';
+import { Type as TypeDef, TypeDefinitionByName, TypeDocTypes } from '../types';
+import { constants } from '../utils/constants';
+import { utils } from '../utils/utils';
+
+import { TypeDefinition } from './type_definition';
+
+const typeToSection: { [typeName: string]: string } = {
+    ExchangeWrapper: 'exchange',
+    TokenWrapper: 'token',
+    TokenRegistryWrapper: 'tokenRegistry',
+    EtherTokenWrapper: 'etherToken',
+    ProxyWrapper: 'proxy',
+    TokenTransferProxyWrapper: 'proxy',
+    OrderStateWatcher: 'orderWatcher',
+};
+
+export interface TypeProps {
+    type: TypeDef;
+    docsInfo: DocsInfo;
+    sectionName: string;
+    typeDefinitionByName?: TypeDefinitionByName;
+}
+
+// The return type needs to be `any` here so that we can recursively define <Type /> components within
+// <Type /> components (e.g when rendering the union type).
+export function Type(props: TypeProps): any {
+    const type = props.type;
+    const isReference = type.typeDocType === TypeDocTypes.Reference;
+    const isArray = type.typeDocType === TypeDocTypes.Array;
+    let typeNameColor = 'inherit';
+    let typeName: string | React.ReactNode;
+    let typeArgs: React.ReactNode[] = [];
+    switch (type.typeDocType) {
+        case TypeDocTypes.Intrinsic:
+        case TypeDocTypes.Unknown:
+            typeName = type.name;
+            typeNameColor = colors.orange;
+            break;
+
+        case TypeDocTypes.Reference:
+            typeName = type.name;
+            typeArgs = _.map(type.typeArguments, (arg: TypeDef) => {
+                if (arg.typeDocType === TypeDocTypes.Array) {
+                    const key = `type-${arg.elementType.name}-${arg.elementType.typeDocType}`;
+                    return (
+                        <span>
+                            <Type
+                                key={key}
+                                type={arg.elementType}
+                                sectionName={props.sectionName}
+                                typeDefinitionByName={props.typeDefinitionByName}
+                                docsInfo={props.docsInfo}
+                            />[]
+                        </span>
+                    );
+                } else {
+                    const subType = (
+                        <Type
+                            key={`type-${arg.name}-${arg.value}-${arg.typeDocType}`}
+                            type={arg}
+                            sectionName={props.sectionName}
+                            typeDefinitionByName={props.typeDefinitionByName}
+                            docsInfo={props.docsInfo}
+                        />
+                    );
+                    return subType;
+                }
+            });
+            break;
+
+        case TypeDocTypes.StringLiteral:
+            typeName = `'${type.value}'`;
+            typeNameColor = colors.green;
+            break;
+
+        case TypeDocTypes.Array:
+            typeName = type.elementType.name;
+            break;
+
+        case TypeDocTypes.Union:
+            const unionTypes = _.map(type.types, t => {
+                return (
+                    <Type
+                        key={`type-${t.name}-${t.value}-${t.typeDocType}`}
+                        type={t}
+                        sectionName={props.sectionName}
+                        typeDefinitionByName={props.typeDefinitionByName}
+                        docsInfo={props.docsInfo}
+                    />
+                );
+            });
+            typeName = _.reduce(unionTypes, (prev: React.ReactNode, curr: React.ReactNode) => {
+                return [prev, '|', curr];
+            });
+            break;
+
+        case TypeDocTypes.TypeParameter:
+            typeName = type.name;
+            break;
+
+        case TypeDocTypes.Intersection:
+            const intersectionsTypes = _.map(type.types, t => {
+                return (
+                    <Type
+                        key={`type-${t.name}-${t.value}-${t.typeDocType}`}
+                        type={t}
+                        sectionName={props.sectionName}
+                        typeDefinitionByName={props.typeDefinitionByName}
+                        docsInfo={props.docsInfo}
+                    />
+                );
+            });
+            typeName = _.reduce(intersectionsTypes, (prev: React.ReactNode, curr: React.ReactNode) => {
+                return [prev, '&', curr];
+            });
+            break;
+
+        default:
+            throw utils.spawnSwitchErr('type.typeDocType', type.typeDocType);
+    }
+    // HACK: Normalize BigNumber to simply BigNumber. For some reason the type
+    // name is unpredictably one or the other.
+    if (typeName === 'BigNumber') {
+        typeName = 'BigNumber';
+    }
+    const commaSeparatedTypeArgs = _.reduce(typeArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
+        return [prev, ', ', curr];
+    });
+
+    let typeNameUrlIfExists;
+    let typePrefixIfExists;
+    let sectionNameIfExists;
+    if (!_.isUndefined(props.docsInfo.typeConfigs)) {
+        typeNameUrlIfExists = !_.isUndefined(props.docsInfo.typeConfigs.typeNameToExternalLink)
+            ? props.docsInfo.typeConfigs.typeNameToExternalLink[typeName as string]
+            : undefined;
+        typePrefixIfExists = !_.isUndefined(props.docsInfo.typeConfigs.typeNameToPrefix)
+            ? props.docsInfo.typeConfigs.typeNameToPrefix[typeName as string]
+            : undefined;
+        sectionNameIfExists = !_.isUndefined(props.docsInfo.typeConfigs.typeNameToDocSection)
+            ? props.docsInfo.typeConfigs.typeNameToDocSection[typeName as string]
+            : undefined;
+    }
+    if (!_.isUndefined(typeNameUrlIfExists)) {
+        typeName = (
+            <a
+                href={typeNameUrlIfExists}
+                target="_blank"
+                className="text-decoration-none"
+                style={{ color: colors.lightBlueA700 }}
+            >
+                {!_.isUndefined(typePrefixIfExists) ? `${typePrefixIfExists}.` : ''}
+                {typeName}
+            </a>
+        );
+    } else if (
+        (isReference || isArray) &&
+        (props.docsInfo.isPublicType(typeName as string) || !_.isUndefined(sectionNameIfExists))
+    ) {
+        const id = Math.random().toString();
+        const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists)
+            ? `${props.sectionName}-${typeName}`
+            : sectionNameIfExists;
+        let typeDefinition;
+        if (props.typeDefinitionByName) {
+            typeDefinition = props.typeDefinitionByName[typeName as string];
+        }
+        typeName = (
+            <ScrollLink
+                to={typeDefinitionAnchorId}
+                offset={0}
+                duration={sharedConstants.DOCS_SCROLL_DURATION_MS}
+                containerId={sharedConstants.DOCS_CONTAINER_ID}
+            >
+                {_.isUndefined(typeDefinition) || sharedUtils.isUserOnMobile() ? (
+                    <span
+                        onClick={sharedUtils.setUrlHash.bind(null, typeDefinitionAnchorId)}
+                        style={{ color: colors.lightBlueA700, cursor: 'pointer' }}
+                    >
+                        {typeName}
+                    </span>
+                ) : (
+                    <span
+                        data-tip={true}
+                        data-for={id}
+                        onClick={sharedUtils.setUrlHash.bind(null, typeDefinitionAnchorId)}
+                        style={{
+                            color: colors.lightBlueA700,
+                            cursor: 'pointer',
+                            display: 'inline-block',
+                        }}
+                    >
+                        {typeName}
+                        <ReactTooltip type="light" effect="solid" id={id} className="typeTooltip">
+                            <TypeDefinition
+                                sectionName={props.sectionName}
+                                customType={typeDefinition}
+                                shouldAddId={false}
+                                docsInfo={props.docsInfo}
+                            />
+                        </ReactTooltip>
+                    </span>
+                )}
+            </ScrollLink>
+        );
+    }
+    return (
+        <span>
+            <span style={{ color: typeNameColor }}>{typeName}</span>
+            {isArray && '[]'}
+            {!_.isEmpty(typeArgs) && (
+                <span>
+                    {'<'}
+                    {commaSeparatedTypeArgs}
+                    {'>'}
+                </span>
+            )}
+        </span>
+    );
+}
diff --git a/packages/react-docs/src/components/type_definition.tsx b/packages/react-docs/src/components/type_definition.tsx
new file mode 100644
index 000000000..68ef4c465
--- /dev/null
+++ b/packages/react-docs/src/components/type_definition.tsx
@@ -0,0 +1,131 @@
+import { AnchorTitle, colors, HeaderSizes } from '@0xproject/react-shared';
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { DocsInfo } from '../docs_info';
+import { CustomType, CustomTypeChild, KindString, TypeDocTypes } from '../types';
+import { constants } from '../utils/constants';
+import { utils } from '../utils/utils';
+
+import { Comment } from './comment';
+import { CustomEnum } from './custom_enum';
+import { Enum } from './enum';
+import { Interface } from './interface';
+import { MethodSignature } from './method_signature';
+import { Type } from './type';
+
+export interface TypeDefinitionProps {
+    sectionName: string;
+    customType: CustomType;
+    shouldAddId?: boolean;
+    docsInfo: DocsInfo;
+}
+
+export interface TypeDefinitionState {
+    shouldShowAnchor: boolean;
+}
+
+export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDefinitionState> {
+    public static defaultProps: Partial<TypeDefinitionProps> = {
+        shouldAddId: true,
+    };
+    constructor(props: TypeDefinitionProps) {
+        super(props);
+        this.state = {
+            shouldShowAnchor: false,
+        };
+    }
+    public render() {
+        const customType = this.props.customType;
+        if (!this.props.docsInfo.isPublicType(customType.name)) {
+            return null; // no-op
+        }
+
+        let typePrefix: string;
+        let codeSnippet: React.ReactNode;
+        switch (customType.kindString) {
+            case KindString.Interface:
+                typePrefix = 'Interface';
+                codeSnippet = (
+                    <Interface type={customType} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
+                );
+                break;
+
+            case KindString.Variable:
+                typePrefix = 'Enum';
+                codeSnippet = <CustomEnum type={customType} />;
+                break;
+
+            case KindString.Enumeration:
+                typePrefix = 'Enum';
+                const enumValues = _.map(customType.children, (c: CustomTypeChild) => {
+                    return {
+                        name: c.name,
+                        defaultValue: c.defaultValue,
+                    };
+                });
+                codeSnippet = <Enum values={enumValues} />;
+                break;
+
+            case KindString.TypeAlias:
+                typePrefix = 'Type Alias';
+                codeSnippet = (
+                    <span>
+                        <span style={{ color: colors.lightPurple }}>type</span> {customType.name} ={' '}
+                        {customType.type.typeDocType !== TypeDocTypes.Reflection ? (
+                            <Type
+                                type={customType.type}
+                                sectionName={this.props.sectionName}
+                                docsInfo={this.props.docsInfo}
+                            />
+                        ) : (
+                            <MethodSignature
+                                method={customType.type.method}
+                                sectionName={this.props.sectionName}
+                                shouldHideMethodName={true}
+                                shouldUseArrowSyntax={true}
+                                docsInfo={this.props.docsInfo}
+                            />
+                        )}
+                    </span>
+                );
+                break;
+
+            default:
+                throw utils.spawnSwitchErr('type.kindString', customType.kindString);
+        }
+
+        const typeDefinitionAnchorId = `${this.props.sectionName}-${customType.name}`;
+        return (
+            <div
+                id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
+                className="pb2"
+                style={{ overflow: 'hidden', width: '100%' }}
+                onMouseOver={this._setAnchorVisibility.bind(this, true)}
+                onMouseOut={this._setAnchorVisibility.bind(this, false)}
+            >
+                <AnchorTitle
+                    headerSize={HeaderSizes.H3}
+                    title={`${typePrefix} ${customType.name}`}
+                    id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
+                    shouldShowAnchor={this.state.shouldShowAnchor}
+                />
+                <div style={{ fontSize: 16 }}>
+                    <pre>
+                        <code className={`hljs ${constants.TYPE_TO_SYNTAX[this.props.docsInfo.type]}`}>
+                            {codeSnippet}
+                        </code>
+                    </pre>
+                </div>
+                <div style={{ maxWidth: 620 }}>
+                    {customType.comment && <Comment comment={customType.comment} className="py2" />}
+                </div>
+            </div>
+        );
+    }
+    private _setAnchorVisibility(shouldShowAnchor: boolean) {
+        this.setState({
+            shouldShowAnchor,
+        });
+    }
+}
diff --git a/packages/react-docs/src/docs_info.ts b/packages/react-docs/src/docs_info.ts
new file mode 100644
index 000000000..68bddef06
--- /dev/null
+++ b/packages/react-docs/src/docs_info.ts
@@ -0,0 +1,123 @@
+import { MenuSubsectionsBySection } from '@0xproject/react-shared';
+import compareVersions = require('compare-versions');
+import * as _ from 'lodash';
+
+import {
+    ContractsByVersionByNetworkId,
+    DocAgnosticFormat,
+    DocsInfoConfig,
+    DocsInfoTypeConfigs,
+    DocsMenu,
+    DoxityDocObj,
+    SectionsMap,
+    SupportedDocJson,
+    TypeDocNode,
+} from './types';
+import { doxityUtils } from './utils/doxity_utils';
+import { typeDocUtils } from './utils/typedoc_utils';
+
+export class DocsInfo {
+    public id: string;
+    public type: SupportedDocJson;
+    public displayName: string;
+    public packageUrl: string;
+    public menu: DocsMenu;
+    public sections: SectionsMap;
+    public sectionNameToMarkdown: { [sectionName: string]: string };
+    public contractsByVersionByNetworkId?: ContractsByVersionByNetworkId;
+    public typeConfigs: DocsInfoTypeConfigs;
+    private _docsInfo: DocsInfoConfig;
+    constructor(config: DocsInfoConfig) {
+        this.id = config.id;
+        this.type = config.type;
+        this.displayName = config.displayName;
+        this.packageUrl = config.packageUrl;
+        this.sections = config.sections;
+        this.sectionNameToMarkdown = config.sectionNameToMarkdown;
+        this.contractsByVersionByNetworkId = config.contractsByVersionByNetworkId;
+        this.typeConfigs = config.typeConfigs;
+        this._docsInfo = config;
+    }
+    public isPublicType(typeName: string): boolean {
+        if (_.isUndefined(this._docsInfo.typeConfigs.publicTypes)) {
+            return false;
+        }
+        const isPublic = _.includes(this._docsInfo.typeConfigs.publicTypes, typeName);
+        return isPublic;
+    }
+    public getModulePathsIfExists(sectionName: string): string[] {
+        const modulePathsIfExists = this._docsInfo.sectionNameToModulePath[sectionName];
+        return modulePathsIfExists;
+    }
+    public getMenu(selectedVersion?: string): { [section: string]: string[] } {
+        if (_.isUndefined(selectedVersion) || _.isUndefined(this._docsInfo.menuSubsectionToVersionWhenIntroduced)) {
+            return this._docsInfo.menu;
+        }
+
+        const finalMenu = _.cloneDeep(this._docsInfo.menu);
+        if (_.isUndefined(finalMenu.contracts)) {
+            return finalMenu;
+        }
+
+        // TODO: refactor to include more sections then simply the `contracts` section
+        finalMenu.contracts = _.filter(finalMenu.contracts, (contractName: string) => {
+            const versionIntroducedIfExists = this._docsInfo.menuSubsectionToVersionWhenIntroduced[contractName];
+            if (!_.isUndefined(versionIntroducedIfExists)) {
+                const existsInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0;
+                return existsInSelectedVersion;
+            } else {
+                return true;
+            }
+        });
+        return finalMenu;
+    }
+    public getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection {
+        const menuSubsectionsBySection = {} as MenuSubsectionsBySection;
+        if (_.isUndefined(docAgnosticFormat)) {
+            return menuSubsectionsBySection;
+        }
+
+        const docSections = _.keys(this.sections);
+        _.each(docSections, sectionName => {
+            const docSection = docAgnosticFormat[sectionName];
+            if (_.isUndefined(docSection)) {
+                return; // no-op
+            }
+
+            if (!_.isUndefined(this.sections.types) && sectionName === this.sections.types) {
+                const sortedTypesNames = _.sortBy(docSection.types, 'name');
+                const typeNames = _.map(sortedTypesNames, t => t.name);
+                menuSubsectionsBySection[sectionName] = typeNames;
+            } else {
+                let eventNames: string[] = [];
+                if (!_.isUndefined(docSection.events)) {
+                    const sortedEventNames = _.sortBy(docSection.events, 'name');
+                    eventNames = _.map(sortedEventNames, m => m.name);
+                }
+                const sortedMethodNames = _.sortBy(docSection.methods, 'name');
+                const methodNames = _.map(sortedMethodNames, m => m.name);
+                menuSubsectionsBySection[sectionName] = [...methodNames, ...eventNames];
+            }
+        });
+        return menuSubsectionsBySection;
+    }
+    public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat) {
+        if (_.isUndefined(this.sections.types)) {
+            return {};
+        }
+
+        const typeDocSection = docAgnosticFormat[this.sections.types];
+        const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name');
+        return typeDefinitionByName;
+    }
+    public isVisibleConstructor(sectionName: string): boolean {
+        return _.includes(this._docsInfo.visibleConstructors, sectionName);
+    }
+    public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat {
+        if (this.type === SupportedDocJson.Doxity) {
+            return doxityUtils.convertToDocAgnosticFormat(docObj as DoxityDocObj);
+        } else {
+            return typeDocUtils.convertToDocAgnosticFormat(docObj as TypeDocNode, this);
+        }
+    }
+}
diff --git a/packages/react-docs/src/globals.d.ts b/packages/react-docs/src/globals.d.ts
new file mode 100644
index 000000000..c7cd53854
--- /dev/null
+++ b/packages/react-docs/src/globals.d.ts
@@ -0,0 +1,14 @@
+declare module 'react-tooltip';
+
+// compare-version declarations
+declare function compareVersions(firstVersion: string, secondVersion: string): number;
+declare module 'compare-versions' {
+    export = compareVersions;
+}
+
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/react-docs/src/index.ts b/packages/react-docs/src/index.ts
new file mode 100644
index 000000000..a62c91376
--- /dev/null
+++ b/packages/react-docs/src/index.ts
@@ -0,0 +1,20 @@
+// Exported to give users of this library added flexibility if they want to build
+// a docs page from scratch using the individual components.
+export { Badge } from './components/badge';
+export { Comment } from './components/comment';
+export { CustomEnum } from './components/custom_enum';
+export { Documentation } from './components/documentation';
+export { Enum } from './components/enum';
+export { EventDefinition } from './components/event_definition';
+export { Interface } from './components/interface';
+export { MethodBlock } from './components/method_block';
+export { MethodSignature } from './components/method_signature';
+export { SourceLink } from './components/source_link';
+export { TypeDefinition } from './components/type_definition';
+export { Type } from './components/type';
+
+export { DocsInfo } from './docs_info';
+
+export { DocsInfoConfig, DocAgnosticFormat, DoxityDocObj, DocsMenu, SupportedDocJson, TypeDocNode } from './types';
+
+export { constants } from './utils/constants';
diff --git a/packages/react-docs/src/monorepo_scripts/postpublish.ts b/packages/react-docs/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/react-docs/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/react-docs/src/ts/components/badge.tsx b/packages/react-docs/src/ts/components/badge.tsx
deleted file mode 100644
index b342f2dca..000000000
--- a/packages/react-docs/src/ts/components/badge.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Styles } from '@0xproject/react-shared';
-import * as _ from 'lodash';
-import * as React from 'react';
-
-const styles: Styles = {
-    badge: {
-        width: 50,
-        fontSize: 11,
-        height: 10,
-        borderRadius: 5,
-        lineHeight: 0.9,
-        fontFamily: 'Roboto Mono',
-        marginLeft: 3,
-        marginRight: 3,
-    },
-};
-
-export interface BadgeProps {
-    title: string;
-    backgroundColor: string;
-}
-
-export interface BadgeState {
-    isHovering: boolean;
-}
-
-export class Badge extends React.Component<BadgeProps, BadgeState> {
-    constructor(props: BadgeProps) {
-        super(props);
-        this.state = {
-            isHovering: false,
-        };
-    }
-    public render() {
-        const badgeStyle = {
-            ...styles.badge,
-            backgroundColor: this.props.backgroundColor,
-            opacity: this.state.isHovering ? 0.7 : 1,
-        };
-        return (
-            <div
-                className="p1 center"
-                style={badgeStyle}
-                onMouseOver={this._setHoverState.bind(this, true)}
-                onMouseOut={this._setHoverState.bind(this, false)}
-            >
-                {this.props.title}
-            </div>
-        );
-    }
-    private _setHoverState(isHovering: boolean) {
-        this.setState({
-            isHovering,
-        });
-    }
-}
diff --git a/packages/react-docs/src/ts/components/comment.tsx b/packages/react-docs/src/ts/components/comment.tsx
deleted file mode 100644
index 0d63d4d31..000000000
--- a/packages/react-docs/src/ts/components/comment.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { MarkdownCodeBlock } from '@0xproject/react-shared';
-import * as _ from 'lodash';
-import * as React from 'react';
-import * as ReactMarkdown from 'react-markdown';
-
-export interface CommentProps {
-    comment: string;
-    className?: string;
-}
-
-const defaultProps = {
-    className: '',
-};
-
-export const Comment: React.SFC<CommentProps> = (props: CommentProps) => {
-    return (
-        <div className={`${props.className} comment`}>
-            <ReactMarkdown source={props.comment} renderers={{ code: MarkdownCodeBlock }} />
-        </div>
-    );
-};
-
-Comment.defaultProps = defaultProps;
diff --git a/packages/react-docs/src/ts/components/custom_enum.tsx b/packages/react-docs/src/ts/components/custom_enum.tsx
deleted file mode 100644
index deb33ff1d..000000000
--- a/packages/react-docs/src/ts/components/custom_enum.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { CustomType } from '../types';
-import { utils } from '../utils/utils';
-
-const STRING_ENUM_CODE_PREFIX = ' strEnum(';
-
-export interface CustomEnumProps {
-    type: CustomType;
-}
-
-// This component renders custom string enums that was a work-around for versions of
-// TypeScript <2.4.0 that did not support them natively. We keep it around to support
-// older versions of 0x.js <0.9.0
-export function CustomEnum(props: CustomEnumProps) {
-    const type = props.type;
-    if (!_.startsWith(type.defaultValue, STRING_ENUM_CODE_PREFIX)) {
-        utils.consoleLog('We do not yet support `Variable` types that are not strEnums');
-        return null;
-    }
-    // Remove the prefix and postfix, leaving only the strEnum values without quotes.
-    const enumValues = type.defaultValue.slice(10, -3).replace(/'/g, '');
-    return (
-        <span>
-            {`{`}
-            {'\t'}
-            {enumValues}
-            <br />
-            {`}`}
-        </span>
-    );
-}
diff --git a/packages/react-docs/src/ts/components/documentation.tsx b/packages/react-docs/src/ts/components/documentation.tsx
deleted file mode 100644
index b46358159..000000000
--- a/packages/react-docs/src/ts/components/documentation.tsx
+++ /dev/null
@@ -1,375 +0,0 @@
-import {
-    colors,
-    constants as sharedConstants,
-    EtherscanLinkSuffixes,
-    MarkdownSection,
-    MenuSubsectionsBySection,
-    NestedSidebarMenu,
-    Networks,
-    SectionHeader,
-    Styles,
-    utils as sharedUtils,
-} from '@0xproject/react-shared';
-import * as _ from 'lodash';
-import CircularProgress from 'material-ui/CircularProgress';
-import * as React from 'react';
-import { scroller } from 'react-scroll';
-
-import { DocsInfo } from '../docs_info';
-import {
-    AddressByContractName,
-    DocAgnosticFormat,
-    DoxityDocObj,
-    Event,
-    Property,
-    SolidityMethod,
-    SupportedDocJson,
-    TypeDefinitionByName,
-    TypescriptMethod,
-} from '../types';
-import { constants } from '../utils/constants';
-import { utils } from '../utils/utils';
-
-import { Badge } from './badge';
-import { Comment } from './comment';
-import { EventDefinition } from './event_definition';
-import { MethodBlock } from './method_block';
-import { SourceLink } from './source_link';
-import { Type } from './type';
-import { TypeDefinition } from './type_definition';
-
-const networkNameToColor: { [network: string]: string } = {
-    [Networks.Kovan]: colors.purple,
-    [Networks.Ropsten]: colors.red,
-    [Networks.Mainnet]: colors.turquois,
-    [Networks.Rinkeby]: colors.darkYellow,
-};
-
-export interface DocumentationProps {
-    selectedVersion: string;
-    availableVersions: string[];
-    docsInfo: DocsInfo;
-    sourceUrl: string;
-    onVersionSelected: (semver: string) => void;
-    docAgnosticFormat?: DocAgnosticFormat;
-    sidebarHeader?: React.ReactNode;
-    topBarHeight?: number;
-}
-
-export interface DocumentationState {
-    isHoveringSidebar: boolean;
-}
-
-export class Documentation extends React.Component<DocumentationProps, DocumentationState> {
-    public static defaultProps: Partial<DocumentationProps> = {
-        topBarHeight: 0,
-    };
-    constructor(props: DocumentationProps) {
-        super(props);
-        this.state = {
-            isHoveringSidebar: false,
-        };
-    }
-    public componentDidMount() {
-        window.addEventListener('hashchange', this._onHashChanged.bind(this), false);
-    }
-    public componentWillUnmount() {
-        window.removeEventListener('hashchange', this._onHashChanged.bind(this), false);
-    }
-    public componentDidUpdate(prevProps: DocumentationProps, prevState: DocumentationState) {
-        if (!_.isEqual(prevProps.docAgnosticFormat, this.props.docAgnosticFormat)) {
-            const hash = window.location.hash.slice(1);
-            sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID);
-        }
-    }
-    public render() {
-        const styles: Styles = {
-            mainContainers: {
-                position: 'absolute',
-                top: 1,
-                left: 0,
-                bottom: 0,
-                right: 0,
-                overflowZ: 'hidden',
-                overflowY: 'scroll',
-                minHeight: `calc(100vh - ${this.props.topBarHeight}px)`,
-                WebkitOverflowScrolling: 'touch',
-            },
-            menuContainer: {
-                borderColor: colors.grey300,
-                maxWidth: 330,
-                marginLeft: 20,
-            },
-        };
-        const menuSubsectionsBySection = this.props.docsInfo.getMenuSubsectionsBySection(this.props.docAgnosticFormat);
-        return (
-            <div>
-                {_.isUndefined(this.props.docAgnosticFormat) ? (
-                    this._renderLoading(styles.mainContainers)
-                ) : (
-                    <div style={{ width: '100%', height: '100%', backgroundColor: colors.gray40 }}>
-                        <div
-                            className="mx-auto max-width-4 flex"
-                            style={{ color: colors.grey800, height: `calc(100vh - ${this.props.topBarHeight}px)` }}
-                        >
-                            <div
-                                className="relative sm-hide xs-hide"
-                                style={{ width: '36%', height: `calc(100vh - ${this.props.topBarHeight}px)` }}
-                            >
-                                <div
-                                    className="border-right absolute"
-                                    style={{
-                                        ...styles.menuContainer,
-                                        ...styles.mainContainers,
-                                        height: `calc(100vh - ${this.props.topBarHeight}px)`,
-                                        overflow: this.state.isHoveringSidebar ? 'auto' : 'hidden',
-                                    }}
-                                    onMouseEnter={this._onSidebarHover.bind(this)}
-                                    onMouseLeave={this._onSidebarHoverOff.bind(this)}
-                                >
-                                    <NestedSidebarMenu
-                                        selectedVersion={this.props.selectedVersion}
-                                        versions={this.props.availableVersions}
-                                        sidebarHeader={this.props.sidebarHeader}
-                                        topLevelMenu={this.props.docsInfo.getMenu(this.props.selectedVersion)}
-                                        menuSubsectionsBySection={menuSubsectionsBySection}
-                                        onVersionSelected={this.props.onVersionSelected}
-                                    />
-                                </div>
-                            </div>
-                            <div
-                                className="relative col lg-col-9 md-col-9 sm-col-12 col-12"
-                                style={{ backgroundColor: colors.white }}
-                            >
-                                <div
-                                    id={sharedConstants.SCROLL_CONTAINER_ID}
-                                    style={styles.mainContainers}
-                                    className="absolute px1"
-                                >
-                                    <div id={sharedConstants.SCROLL_TOP_ID} />
-                                    {this._renderDocumentation()}
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                )}
-            </div>
-        );
-    }
-    private _renderLoading(mainContainersStyles: React.CSSProperties) {
-        return (
-            <div className="col col-12" style={mainContainersStyles}>
-                <div
-                    className="relative sm-px2 sm-pt2 sm-m1"
-                    style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
-                >
-                    <div className="center pb2">
-                        <CircularProgress size={40} thickness={5} />
-                    </div>
-                    <div className="center pt2" style={{ paddingBottom: 11 }}>
-                        Loading documentation...
-                    </div>
-                </div>
-            </div>
-        );
-    }
-    private _renderDocumentation(): React.ReactNode {
-        const subMenus = _.values(this.props.docsInfo.getMenu());
-        const orderedSectionNames = _.flatten(subMenus);
-
-        const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.props.docAgnosticFormat);
-        const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName));
-
-        return renderedSections;
-    }
-    private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode {
-        const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdown[sectionName];
-        if (!_.isUndefined(markdownFileIfExists)) {
-            return (
-                <MarkdownSection
-                    key={`markdown-section-${sectionName}`}
-                    sectionName={sectionName}
-                    markdownContent={markdownFileIfExists}
-                />
-            );
-        }
-
-        const docSection = this.props.docAgnosticFormat[sectionName];
-        if (_.isUndefined(docSection)) {
-            return null;
-        }
-
-        const sortedTypes = _.sortBy(docSection.types, 'name');
-        const typeDefs = _.map(sortedTypes, customType => {
-            return (
-                <TypeDefinition
-                    sectionName={sectionName}
-                    key={`type-${customType.name}`}
-                    customType={customType}
-                    docsInfo={this.props.docsInfo}
-                />
-            );
-        });
-
-        const sortedProperties = _.sortBy(docSection.properties, 'name');
-        const propertyDefs = _.map(sortedProperties, this._renderProperty.bind(this, sectionName));
-
-        const sortedMethods = _.sortBy(docSection.methods, 'name');
-        const methodDefs = _.map(sortedMethods, method => {
-            const isConstructor = false;
-            return this._renderMethodBlocks(method, sectionName, isConstructor, typeDefinitionByName);
-        });
-
-        const sortedEvents = _.sortBy(docSection.events, 'name');
-        const eventDefs = _.map(sortedEvents, (event: Event, i: number) => {
-            return (
-                <EventDefinition
-                    key={`event-${event.name}-${i}`}
-                    event={event}
-                    sectionName={sectionName}
-                    docsInfo={this.props.docsInfo}
-                />
-            );
-        });
-        const headerStyle: React.CSSProperties = {
-            fontWeight: 100,
-        };
-        return (
-            <div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
-                <div className="flex pb2">
-                    <div style={{ marginRight: 7 }}>
-                        <SectionHeader sectionName={sectionName} />
-                    </div>
-                    {this._renderNetworkBadgesIfExists(sectionName)}
-                </div>
-                {docSection.comment && <Comment comment={docSection.comment} />}
-                {docSection.constructors.length > 0 &&
-                    this.props.docsInfo.isVisibleConstructor(sectionName) && (
-                        <div>
-                            <h2 style={headerStyle}>Constructor</h2>
-                            {this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)}
-                        </div>
-                    )}
-                {docSection.properties.length > 0 && (
-                    <div>
-                        <h2 style={headerStyle}>Properties</h2>
-                        <div>{propertyDefs}</div>
-                    </div>
-                )}
-                {docSection.methods.length > 0 && (
-                    <div>
-                        <h2 style={headerStyle}>Methods</h2>
-                        <div>{methodDefs}</div>
-                    </div>
-                )}
-                {!_.isUndefined(docSection.events) &&
-                    docSection.events.length > 0 && (
-                        <div>
-                            <h2 style={headerStyle}>Events</h2>
-                            <div>{eventDefs}</div>
-                        </div>
-                    )}
-                {!_.isUndefined(typeDefs) &&
-                    typeDefs.length > 0 && (
-                        <div>
-                            <div>{typeDefs}</div>
-                        </div>
-                    )}
-            </div>
-        );
-    }
-    private _renderNetworkBadgesIfExists(sectionName: string) {
-        if (this.props.docsInfo.type !== SupportedDocJson.Doxity) {
-            return null;
-        }
-
-        const networkToAddressByContractName = this.props.docsInfo.contractsByVersionByNetworkId[
-            this.props.selectedVersion
-        ];
-        const badges = _.map(
-            networkToAddressByContractName,
-            (addressByContractName: AddressByContractName, networkName: string) => {
-                const contractAddress = addressByContractName[sectionName];
-                if (_.isUndefined(contractAddress)) {
-                    return null;
-                }
-                const linkIfExists = sharedUtils.getEtherScanLinkIfExists(
-                    contractAddress,
-                    sharedConstants.NETWORK_ID_BY_NAME[networkName],
-                    EtherscanLinkSuffixes.Address,
-                );
-                return (
-                    <a
-                        key={`badge-${networkName}-${sectionName}`}
-                        href={linkIfExists}
-                        target="_blank"
-                        style={{ color: colors.white, textDecoration: 'none' }}
-                    >
-                        <Badge title={networkName} backgroundColor={networkNameToColor[networkName]} />
-                    </a>
-                );
-            },
-        );
-        return badges;
-    }
-    private _renderConstructors(
-        constructors: SolidityMethod[] | TypescriptMethod[],
-        sectionName: string,
-        typeDefinitionByName: TypeDefinitionByName,
-    ): React.ReactNode {
-        const constructorDefs = _.map(constructors, constructor => {
-            return this._renderMethodBlocks(constructor, sectionName, constructor.isConstructor, typeDefinitionByName);
-        });
-        return <div>{constructorDefs}</div>;
-    }
-    private _renderProperty(sectionName: string, property: Property): React.ReactNode {
-        return (
-            <div key={`property-${property.name}-${property.type.name}`} className="pb3">
-                <code className={`hljs ${constants.TYPE_TO_SYNTAX[this.props.docsInfo.type]}`}>
-                    {property.name}:
-                    <Type type={property.type} sectionName={sectionName} docsInfo={this.props.docsInfo} />
-                </code>
-                {property.source && (
-                    <SourceLink
-                        version={this.props.selectedVersion}
-                        source={property.source}
-                        sourceUrl={this.props.sourceUrl}
-                    />
-                )}
-                {property.comment && <Comment comment={property.comment} className="py2" />}
-            </div>
-        );
-    }
-    private _renderMethodBlocks(
-        method: SolidityMethod | TypescriptMethod,
-        sectionName: string,
-        isConstructor: boolean,
-        typeDefinitionByName: TypeDefinitionByName,
-    ): React.ReactNode {
-        return (
-            <MethodBlock
-                key={`method-${method.name}-${sectionName}`}
-                sectionName={sectionName}
-                method={method}
-                typeDefinitionByName={typeDefinitionByName}
-                libraryVersion={this.props.selectedVersion}
-                docsInfo={this.props.docsInfo}
-                sourceUrl={this.props.sourceUrl}
-            />
-        );
-    }
-    private _onSidebarHover(event: React.FormEvent<HTMLInputElement>) {
-        this.setState({
-            isHoveringSidebar: true,
-        });
-    }
-    private _onSidebarHoverOff() {
-        this.setState({
-            isHoveringSidebar: false,
-        });
-    }
-    private _onHashChanged(event: any) {
-        const hash = window.location.hash.slice(1);
-        sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID);
-    }
-}
diff --git a/packages/react-docs/src/ts/components/enum.tsx b/packages/react-docs/src/ts/components/enum.tsx
deleted file mode 100644
index 37f82f26e..000000000
--- a/packages/react-docs/src/ts/components/enum.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { EnumValue } from '../types';
-
-export interface EnumProps {
-    values: EnumValue[];
-}
-
-export function Enum(props: EnumProps) {
-    const values = _.map(props.values, (value, i) => {
-        const defaultValueIfAny = !_.isUndefined(value.defaultValue) ? ` = ${value.defaultValue}` : '';
-        return `\n\t${value.name}${defaultValueIfAny},`;
-    });
-    return (
-        <span>
-            {`{`}
-            {values}
-            <br />
-            {`}`}
-        </span>
-    );
-}
diff --git a/packages/react-docs/src/ts/components/event_definition.tsx b/packages/react-docs/src/ts/components/event_definition.tsx
deleted file mode 100644
index 67729ac87..000000000
--- a/packages/react-docs/src/ts/components/event_definition.tsx
+++ /dev/null
@@ -1,84 +0,0 @@
-import { AnchorTitle, colors, HeaderSizes } from '@0xproject/react-shared';
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { DocsInfo } from '../docs_info';
-import { Event, EventArg } from '../types';
-
-import { Type } from './type';
-
-export interface EventDefinitionProps {
-    event: Event;
-    sectionName: string;
-    docsInfo: DocsInfo;
-}
-
-export interface EventDefinitionState {
-    shouldShowAnchor: boolean;
-}
-
-export class EventDefinition extends React.Component<EventDefinitionProps, EventDefinitionState> {
-    constructor(props: EventDefinitionProps) {
-        super(props);
-        this.state = {
-            shouldShowAnchor: false,
-        };
-    }
-    public render() {
-        const event = this.props.event;
-        const id = `${this.props.sectionName}-${event.name}`;
-        return (
-            <div
-                id={id}
-                className="pb2"
-                style={{ overflow: 'hidden', width: '100%' }}
-                onMouseOver={this._setAnchorVisibility.bind(this, true)}
-                onMouseOut={this._setAnchorVisibility.bind(this, false)}
-            >
-                <AnchorTitle
-                    headerSize={HeaderSizes.H3}
-                    title={`Event ${event.name}`}
-                    id={id}
-                    shouldShowAnchor={this.state.shouldShowAnchor}
-                />
-                <div style={{ fontSize: 16 }}>
-                    <pre>
-                        <code className="hljs solidity">{this._renderEventCode()}</code>
-                    </pre>
-                </div>
-            </div>
-        );
-    }
-    private _renderEventCode() {
-        const indexed = <span style={{ color: colors.green }}> indexed</span>;
-        const eventArgs = _.map(this.props.event.eventArgs, (eventArg: EventArg) => {
-            const type = (
-                <Type type={eventArg.type} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
-            );
-            return (
-                <span key={`eventArg-${eventArg.name}`}>
-                    {eventArg.name}
-                    {eventArg.isIndexed ? indexed : ''}: {type},
-                </span>
-            );
-        });
-        const argList = _.reduce(eventArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
-            return [prev, '\n\t', curr];
-        });
-        return (
-            <span>
-                {`{`}
-                <br />
-                {'\t'}
-                {argList}
-                <br />
-                {`}`}
-            </span>
-        );
-    }
-    private _setAnchorVisibility(shouldShowAnchor: boolean) {
-        this.setState({
-            shouldShowAnchor,
-        });
-    }
-}
diff --git a/packages/react-docs/src/ts/components/interface.tsx b/packages/react-docs/src/ts/components/interface.tsx
deleted file mode 100644
index 01f4942ef..000000000
--- a/packages/react-docs/src/ts/components/interface.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { DocsInfo } from '../docs_info';
-import { CustomType, TypeDocTypes } from '../types';
-
-import { MethodSignature } from './method_signature';
-import { Type } from './type';
-
-export interface InterfaceProps {
-    type: CustomType;
-    sectionName: string;
-    docsInfo: DocsInfo;
-}
-
-export function Interface(props: InterfaceProps) {
-    const type = props.type;
-    const properties = _.map(type.children, property => {
-        return (
-            <span key={`property-${property.name}-${property.type}-${type.name}`}>
-                {property.name}:{' '}
-                {property.type.typeDocType !== TypeDocTypes.Reflection ? (
-                    <Type type={property.type} sectionName={props.sectionName} docsInfo={props.docsInfo} />
-                ) : (
-                    <MethodSignature
-                        method={property.type.method}
-                        sectionName={props.sectionName}
-                        shouldHideMethodName={true}
-                        shouldUseArrowSyntax={true}
-                        docsInfo={props.docsInfo}
-                    />
-                )},
-            </span>
-        );
-    });
-    const hasIndexSignature = !_.isUndefined(type.indexSignature);
-    if (hasIndexSignature) {
-        const is = type.indexSignature;
-        const param = (
-            <span key={`indexSigParams-${is.keyName}-${is.keyType}-${type.name}`}>
-                {is.keyName}: <Type type={is.keyType} sectionName={props.sectionName} docsInfo={props.docsInfo} />
-            </span>
-        );
-        properties.push(
-            <span key={`indexSignature-${type.name}-${is.keyType.name}`}>
-                [{param}]: {is.valueName},
-            </span>,
-        );
-    }
-    const propertyList = _.reduce(properties, (prev: React.ReactNode, curr: React.ReactNode) => {
-        return [prev, '\n\t', curr];
-    });
-    return (
-        <span>
-            {`{`}
-            <br />
-            {'\t'}
-            {propertyList}
-            <br />
-            {`}`}
-        </span>
-    );
-}
diff --git a/packages/react-docs/src/ts/components/method_block.tsx b/packages/react-docs/src/ts/components/method_block.tsx
deleted file mode 100644
index 44a1db8af..000000000
--- a/packages/react-docs/src/ts/components/method_block.tsx
+++ /dev/null
@@ -1,150 +0,0 @@
-import { AnchorTitle, colors, HeaderSizes, Styles } from '@0xproject/react-shared';
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { DocsInfo } from '../docs_info';
-import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptMethod } from '../types';
-import { constants } from '../utils/constants';
-import { typeDocUtils } from '../utils/typedoc_utils';
-
-import { Comment } from './comment';
-import { MethodSignature } from './method_signature';
-import { SourceLink } from './source_link';
-
-export interface MethodBlockProps {
-    method: SolidityMethod | TypescriptMethod;
-    sectionName: string;
-    libraryVersion: string;
-    typeDefinitionByName: TypeDefinitionByName;
-    docsInfo: DocsInfo;
-    sourceUrl: string;
-}
-
-export interface MethodBlockState {
-    shouldShowAnchor: boolean;
-}
-
-const styles: Styles = {
-    chip: {
-        fontSize: 13,
-        backgroundColor: colors.lightBlueA700,
-        color: colors.white,
-        height: 11,
-        borderRadius: 14,
-        lineHeight: 0.9,
-    },
-};
-
-export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockState> {
-    constructor(props: MethodBlockProps) {
-        super(props);
-        this.state = {
-            shouldShowAnchor: false,
-        };
-    }
-    public render() {
-        const method = this.props.method;
-        if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) {
-            return null;
-        }
-
-        return (
-            <div
-                id={`${this.props.sectionName}-${method.name}`}
-                style={{ overflow: 'hidden', width: '100%' }}
-                className="pb4"
-                onMouseOver={this._setAnchorVisibility.bind(this, true)}
-                onMouseOut={this._setAnchorVisibility.bind(this, false)}
-            >
-                {!method.isConstructor && (
-                    <div className="flex pb2 pt2">
-                        {(method as TypescriptMethod).isStatic && this._renderChip('Static')}
-                        {(method as SolidityMethod).isConstant && this._renderChip('Constant')}
-                        {(method as SolidityMethod).isPayable && this._renderChip('Payable')}
-                        <div style={{ lineHeight: 1.3 }}>
-                            <AnchorTitle
-                                headerSize={HeaderSizes.H3}
-                                title={method.name}
-                                id={`${this.props.sectionName}-${method.name}`}
-                                shouldShowAnchor={this.state.shouldShowAnchor}
-                            />
-                        </div>
-                    </div>
-                )}
-                <code className={`hljs ${constants.TYPE_TO_SYNTAX[this.props.docsInfo.type]}`}>
-                    <MethodSignature
-                        method={method}
-                        sectionName={this.props.sectionName}
-                        typeDefinitionByName={this.props.typeDefinitionByName}
-                        docsInfo={this.props.docsInfo}
-                    />
-                </code>
-                {(method as TypescriptMethod).source && (
-                    <SourceLink
-                        version={this.props.libraryVersion}
-                        source={(method as TypescriptMethod).source}
-                        sourceUrl={this.props.sourceUrl}
-                    />
-                )}
-                {method.comment && <Comment comment={method.comment} className="py2" />}
-                {method.parameters &&
-                    !_.isEmpty(method.parameters) && (
-                        <div>
-                            <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
-                                ARGUMENTS
-                            </h4>
-                            {this._renderParameterDescriptions(method.parameters)}
-                        </div>
-                    )}
-                {method.returnComment && (
-                    <div className="pt1 comment">
-                        <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
-                            RETURNS
-                        </h4>
-                        <Comment comment={method.returnComment} />
-                    </div>
-                )}
-            </div>
-        );
-    }
-    private _renderChip(text: string) {
-        return (
-            <div className="p1 mr1" style={styles.chip}>
-                {text}
-            </div>
-        );
-    }
-    private _renderParameterDescriptions(parameters: Parameter[]) {
-        const descriptions = _.map(parameters, parameter => {
-            const isOptional = parameter.isOptional;
-            return (
-                <div
-                    key={`param-description-${parameter.name}`}
-                    className="flex pb1 mb2"
-                    style={{ borderBottom: '1px solid #f0f4f7' }}
-                >
-                    <div className="pl2 col lg-col-4 md-col-4 sm-col-12 col-12">
-                        <div
-                            className="bold"
-                            style={{ overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }}
-                        >
-                            {parameter.name}
-                        </div>
-                        <div className="pt1" style={{ color: colors.grey, fontSize: 14 }}>
-                            {isOptional && 'optional'}
-                        </div>
-                    </div>
-                    <div className="col lg-col-8 md-col-8 sm-col-12 col-12" style={{ paddingLeft: 5 }}>
-                        {parameter.comment && <Comment comment={parameter.comment} />}
-                    </div>
-                </div>
-            );
-        });
-        return descriptions;
-    }
-    private _setAnchorVisibility(shouldShowAnchor: boolean) {
-        this.setState({
-            shouldShowAnchor,
-        });
-    }
-}
diff --git a/packages/react-docs/src/ts/components/method_signature.tsx b/packages/react-docs/src/ts/components/method_signature.tsx
deleted file mode 100644
index 1400182ea..000000000
--- a/packages/react-docs/src/ts/components/method_signature.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-import * as ReactDOM from 'react-dom';
-
-import { DocsInfo } from '../docs_info';
-import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptMethod } from '../types';
-import { constants } from '../utils/constants';
-
-import { Type } from './type';
-
-export interface MethodSignatureProps {
-    method: TypescriptMethod | SolidityMethod;
-    sectionName: string;
-    shouldHideMethodName?: boolean;
-    shouldUseArrowSyntax?: boolean;
-    typeDefinitionByName?: TypeDefinitionByName;
-    docsInfo: DocsInfo;
-}
-
-const defaultProps = {
-    shouldHideMethodName: false,
-    shouldUseArrowSyntax: false,
-};
-
-export const MethodSignature: React.SFC<MethodSignatureProps> = (props: MethodSignatureProps) => {
-    const sectionName = constants.TYPES_SECTION_NAME;
-    const parameters = renderParameters(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
-    const paramStringArray: any[] = [];
-    // HACK: For now we don't put params on newlines if there are less then 2 of them.
-    // Ideally we would check the character length of the resulting method signature and
-    // if it exceeds the available space, put params on their own lines.
-    const hasMoreThenTwoParams = parameters.length > 2;
-    _.each(parameters, (param: React.ReactNode, i: number) => {
-        const finalParam = hasMoreThenTwoParams ? (
-            <span className="pl2" key={`param-${i}`}>
-                {param}
-            </span>
-        ) : (
-            param
-        );
-        paramStringArray.push(finalParam);
-        const comma = hasMoreThenTwoParams ? (
-            <span key={`param-comma-${i}`}>
-                , <br />
-            </span>
-        ) : (
-            ', '
-        );
-        paramStringArray.push(comma);
-    });
-    if (!hasMoreThenTwoParams) {
-        paramStringArray.pop();
-    }
-    const methodName = props.shouldHideMethodName ? '' : props.method.name;
-    const typeParameterIfExists = _.isUndefined((props.method as TypescriptMethod).typeParameter)
-        ? undefined
-        : renderTypeParameter(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
-    return (
-        <span style={{ fontSize: 15 }}>
-            {props.method.callPath}
-            {methodName}
-            {typeParameterIfExists}({hasMoreThenTwoParams && <br />}
-            {paramStringArray})
-            {props.method.returnType && (
-                <span>
-                    {props.shouldUseArrowSyntax ? ' => ' : ': '}{' '}
-                    <Type
-                        type={props.method.returnType}
-                        sectionName={sectionName}
-                        typeDefinitionByName={props.typeDefinitionByName}
-                        docsInfo={props.docsInfo}
-                    />
-                </span>
-            )}
-        </span>
-    );
-};
-
-MethodSignature.defaultProps = defaultProps;
-
-function renderParameters(
-    method: TypescriptMethod | SolidityMethod,
-    docsInfo: DocsInfo,
-    sectionName: string,
-    typeDefinitionByName?: TypeDefinitionByName,
-) {
-    const parameters = method.parameters;
-    const params = _.map(parameters, (p: Parameter) => {
-        const isOptional = p.isOptional;
-        const type = (
-            <Type
-                type={p.type}
-                sectionName={sectionName}
-                typeDefinitionByName={typeDefinitionByName}
-                docsInfo={docsInfo}
-            />
-        );
-        return (
-            <span key={`param-${p.type}-${p.name}`}>
-                {p.name}
-                {isOptional && '?'}: {type}
-            </span>
-        );
-    });
-    return params;
-}
-
-function renderTypeParameter(
-    method: TypescriptMethod,
-    docsInfo: DocsInfo,
-    sectionName: string,
-    typeDefinitionByName?: TypeDefinitionByName,
-) {
-    const typeParameter = method.typeParameter;
-    const typeParam = (
-        <span>
-            {`<${typeParameter.name} extends `}
-            <Type
-                type={typeParameter.type}
-                sectionName={sectionName}
-                typeDefinitionByName={typeDefinitionByName}
-                docsInfo={docsInfo}
-            />
-            {`>`}
-        </span>
-    );
-    return typeParam;
-}
diff --git a/packages/react-docs/src/ts/components/source_link.tsx b/packages/react-docs/src/ts/components/source_link.tsx
deleted file mode 100644
index 89956a507..000000000
--- a/packages/react-docs/src/ts/components/source_link.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { colors } from '@0xproject/react-shared';
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { Source } from '../types';
-
-export interface SourceLinkProps {
-    source: Source;
-    sourceUrl: string;
-    version: string;
-}
-
-export function SourceLink(props: SourceLinkProps) {
-    const src = props.source;
-    const sourceCodeUrl = `${props.sourceUrl}/${src.fileName}#L${src.line}`;
-    return (
-        <div className="pt2" style={{ fontSize: 14 }}>
-            <a href={sourceCodeUrl} target="_blank" className="underline" style={{ color: colors.grey }}>
-                Source
-            </a>
-        </div>
-    );
-}
diff --git a/packages/react-docs/src/ts/components/type.tsx b/packages/react-docs/src/ts/components/type.tsx
deleted file mode 100644
index 56425a5df..000000000
--- a/packages/react-docs/src/ts/components/type.tsx
+++ /dev/null
@@ -1,227 +0,0 @@
-import { colors, constants as sharedConstants, utils as sharedUtils } from '@0xproject/react-shared';
-import * as _ from 'lodash';
-import * as React from 'react';
-import { Link as ScrollLink } from 'react-scroll';
-import * as ReactTooltip from 'react-tooltip';
-
-import { DocsInfo } from '../docs_info';
-import { Type as TypeDef, TypeDefinitionByName, TypeDocTypes } from '../types';
-import { constants } from '../utils/constants';
-import { utils } from '../utils/utils';
-
-import { TypeDefinition } from './type_definition';
-
-const typeToSection: { [typeName: string]: string } = {
-    ExchangeWrapper: 'exchange',
-    TokenWrapper: 'token',
-    TokenRegistryWrapper: 'tokenRegistry',
-    EtherTokenWrapper: 'etherToken',
-    ProxyWrapper: 'proxy',
-    TokenTransferProxyWrapper: 'proxy',
-    OrderStateWatcher: 'orderWatcher',
-};
-
-export interface TypeProps {
-    type: TypeDef;
-    docsInfo: DocsInfo;
-    sectionName: string;
-    typeDefinitionByName?: TypeDefinitionByName;
-}
-
-// The return type needs to be `any` here so that we can recursively define <Type /> components within
-// <Type /> components (e.g when rendering the union type).
-export function Type(props: TypeProps): any {
-    const type = props.type;
-    const isReference = type.typeDocType === TypeDocTypes.Reference;
-    const isArray = type.typeDocType === TypeDocTypes.Array;
-    let typeNameColor = 'inherit';
-    let typeName: string | React.ReactNode;
-    let typeArgs: React.ReactNode[] = [];
-    switch (type.typeDocType) {
-        case TypeDocTypes.Intrinsic:
-        case TypeDocTypes.Unknown:
-            typeName = type.name;
-            typeNameColor = colors.orange;
-            break;
-
-        case TypeDocTypes.Reference:
-            typeName = type.name;
-            typeArgs = _.map(type.typeArguments, (arg: TypeDef) => {
-                if (arg.typeDocType === TypeDocTypes.Array) {
-                    const key = `type-${arg.elementType.name}-${arg.elementType.typeDocType}`;
-                    return (
-                        <span>
-                            <Type
-                                key={key}
-                                type={arg.elementType}
-                                sectionName={props.sectionName}
-                                typeDefinitionByName={props.typeDefinitionByName}
-                                docsInfo={props.docsInfo}
-                            />[]
-                        </span>
-                    );
-                } else {
-                    const subType = (
-                        <Type
-                            key={`type-${arg.name}-${arg.value}-${arg.typeDocType}`}
-                            type={arg}
-                            sectionName={props.sectionName}
-                            typeDefinitionByName={props.typeDefinitionByName}
-                            docsInfo={props.docsInfo}
-                        />
-                    );
-                    return subType;
-                }
-            });
-            break;
-
-        case TypeDocTypes.StringLiteral:
-            typeName = `'${type.value}'`;
-            typeNameColor = colors.green;
-            break;
-
-        case TypeDocTypes.Array:
-            typeName = type.elementType.name;
-            break;
-
-        case TypeDocTypes.Union:
-            const unionTypes = _.map(type.types, t => {
-                return (
-                    <Type
-                        key={`type-${t.name}-${t.value}-${t.typeDocType}`}
-                        type={t}
-                        sectionName={props.sectionName}
-                        typeDefinitionByName={props.typeDefinitionByName}
-                        docsInfo={props.docsInfo}
-                    />
-                );
-            });
-            typeName = _.reduce(unionTypes, (prev: React.ReactNode, curr: React.ReactNode) => {
-                return [prev, '|', curr];
-            });
-            break;
-
-        case TypeDocTypes.TypeParameter:
-            typeName = type.name;
-            break;
-
-        case TypeDocTypes.Intersection:
-            const intersectionsTypes = _.map(type.types, t => {
-                return (
-                    <Type
-                        key={`type-${t.name}-${t.value}-${t.typeDocType}`}
-                        type={t}
-                        sectionName={props.sectionName}
-                        typeDefinitionByName={props.typeDefinitionByName}
-                        docsInfo={props.docsInfo}
-                    />
-                );
-            });
-            typeName = _.reduce(intersectionsTypes, (prev: React.ReactNode, curr: React.ReactNode) => {
-                return [prev, '&', curr];
-            });
-            break;
-
-        default:
-            throw utils.spawnSwitchErr('type.typeDocType', type.typeDocType);
-    }
-    // HACK: Normalize BigNumber to simply BigNumber. For some reason the type
-    // name is unpredictably one or the other.
-    if (typeName === 'BigNumber') {
-        typeName = 'BigNumber';
-    }
-    const commaSeparatedTypeArgs = _.reduce(typeArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
-        return [prev, ', ', curr];
-    });
-
-    let typeNameUrlIfExists;
-    let typePrefixIfExists;
-    let sectionNameIfExists;
-    if (!_.isUndefined(props.docsInfo.typeConfigs)) {
-        typeNameUrlIfExists = !_.isUndefined(props.docsInfo.typeConfigs.typeNameToExternalLink)
-            ? props.docsInfo.typeConfigs.typeNameToExternalLink[typeName as string]
-            : undefined;
-        typePrefixIfExists = !_.isUndefined(props.docsInfo.typeConfigs.typeNameToPrefix)
-            ? props.docsInfo.typeConfigs.typeNameToPrefix[typeName as string]
-            : undefined;
-        sectionNameIfExists = !_.isUndefined(props.docsInfo.typeConfigs.typeNameToDocSection)
-            ? props.docsInfo.typeConfigs.typeNameToDocSection[typeName as string]
-            : undefined;
-    }
-    if (!_.isUndefined(typeNameUrlIfExists)) {
-        typeName = (
-            <a
-                href={typeNameUrlIfExists}
-                target="_blank"
-                className="text-decoration-none"
-                style={{ color: colors.lightBlueA700 }}
-            >
-                {!_.isUndefined(typePrefixIfExists) ? `${typePrefixIfExists}.` : ''}
-                {typeName}
-            </a>
-        );
-    } else if (
-        (isReference || isArray) &&
-        (props.docsInfo.isPublicType(typeName as string) || !_.isUndefined(sectionNameIfExists))
-    ) {
-        const id = Math.random().toString();
-        const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists)
-            ? `${props.sectionName}-${typeName}`
-            : sectionNameIfExists;
-        let typeDefinition;
-        if (props.typeDefinitionByName) {
-            typeDefinition = props.typeDefinitionByName[typeName as string];
-        }
-        typeName = (
-            <ScrollLink
-                to={typeDefinitionAnchorId}
-                offset={0}
-                duration={sharedConstants.DOCS_SCROLL_DURATION_MS}
-                containerId={sharedConstants.DOCS_CONTAINER_ID}
-            >
-                {_.isUndefined(typeDefinition) || sharedUtils.isUserOnMobile() ? (
-                    <span
-                        onClick={sharedUtils.setUrlHash.bind(null, typeDefinitionAnchorId)}
-                        style={{ color: colors.lightBlueA700, cursor: 'pointer' }}
-                    >
-                        {typeName}
-                    </span>
-                ) : (
-                    <span
-                        data-tip={true}
-                        data-for={id}
-                        onClick={sharedUtils.setUrlHash.bind(null, typeDefinitionAnchorId)}
-                        style={{
-                            color: colors.lightBlueA700,
-                            cursor: 'pointer',
-                            display: 'inline-block',
-                        }}
-                    >
-                        {typeName}
-                        <ReactTooltip type="light" effect="solid" id={id} className="typeTooltip">
-                            <TypeDefinition
-                                sectionName={props.sectionName}
-                                customType={typeDefinition}
-                                shouldAddId={false}
-                                docsInfo={props.docsInfo}
-                            />
-                        </ReactTooltip>
-                    </span>
-                )}
-            </ScrollLink>
-        );
-    }
-    return (
-        <span>
-            <span style={{ color: typeNameColor }}>{typeName}</span>
-            {isArray && '[]'}
-            {!_.isEmpty(typeArgs) && (
-                <span>
-                    {'<'}
-                    {commaSeparatedTypeArgs}
-                    {'>'}
-                </span>
-            )}
-        </span>
-    );
-}
diff --git a/packages/react-docs/src/ts/components/type_definition.tsx b/packages/react-docs/src/ts/components/type_definition.tsx
deleted file mode 100644
index 68ef4c465..000000000
--- a/packages/react-docs/src/ts/components/type_definition.tsx
+++ /dev/null
@@ -1,131 +0,0 @@
-import { AnchorTitle, colors, HeaderSizes } from '@0xproject/react-shared';
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { DocsInfo } from '../docs_info';
-import { CustomType, CustomTypeChild, KindString, TypeDocTypes } from '../types';
-import { constants } from '../utils/constants';
-import { utils } from '../utils/utils';
-
-import { Comment } from './comment';
-import { CustomEnum } from './custom_enum';
-import { Enum } from './enum';
-import { Interface } from './interface';
-import { MethodSignature } from './method_signature';
-import { Type } from './type';
-
-export interface TypeDefinitionProps {
-    sectionName: string;
-    customType: CustomType;
-    shouldAddId?: boolean;
-    docsInfo: DocsInfo;
-}
-
-export interface TypeDefinitionState {
-    shouldShowAnchor: boolean;
-}
-
-export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDefinitionState> {
-    public static defaultProps: Partial<TypeDefinitionProps> = {
-        shouldAddId: true,
-    };
-    constructor(props: TypeDefinitionProps) {
-        super(props);
-        this.state = {
-            shouldShowAnchor: false,
-        };
-    }
-    public render() {
-        const customType = this.props.customType;
-        if (!this.props.docsInfo.isPublicType(customType.name)) {
-            return null; // no-op
-        }
-
-        let typePrefix: string;
-        let codeSnippet: React.ReactNode;
-        switch (customType.kindString) {
-            case KindString.Interface:
-                typePrefix = 'Interface';
-                codeSnippet = (
-                    <Interface type={customType} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
-                );
-                break;
-
-            case KindString.Variable:
-                typePrefix = 'Enum';
-                codeSnippet = <CustomEnum type={customType} />;
-                break;
-
-            case KindString.Enumeration:
-                typePrefix = 'Enum';
-                const enumValues = _.map(customType.children, (c: CustomTypeChild) => {
-                    return {
-                        name: c.name,
-                        defaultValue: c.defaultValue,
-                    };
-                });
-                codeSnippet = <Enum values={enumValues} />;
-                break;
-
-            case KindString.TypeAlias:
-                typePrefix = 'Type Alias';
-                codeSnippet = (
-                    <span>
-                        <span style={{ color: colors.lightPurple }}>type</span> {customType.name} ={' '}
-                        {customType.type.typeDocType !== TypeDocTypes.Reflection ? (
-                            <Type
-                                type={customType.type}
-                                sectionName={this.props.sectionName}
-                                docsInfo={this.props.docsInfo}
-                            />
-                        ) : (
-                            <MethodSignature
-                                method={customType.type.method}
-                                sectionName={this.props.sectionName}
-                                shouldHideMethodName={true}
-                                shouldUseArrowSyntax={true}
-                                docsInfo={this.props.docsInfo}
-                            />
-                        )}
-                    </span>
-                );
-                break;
-
-            default:
-                throw utils.spawnSwitchErr('type.kindString', customType.kindString);
-        }
-
-        const typeDefinitionAnchorId = `${this.props.sectionName}-${customType.name}`;
-        return (
-            <div
-                id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
-                className="pb2"
-                style={{ overflow: 'hidden', width: '100%' }}
-                onMouseOver={this._setAnchorVisibility.bind(this, true)}
-                onMouseOut={this._setAnchorVisibility.bind(this, false)}
-            >
-                <AnchorTitle
-                    headerSize={HeaderSizes.H3}
-                    title={`${typePrefix} ${customType.name}`}
-                    id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
-                    shouldShowAnchor={this.state.shouldShowAnchor}
-                />
-                <div style={{ fontSize: 16 }}>
-                    <pre>
-                        <code className={`hljs ${constants.TYPE_TO_SYNTAX[this.props.docsInfo.type]}`}>
-                            {codeSnippet}
-                        </code>
-                    </pre>
-                </div>
-                <div style={{ maxWidth: 620 }}>
-                    {customType.comment && <Comment comment={customType.comment} className="py2" />}
-                </div>
-            </div>
-        );
-    }
-    private _setAnchorVisibility(shouldShowAnchor: boolean) {
-        this.setState({
-            shouldShowAnchor,
-        });
-    }
-}
diff --git a/packages/react-docs/src/ts/docs_info.ts b/packages/react-docs/src/ts/docs_info.ts
deleted file mode 100644
index 68bddef06..000000000
--- a/packages/react-docs/src/ts/docs_info.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-import { MenuSubsectionsBySection } from '@0xproject/react-shared';
-import compareVersions = require('compare-versions');
-import * as _ from 'lodash';
-
-import {
-    ContractsByVersionByNetworkId,
-    DocAgnosticFormat,
-    DocsInfoConfig,
-    DocsInfoTypeConfigs,
-    DocsMenu,
-    DoxityDocObj,
-    SectionsMap,
-    SupportedDocJson,
-    TypeDocNode,
-} from './types';
-import { doxityUtils } from './utils/doxity_utils';
-import { typeDocUtils } from './utils/typedoc_utils';
-
-export class DocsInfo {
-    public id: string;
-    public type: SupportedDocJson;
-    public displayName: string;
-    public packageUrl: string;
-    public menu: DocsMenu;
-    public sections: SectionsMap;
-    public sectionNameToMarkdown: { [sectionName: string]: string };
-    public contractsByVersionByNetworkId?: ContractsByVersionByNetworkId;
-    public typeConfigs: DocsInfoTypeConfigs;
-    private _docsInfo: DocsInfoConfig;
-    constructor(config: DocsInfoConfig) {
-        this.id = config.id;
-        this.type = config.type;
-        this.displayName = config.displayName;
-        this.packageUrl = config.packageUrl;
-        this.sections = config.sections;
-        this.sectionNameToMarkdown = config.sectionNameToMarkdown;
-        this.contractsByVersionByNetworkId = config.contractsByVersionByNetworkId;
-        this.typeConfigs = config.typeConfigs;
-        this._docsInfo = config;
-    }
-    public isPublicType(typeName: string): boolean {
-        if (_.isUndefined(this._docsInfo.typeConfigs.publicTypes)) {
-            return false;
-        }
-        const isPublic = _.includes(this._docsInfo.typeConfigs.publicTypes, typeName);
-        return isPublic;
-    }
-    public getModulePathsIfExists(sectionName: string): string[] {
-        const modulePathsIfExists = this._docsInfo.sectionNameToModulePath[sectionName];
-        return modulePathsIfExists;
-    }
-    public getMenu(selectedVersion?: string): { [section: string]: string[] } {
-        if (_.isUndefined(selectedVersion) || _.isUndefined(this._docsInfo.menuSubsectionToVersionWhenIntroduced)) {
-            return this._docsInfo.menu;
-        }
-
-        const finalMenu = _.cloneDeep(this._docsInfo.menu);
-        if (_.isUndefined(finalMenu.contracts)) {
-            return finalMenu;
-        }
-
-        // TODO: refactor to include more sections then simply the `contracts` section
-        finalMenu.contracts = _.filter(finalMenu.contracts, (contractName: string) => {
-            const versionIntroducedIfExists = this._docsInfo.menuSubsectionToVersionWhenIntroduced[contractName];
-            if (!_.isUndefined(versionIntroducedIfExists)) {
-                const existsInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0;
-                return existsInSelectedVersion;
-            } else {
-                return true;
-            }
-        });
-        return finalMenu;
-    }
-    public getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection {
-        const menuSubsectionsBySection = {} as MenuSubsectionsBySection;
-        if (_.isUndefined(docAgnosticFormat)) {
-            return menuSubsectionsBySection;
-        }
-
-        const docSections = _.keys(this.sections);
-        _.each(docSections, sectionName => {
-            const docSection = docAgnosticFormat[sectionName];
-            if (_.isUndefined(docSection)) {
-                return; // no-op
-            }
-
-            if (!_.isUndefined(this.sections.types) && sectionName === this.sections.types) {
-                const sortedTypesNames = _.sortBy(docSection.types, 'name');
-                const typeNames = _.map(sortedTypesNames, t => t.name);
-                menuSubsectionsBySection[sectionName] = typeNames;
-            } else {
-                let eventNames: string[] = [];
-                if (!_.isUndefined(docSection.events)) {
-                    const sortedEventNames = _.sortBy(docSection.events, 'name');
-                    eventNames = _.map(sortedEventNames, m => m.name);
-                }
-                const sortedMethodNames = _.sortBy(docSection.methods, 'name');
-                const methodNames = _.map(sortedMethodNames, m => m.name);
-                menuSubsectionsBySection[sectionName] = [...methodNames, ...eventNames];
-            }
-        });
-        return menuSubsectionsBySection;
-    }
-    public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat) {
-        if (_.isUndefined(this.sections.types)) {
-            return {};
-        }
-
-        const typeDocSection = docAgnosticFormat[this.sections.types];
-        const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name');
-        return typeDefinitionByName;
-    }
-    public isVisibleConstructor(sectionName: string): boolean {
-        return _.includes(this._docsInfo.visibleConstructors, sectionName);
-    }
-    public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat {
-        if (this.type === SupportedDocJson.Doxity) {
-            return doxityUtils.convertToDocAgnosticFormat(docObj as DoxityDocObj);
-        } else {
-            return typeDocUtils.convertToDocAgnosticFormat(docObj as TypeDocNode, this);
-        }
-    }
-}
diff --git a/packages/react-docs/src/ts/globals.d.ts b/packages/react-docs/src/ts/globals.d.ts
deleted file mode 100644
index c7cd53854..000000000
--- a/packages/react-docs/src/ts/globals.d.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-declare module 'react-tooltip';
-
-// compare-version declarations
-declare function compareVersions(firstVersion: string, secondVersion: string): number;
-declare module 'compare-versions' {
-    export = compareVersions;
-}
-
-declare module '*.json' {
-    const json: any;
-    /* tslint:disable */
-    export default json;
-    /* tslint:enable */
-}
diff --git a/packages/react-docs/src/ts/index.ts b/packages/react-docs/src/ts/index.ts
deleted file mode 100644
index a62c91376..000000000
--- a/packages/react-docs/src/ts/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// Exported to give users of this library added flexibility if they want to build
-// a docs page from scratch using the individual components.
-export { Badge } from './components/badge';
-export { Comment } from './components/comment';
-export { CustomEnum } from './components/custom_enum';
-export { Documentation } from './components/documentation';
-export { Enum } from './components/enum';
-export { EventDefinition } from './components/event_definition';
-export { Interface } from './components/interface';
-export { MethodBlock } from './components/method_block';
-export { MethodSignature } from './components/method_signature';
-export { SourceLink } from './components/source_link';
-export { TypeDefinition } from './components/type_definition';
-export { Type } from './components/type';
-
-export { DocsInfo } from './docs_info';
-
-export { DocsInfoConfig, DocAgnosticFormat, DoxityDocObj, DocsMenu, SupportedDocJson, TypeDocNode } from './types';
-
-export { constants } from './utils/constants';
diff --git a/packages/react-docs/src/ts/types.ts b/packages/react-docs/src/ts/types.ts
deleted file mode 100644
index d192af313..000000000
--- a/packages/react-docs/src/ts/types.ts
+++ /dev/null
@@ -1,272 +0,0 @@
-export interface DocsInfoConfig {
-    id: string;
-    type: SupportedDocJson;
-    displayName: string;
-    packageUrl: string;
-    menu: DocsMenu;
-    sections: SectionsMap;
-    sectionNameToMarkdown: { [sectionName: string]: string };
-    visibleConstructors: string[];
-    sectionNameToModulePath?: { [sectionName: string]: string[] };
-    menuSubsectionToVersionWhenIntroduced?: { [sectionName: string]: string };
-    contractsByVersionByNetworkId?: ContractsByVersionByNetworkId;
-    typeConfigs?: DocsInfoTypeConfigs;
-}
-
-export interface DocsInfoTypeConfigs {
-    typeNameToExternalLink?: { [typeName: string]: string };
-    publicTypes?: string[];
-    typeNameToPrefix?: { [typeName: string]: string };
-    typeNameToDocSection?: { [typeName: string]: string };
-}
-
-export interface DocsMenu {
-    [sectionName: string]: string[];
-}
-
-export interface SectionsMap {
-    [sectionName: string]: string;
-}
-
-export interface TypeDocType {
-    type: TypeDocTypes;
-    value: string;
-    name: string;
-    types: TypeDocType[];
-    typeArguments?: TypeDocType[];
-    declaration: TypeDocNode;
-    elementType?: TypeDocType;
-}
-
-export interface TypeDocFlags {
-    isStatic?: boolean;
-    isOptional?: boolean;
-    isPublic?: boolean;
-}
-
-export interface TypeDocGroup {
-    title: string;
-    children: number[];
-}
-
-export interface TypeDocNode {
-    id?: number;
-    name?: string;
-    kind?: string;
-    defaultValue?: string;
-    kindString?: string;
-    type?: TypeDocType;
-    fileName?: string;
-    line?: number;
-    comment?: TypeDocNode;
-    text?: string;
-    shortText?: string;
-    returns?: string;
-    declaration: TypeDocNode;
-    flags?: TypeDocFlags;
-    indexSignature?: TypeDocNode | TypeDocNode[]; // TypeDocNode in TypeDoc <V0.9.0, TypeDocNode[] in >V0.9.0
-    signatures?: TypeDocNode[];
-    parameters?: TypeDocNode[];
-    typeParameter?: TypeDocNode[];
-    sources?: TypeDocNode[];
-    children?: TypeDocNode[];
-    groups?: TypeDocGroup[];
-}
-
-export enum TypeDocTypes {
-    Intrinsic = 'intrinsic',
-    Reference = 'reference',
-    Array = 'array',
-    StringLiteral = 'stringLiteral',
-    Reflection = 'reflection',
-    Union = 'union',
-    TypeParameter = 'typeParameter',
-    Intersection = 'intersection',
-    Unknown = 'unknown',
-}
-
-// Exception: We don't make the values uppercase because these KindString's need to
-// match up those returned by TypeDoc
-export enum KindString {
-    Constructor = 'Constructor',
-    Property = 'Property',
-    Method = 'Method',
-    Interface = 'Interface',
-    TypeAlias = 'Type alias',
-    Variable = 'Variable',
-    Function = 'Function',
-    Enumeration = 'Enumeration',
-}
-
-export interface DocAgnosticFormat {
-    [sectionName: string]: DocSection;
-}
-
-export interface DocSection {
-    comment: string;
-    constructors: Array<TypescriptMethod | SolidityMethod>;
-    methods: Array<TypescriptMethod | SolidityMethod>;
-    properties: Property[];
-    types: CustomType[];
-    events?: Event[];
-}
-
-export interface TypescriptMethod extends BaseMethod {
-    source?: Source;
-    isStatic?: boolean;
-    typeParameter?: TypeParameter;
-}
-
-export interface SolidityMethod extends BaseMethod {
-    isConstant?: boolean;
-    isPayable?: boolean;
-}
-
-export interface Source {
-    fileName: string;
-    line: number;
-}
-
-export interface Parameter {
-    name: string;
-    comment: string;
-    isOptional: boolean;
-    type: Type;
-}
-
-export interface TypeParameter {
-    name: string;
-    type: Type;
-}
-
-export interface Type {
-    name: string;
-    typeDocType: TypeDocTypes;
-    value?: string;
-    typeArguments?: Type[];
-    elementType?: ElementType;
-    types?: Type[];
-    method?: TypescriptMethod;
-}
-
-export interface ElementType {
-    name: string;
-    typeDocType: TypeDocTypes;
-}
-
-export interface IndexSignature {
-    keyName: string;
-    keyType: Type;
-    valueName: string;
-}
-
-export interface CustomType {
-    name: string;
-    kindString: string;
-    type?: Type;
-    method?: TypescriptMethod;
-    indexSignature?: IndexSignature;
-    defaultValue?: string;
-    comment?: string;
-    children?: CustomTypeChild[];
-}
-
-export interface CustomTypeChild {
-    name: string;
-    type?: Type;
-    defaultValue?: string;
-}
-
-export interface Event {
-    name: string;
-    eventArgs: EventArg[];
-}
-
-export interface EventArg {
-    isIndexed: boolean;
-    name: string;
-    type: Type;
-}
-
-export interface Property {
-    name: string;
-    type: Type;
-    source?: Source;
-    comment?: string;
-}
-
-export interface BaseMethod {
-    isConstructor: boolean;
-    name: string;
-    returnComment?: string | undefined;
-    callPath: string;
-    parameters: Parameter[];
-    returnType: Type;
-    comment?: string;
-}
-
-export interface TypeDefinitionByName {
-    [typeName: string]: CustomType;
-}
-
-export enum SupportedDocJson {
-    Doxity = 'DOXITY',
-    TypeDoc = 'TYPEDOC',
-}
-
-export interface ContractsByVersionByNetworkId {
-    [version: string]: {
-        [networkName: string]: {
-            [contractName: string]: string;
-        };
-    };
-}
-
-export interface DoxityDocObj {
-    [contractName: string]: DoxityContractObj;
-}
-
-export interface DoxityContractObj {
-    title: string;
-    fileName: string;
-    name: string;
-    abiDocs: DoxityAbiDoc[];
-}
-
-export interface DoxityAbiDoc {
-    constant: boolean;
-    inputs: DoxityInput[];
-    name: string;
-    outputs: DoxityOutput[];
-    payable: boolean;
-    type: string;
-    details?: string;
-    return?: string;
-}
-
-export interface DoxityOutput {
-    name: string;
-    type: string;
-}
-
-export interface DoxityInput {
-    name: string;
-    type: string;
-    description: string;
-    indexed?: boolean;
-}
-
-export interface AddressByContractName {
-    [contractName: string]: string;
-}
-
-export interface EnumValue {
-    name: string;
-    defaultValue?: string;
-}
-
-export enum AbiTypes {
-    Constructor = 'constructor',
-    Function = 'function',
-    Event = 'event',
-}
diff --git a/packages/react-docs/src/ts/utils/constants.ts b/packages/react-docs/src/ts/utils/constants.ts
deleted file mode 100644
index c3c74fd11..000000000
--- a/packages/react-docs/src/ts/utils/constants.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { SupportedDocJson } from '../types';
-
-export const constants = {
-    TYPES_SECTION_NAME: 'types',
-    TYPE_TO_SYNTAX: {
-        [SupportedDocJson.Doxity]: 'solidity',
-        [SupportedDocJson.TypeDoc]: 'typescript',
-    } as { [supportedDocType: string]: string },
-};
diff --git a/packages/react-docs/src/ts/utils/doxity_utils.ts b/packages/react-docs/src/ts/utils/doxity_utils.ts
deleted file mode 100644
index 26dea6966..000000000
--- a/packages/react-docs/src/ts/utils/doxity_utils.ts
+++ /dev/null
@@ -1,175 +0,0 @@
-import * as _ from 'lodash';
-
-import {
-    AbiTypes,
-    DocAgnosticFormat,
-    DocSection,
-    DoxityAbiDoc,
-    DoxityContractObj,
-    DoxityDocObj,
-    DoxityInput,
-    EventArg,
-    Parameter,
-    Property,
-    SolidityMethod,
-    Type,
-    TypeDocTypes,
-} from '../types';
-
-export const doxityUtils = {
-    convertToDocAgnosticFormat(doxityDocObj: DoxityDocObj): DocAgnosticFormat {
-        const docAgnosticFormat: DocAgnosticFormat = {};
-        _.each(doxityDocObj, (doxityContractObj: DoxityContractObj, contractName: string) => {
-            const doxityConstructor = _.find(doxityContractObj.abiDocs, (abiDoc: DoxityAbiDoc) => {
-                return abiDoc.type === AbiTypes.Constructor;
-            });
-            const constructors = [];
-            if (!_.isUndefined(doxityConstructor)) {
-                const constructor = {
-                    isConstructor: true,
-                    name: doxityContractObj.name,
-                    comment: doxityConstructor.details,
-                    returnComment: doxityConstructor.return,
-                    callPath: '',
-                    parameters: this._convertParameters(doxityConstructor.inputs),
-                    returnType: this._convertType(doxityContractObj.name),
-                };
-                constructors.push(constructor);
-            }
-
-            const doxityMethods: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
-                doxityContractObj.abiDocs,
-                (abiDoc: DoxityAbiDoc) => {
-                    return this._isMethod(abiDoc);
-                },
-            );
-            const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>(
-                doxityMethods,
-                (doxityMethod: DoxityAbiDoc) => {
-                    const outputs = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs : [];
-                    let returnTypeIfExists: Type;
-                    if (outputs.length === 0) {
-                        // no-op. It's already undefined
-                    } else if (outputs.length === 1) {
-                        const outputsType = outputs[0].type;
-                        returnTypeIfExists = this._convertType(outputsType);
-                    } else {
-                        const outputsType = `[${_.map(outputs, output => output.type).join(', ')}]`;
-                        returnTypeIfExists = this._convertType(outputsType);
-                    }
-                    // For ZRXToken, we want to convert it to zrxToken, rather then simply zRXToken
-                    const callPath =
-                        contractName !== 'ZRXToken'
-                            ? `${contractName[0].toLowerCase()}${contractName.slice(1)}.`
-                            : `${contractName.slice(0, 3).toLowerCase()}${contractName.slice(3)}.`;
-                    const method = {
-                        isConstructor: false,
-                        isConstant: doxityMethod.constant,
-                        isPayable: doxityMethod.payable,
-                        name: doxityMethod.name,
-                        comment: doxityMethod.details,
-                        returnComment: doxityMethod.return,
-                        callPath,
-                        parameters: this._convertParameters(doxityMethod.inputs),
-                        returnType: returnTypeIfExists,
-                    };
-                    return method;
-                },
-            );
-
-            const doxityProperties: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
-                doxityContractObj.abiDocs,
-                (abiDoc: DoxityAbiDoc) => {
-                    return this._isProperty(abiDoc);
-                },
-            );
-            const properties = _.map<DoxityAbiDoc, Property>(doxityProperties, (doxityProperty: DoxityAbiDoc) => {
-                // We assume that none of our functions return more then a single return value
-                let typeName = doxityProperty.outputs[0].type;
-                if (!_.isEmpty(doxityProperty.inputs)) {
-                    // Properties never have more then a single input
-                    typeName = `(${doxityProperty.inputs[0].type} => ${typeName})`;
-                }
-                const property = {
-                    name: doxityProperty.name,
-                    type: this._convertType(typeName),
-                    comment: doxityProperty.details,
-                };
-                return property;
-            });
-
-            const doxityEvents = _.filter(
-                doxityContractObj.abiDocs,
-                (abiDoc: DoxityAbiDoc) => abiDoc.type === AbiTypes.Event,
-            );
-            const events = _.map(doxityEvents, doxityEvent => {
-                const event = {
-                    name: doxityEvent.name,
-                    eventArgs: this._convertEventArgs(doxityEvent.inputs),
-                };
-                return event;
-            });
-
-            const docSection: DocSection = {
-                comment: doxityContractObj.title,
-                constructors,
-                methods,
-                properties,
-                types: [],
-                events,
-            };
-            docAgnosticFormat[contractName] = docSection;
-        });
-        return docAgnosticFormat;
-    },
-    _convertParameters(inputs: DoxityInput[]): Parameter[] {
-        const parameters = _.map(inputs, input => {
-            const parameter = {
-                name: input.name,
-                comment: input.description,
-                isOptional: false,
-                type: this._convertType(input.type),
-            };
-            return parameter;
-        });
-        return parameters;
-    },
-    _convertType(typeName: string): Type {
-        const type = {
-            name: typeName,
-            typeDocType: TypeDocTypes.Intrinsic,
-        };
-        return type;
-    },
-    _isMethod(abiDoc: DoxityAbiDoc) {
-        if (abiDoc.type !== AbiTypes.Function) {
-            return false;
-        }
-        const hasInputs = !_.isEmpty(abiDoc.inputs);
-        const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
-        const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
-        const isMethod = hasNamedOutputIfExists && !isNameAllCaps;
-        return isMethod;
-    },
-    _isProperty(abiDoc: DoxityAbiDoc) {
-        if (abiDoc.type !== AbiTypes.Function) {
-            return false;
-        }
-        const hasInputs = !_.isEmpty(abiDoc.inputs);
-        const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
-        const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
-        const isProperty = !hasNamedOutputIfExists || isNameAllCaps;
-        return isProperty;
-    },
-    _convertEventArgs(inputs: DoxityInput[]): EventArg[] {
-        const eventArgs = _.map(inputs, input => {
-            const eventArg = {
-                isIndexed: input.indexed,
-                name: input.name,
-                type: this._convertType(input.type),
-            };
-            return eventArg;
-        });
-        return eventArgs;
-    },
-};
diff --git a/packages/react-docs/src/ts/utils/typedoc_utils.ts b/packages/react-docs/src/ts/utils/typedoc_utils.ts
deleted file mode 100644
index e4cea1e40..000000000
--- a/packages/react-docs/src/ts/utils/typedoc_utils.ts
+++ /dev/null
@@ -1,370 +0,0 @@
-import * as _ from 'lodash';
-
-import { DocsInfo } from '../docs_info';
-import {
-    CustomType,
-    CustomTypeChild,
-    DocAgnosticFormat,
-    DocSection,
-    IndexSignature,
-    KindString,
-    Parameter,
-    Property,
-    SectionsMap,
-    Type,
-    TypeDocNode,
-    TypeDocType,
-    TypeParameter,
-    TypescriptMethod,
-} from '../types';
-import { utils } from '../utils/utils';
-
-export const typeDocUtils = {
-    isType(entity: TypeDocNode): boolean {
-        return (
-            entity.kindString === KindString.Interface ||
-            entity.kindString === KindString.Function ||
-            entity.kindString === KindString.TypeAlias ||
-            entity.kindString === KindString.Variable ||
-            entity.kindString === KindString.Enumeration
-        );
-    },
-    isMethod(entity: TypeDocNode): boolean {
-        return entity.kindString === KindString.Method;
-    },
-    isConstructor(entity: TypeDocNode): boolean {
-        return entity.kindString === KindString.Constructor;
-    },
-    isProperty(entity: TypeDocNode): boolean {
-        return entity.kindString === KindString.Property;
-    },
-    isPrivateOrProtectedProperty(propertyName: string): boolean {
-        return _.startsWith(propertyName, '_');
-    },
-    getModuleDefinitionsBySectionName(versionDocObj: TypeDocNode, configModulePaths: string[]): TypeDocNode[] {
-        const moduleDefinitions: TypeDocNode[] = [];
-        const jsonModules = versionDocObj.children;
-        _.each(jsonModules, jsonMod => {
-            _.each(configModulePaths, configModulePath => {
-                if (_.includes(configModulePath, jsonMod.name)) {
-                    moduleDefinitions.push(jsonMod);
-                }
-            });
-        });
-        return moduleDefinitions;
-    },
-    convertToDocAgnosticFormat(typeDocJson: TypeDocNode, docsInfo: DocsInfo): DocAgnosticFormat {
-        const subMenus = _.values(docsInfo.getMenu());
-        const orderedSectionNames = _.flatten(subMenus);
-        const docAgnosticFormat: DocAgnosticFormat = {};
-        _.each(orderedSectionNames, sectionName => {
-            const modulePathsIfExists = docsInfo.getModulePathsIfExists(sectionName);
-            if (_.isUndefined(modulePathsIfExists)) {
-                return; // no-op
-            }
-            const packageDefinitions = typeDocUtils.getModuleDefinitionsBySectionName(typeDocJson, modulePathsIfExists);
-            let packageDefinitionWithMergedChildren;
-            if (_.isEmpty(packageDefinitions)) {
-                return; // no-op
-            } else if (packageDefinitions.length === 1) {
-                packageDefinitionWithMergedChildren = packageDefinitions[0];
-            } else {
-                // HACK: For now, if there are two modules to display in a single section,
-                // we simply concat the children. This works for our limited use-case where
-                // we want to display types stored in two files under a single section
-                packageDefinitionWithMergedChildren = packageDefinitions[0];
-                for (let i = 1; i < packageDefinitions.length; i++) {
-                    packageDefinitionWithMergedChildren.children = [
-                        ...packageDefinitionWithMergedChildren.children,
-                        ...packageDefinitions[i].children,
-                    ];
-                }
-            }
-
-            // Since the `types.ts` file is the only file that does not export a module/class but
-            // instead has each type export itself, we do not need to go down two levels of nesting
-            // for it.
-            let entities;
-            let packageComment = '';
-            if (sectionName === docsInfo.sections.types) {
-                entities = packageDefinitionWithMergedChildren.children;
-            } else {
-                entities = packageDefinitionWithMergedChildren.children[0].children;
-                const commentObj = packageDefinitionWithMergedChildren.children[0].comment;
-                packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment;
-            }
-
-            const docSection = typeDocUtils._convertEntitiesToDocSection(entities, docsInfo, sectionName);
-            docSection.comment = packageComment;
-            docAgnosticFormat[sectionName] = docSection;
-        });
-        return docAgnosticFormat;
-    },
-    _convertEntitiesToDocSection(entities: TypeDocNode[], docsInfo: DocsInfo, sectionName: string) {
-        const docSection: DocSection = {
-            comment: '',
-            constructors: [],
-            methods: [],
-            properties: [],
-            types: [],
-        };
-
-        let isConstructor;
-        _.each(entities, entity => {
-            switch (entity.kindString) {
-                case KindString.Constructor:
-                    isConstructor = true;
-                    const constructor = typeDocUtils._convertMethod(
-                        entity,
-                        isConstructor,
-                        docsInfo.sections,
-                        sectionName,
-                        docsInfo.id,
-                    );
-                    docSection.constructors.push(constructor);
-                    break;
-
-                case KindString.Method:
-                    if (entity.flags.isPublic) {
-                        isConstructor = false;
-                        const method = typeDocUtils._convertMethod(
-                            entity,
-                            isConstructor,
-                            docsInfo.sections,
-                            sectionName,
-                            docsInfo.id,
-                        );
-                        docSection.methods.push(method);
-                    }
-                    break;
-
-                case KindString.Property:
-                    if (!typeDocUtils.isPrivateOrProtectedProperty(entity.name)) {
-                        const property = typeDocUtils._convertProperty(
-                            entity,
-                            docsInfo.sections,
-                            sectionName,
-                            docsInfo.id,
-                        );
-                        docSection.properties.push(property);
-                    }
-                    break;
-
-                case KindString.Interface:
-                case KindString.Function:
-                case KindString.Variable:
-                case KindString.Enumeration:
-                case KindString.TypeAlias:
-                    if (docsInfo.isPublicType(entity.name)) {
-                        const customType = typeDocUtils._convertCustomType(
-                            entity,
-                            docsInfo.sections,
-                            sectionName,
-                            docsInfo.id,
-                        );
-                        docSection.types.push(customType);
-                    }
-                    break;
-
-                default:
-                    throw utils.spawnSwitchErr('kindString', entity.kindString);
-            }
-        });
-        return docSection;
-    },
-    _convertCustomType(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): CustomType {
-        const typeIfExists = !_.isUndefined(entity.type)
-            ? typeDocUtils._convertType(entity.type, sections, sectionName, docId)
-            : undefined;
-        const isConstructor = false;
-        const methodIfExists = !_.isUndefined(entity.declaration)
-            ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId)
-            : undefined;
-        const doesIndexSignatureExist = !_.isUndefined(entity.indexSignature);
-        const isIndexSignatureArray = _.isArray(entity.indexSignature);
-        // HACK: TypeDoc Versions <0.9.0 indexSignature is of type TypeDocNode[]
-        // Versions >0.9.0 have it as type TypeDocNode
-        const indexSignature =
-            doesIndexSignatureExist && isIndexSignatureArray
-                ? (entity.indexSignature as TypeDocNode[])[0]
-                : (entity.indexSignature as TypeDocNode);
-        const indexSignatureIfExists = doesIndexSignatureExist
-            ? typeDocUtils._convertIndexSignature(indexSignature, sections, sectionName, docId)
-            : undefined;
-        const commentIfExists =
-            !_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText)
-                ? entity.comment.shortText
-                : undefined;
-
-        const childrenIfExist = !_.isUndefined(entity.children)
-            ? _.map(entity.children, (child: TypeDocNode) => {
-                  const childTypeIfExists = !_.isUndefined(child.type)
-                      ? typeDocUtils._convertType(child.type, sections, sectionName, docId)
-                      : undefined;
-                  const c: CustomTypeChild = {
-                      name: child.name,
-                      type: childTypeIfExists,
-                      defaultValue: child.defaultValue,
-                  };
-                  return c;
-              })
-            : undefined;
-
-        const customType = {
-            name: entity.name,
-            kindString: entity.kindString,
-            type: typeIfExists,
-            method: methodIfExists,
-            indexSignature: indexSignatureIfExists,
-            defaultValue: entity.defaultValue,
-            comment: commentIfExists,
-            children: childrenIfExist,
-        };
-        return customType;
-    },
-    _convertIndexSignature(
-        entity: TypeDocNode,
-        sections: SectionsMap,
-        sectionName: string,
-        docId: string,
-    ): IndexSignature {
-        const key = entity.parameters[0];
-        const indexSignature = {
-            keyName: key.name,
-            keyType: typeDocUtils._convertType(key.type, sections, sectionName, docId),
-            valueName: entity.type.name,
-        };
-        return indexSignature;
-    },
-    _convertProperty(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Property {
-        const source = entity.sources[0];
-        const commentIfExists = !_.isUndefined(entity.comment) ? entity.comment.shortText : undefined;
-        const property = {
-            name: entity.name,
-            type: typeDocUtils._convertType(entity.type, sections, sectionName, docId),
-            source: {
-                fileName: source.fileName,
-                line: source.line,
-            },
-            comment: commentIfExists,
-        };
-        return property;
-    },
-    _convertMethod(
-        entity: TypeDocNode,
-        isConstructor: boolean,
-        sections: SectionsMap,
-        sectionName: string,
-        docId: string,
-    ): TypescriptMethod {
-        const signature = entity.signatures[0];
-        const source = entity.sources[0];
-        const hasComment = !_.isUndefined(signature.comment);
-        const isStatic = _.isUndefined(entity.flags.isStatic) ? false : entity.flags.isStatic;
-
-        // HACK: we use the fact that the sectionName is the same as the property name at the top-level
-        // of the public interface. In the future, we shouldn't use this hack but rather get it from the JSON.
-        let callPath;
-        if (isConstructor || entity.name === '__type') {
-            callPath = '';
-            // TODO: Get rid of this 0x-specific logic
-        } else if (docId === 'ZERO_EX_JS') {
-            const topLevelInterface = isStatic ? 'ZeroEx.' : 'zeroEx.';
-            callPath =
-                !_.isUndefined(sections.zeroEx) && sectionName !== sections.zeroEx
-                    ? `${topLevelInterface}${sectionName}.`
-                    : topLevelInterface;
-        } else {
-            callPath = `${sectionName}.`;
-        }
-
-        const parameters = _.map(signature.parameters, param => {
-            return typeDocUtils._convertParameter(param, sections, sectionName, docId);
-        });
-        const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, docId);
-        const typeParameter = _.isUndefined(signature.typeParameter)
-            ? undefined
-            : typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, docId);
-
-        const method = {
-            isConstructor,
-            isStatic,
-            name: signature.name,
-            comment: hasComment ? signature.comment.shortText : undefined,
-            returnComment: hasComment && signature.comment.returns ? signature.comment.returns : undefined,
-            source: {
-                fileName: source.fileName,
-                line: source.line,
-            },
-            callPath,
-            parameters,
-            returnType,
-            typeParameter,
-        };
-        return method;
-    },
-    _convertTypeParameter(
-        entity: TypeDocNode,
-        sections: SectionsMap,
-        sectionName: string,
-        docId: string,
-    ): TypeParameter {
-        const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId);
-        const parameter = {
-            name: entity.name,
-            type,
-        };
-        return parameter;
-    },
-    _convertParameter(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Parameter {
-        let comment = '<No comment>';
-        if (entity.comment && entity.comment.shortText) {
-            comment = entity.comment.shortText;
-        } else if (entity.comment && entity.comment.text) {
-            comment = entity.comment.text;
-        }
-
-        const isOptional = !_.isUndefined(entity.flags.isOptional) ? entity.flags.isOptional : false;
-
-        const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId);
-
-        const parameter = {
-            name: entity.name,
-            comment,
-            isOptional,
-            type,
-        };
-        return parameter;
-    },
-    _convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, docId: string): Type {
-        const typeArguments = _.map(entity.typeArguments, typeArgument => {
-            return typeDocUtils._convertType(typeArgument, sections, sectionName, docId);
-        });
-        const types = _.map(entity.types, t => {
-            return typeDocUtils._convertType(t, sections, sectionName, docId);
-        });
-
-        const isConstructor = false;
-        const methodIfExists = !_.isUndefined(entity.declaration)
-            ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId)
-            : undefined;
-
-        const elementTypeIfExists = !_.isUndefined(entity.elementType)
-            ? {
-                  name: entity.elementType.name,
-                  typeDocType: entity.elementType.type,
-              }
-            : undefined;
-
-        const type = {
-            name: entity.name,
-            value: entity.value,
-            typeDocType: entity.type,
-            typeArguments,
-            elementType: elementTypeIfExists,
-            types,
-            method: methodIfExists,
-        };
-        return type;
-    },
-};
diff --git a/packages/react-docs/src/ts/utils/utils.ts b/packages/react-docs/src/ts/utils/utils.ts
deleted file mode 100644
index 8e1a80a44..000000000
--- a/packages/react-docs/src/ts/utils/utils.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export const utils = {
-    consoleLog(message: string) {
-        /* tslint:disable */
-        console.log(message);
-        /* tslint:enable */
-    },
-    spawnSwitchErr(name: string, value: any) {
-        return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
-    },
-};
diff --git a/packages/react-docs/src/types.ts b/packages/react-docs/src/types.ts
new file mode 100644
index 000000000..d192af313
--- /dev/null
+++ b/packages/react-docs/src/types.ts
@@ -0,0 +1,272 @@
+export interface DocsInfoConfig {
+    id: string;
+    type: SupportedDocJson;
+    displayName: string;
+    packageUrl: string;
+    menu: DocsMenu;
+    sections: SectionsMap;
+    sectionNameToMarkdown: { [sectionName: string]: string };
+    visibleConstructors: string[];
+    sectionNameToModulePath?: { [sectionName: string]: string[] };
+    menuSubsectionToVersionWhenIntroduced?: { [sectionName: string]: string };
+    contractsByVersionByNetworkId?: ContractsByVersionByNetworkId;
+    typeConfigs?: DocsInfoTypeConfigs;
+}
+
+export interface DocsInfoTypeConfigs {
+    typeNameToExternalLink?: { [typeName: string]: string };
+    publicTypes?: string[];
+    typeNameToPrefix?: { [typeName: string]: string };
+    typeNameToDocSection?: { [typeName: string]: string };
+}
+
+export interface DocsMenu {
+    [sectionName: string]: string[];
+}
+
+export interface SectionsMap {
+    [sectionName: string]: string;
+}
+
+export interface TypeDocType {
+    type: TypeDocTypes;
+    value: string;
+    name: string;
+    types: TypeDocType[];
+    typeArguments?: TypeDocType[];
+    declaration: TypeDocNode;
+    elementType?: TypeDocType;
+}
+
+export interface TypeDocFlags {
+    isStatic?: boolean;
+    isOptional?: boolean;
+    isPublic?: boolean;
+}
+
+export interface TypeDocGroup {
+    title: string;
+    children: number[];
+}
+
+export interface TypeDocNode {
+    id?: number;
+    name?: string;
+    kind?: string;
+    defaultValue?: string;
+    kindString?: string;
+    type?: TypeDocType;
+    fileName?: string;
+    line?: number;
+    comment?: TypeDocNode;
+    text?: string;
+    shortText?: string;
+    returns?: string;
+    declaration: TypeDocNode;
+    flags?: TypeDocFlags;
+    indexSignature?: TypeDocNode | TypeDocNode[]; // TypeDocNode in TypeDoc <V0.9.0, TypeDocNode[] in >V0.9.0
+    signatures?: TypeDocNode[];
+    parameters?: TypeDocNode[];
+    typeParameter?: TypeDocNode[];
+    sources?: TypeDocNode[];
+    children?: TypeDocNode[];
+    groups?: TypeDocGroup[];
+}
+
+export enum TypeDocTypes {
+    Intrinsic = 'intrinsic',
+    Reference = 'reference',
+    Array = 'array',
+    StringLiteral = 'stringLiteral',
+    Reflection = 'reflection',
+    Union = 'union',
+    TypeParameter = 'typeParameter',
+    Intersection = 'intersection',
+    Unknown = 'unknown',
+}
+
+// Exception: We don't make the values uppercase because these KindString's need to
+// match up those returned by TypeDoc
+export enum KindString {
+    Constructor = 'Constructor',
+    Property = 'Property',
+    Method = 'Method',
+    Interface = 'Interface',
+    TypeAlias = 'Type alias',
+    Variable = 'Variable',
+    Function = 'Function',
+    Enumeration = 'Enumeration',
+}
+
+export interface DocAgnosticFormat {
+    [sectionName: string]: DocSection;
+}
+
+export interface DocSection {
+    comment: string;
+    constructors: Array<TypescriptMethod | SolidityMethod>;
+    methods: Array<TypescriptMethod | SolidityMethod>;
+    properties: Property[];
+    types: CustomType[];
+    events?: Event[];
+}
+
+export interface TypescriptMethod extends BaseMethod {
+    source?: Source;
+    isStatic?: boolean;
+    typeParameter?: TypeParameter;
+}
+
+export interface SolidityMethod extends BaseMethod {
+    isConstant?: boolean;
+    isPayable?: boolean;
+}
+
+export interface Source {
+    fileName: string;
+    line: number;
+}
+
+export interface Parameter {
+    name: string;
+    comment: string;
+    isOptional: boolean;
+    type: Type;
+}
+
+export interface TypeParameter {
+    name: string;
+    type: Type;
+}
+
+export interface Type {
+    name: string;
+    typeDocType: TypeDocTypes;
+    value?: string;
+    typeArguments?: Type[];
+    elementType?: ElementType;
+    types?: Type[];
+    method?: TypescriptMethod;
+}
+
+export interface ElementType {
+    name: string;
+    typeDocType: TypeDocTypes;
+}
+
+export interface IndexSignature {
+    keyName: string;
+    keyType: Type;
+    valueName: string;
+}
+
+export interface CustomType {
+    name: string;
+    kindString: string;
+    type?: Type;
+    method?: TypescriptMethod;
+    indexSignature?: IndexSignature;
+    defaultValue?: string;
+    comment?: string;
+    children?: CustomTypeChild[];
+}
+
+export interface CustomTypeChild {
+    name: string;
+    type?: Type;
+    defaultValue?: string;
+}
+
+export interface Event {
+    name: string;
+    eventArgs: EventArg[];
+}
+
+export interface EventArg {
+    isIndexed: boolean;
+    name: string;
+    type: Type;
+}
+
+export interface Property {
+    name: string;
+    type: Type;
+    source?: Source;
+    comment?: string;
+}
+
+export interface BaseMethod {
+    isConstructor: boolean;
+    name: string;
+    returnComment?: string | undefined;
+    callPath: string;
+    parameters: Parameter[];
+    returnType: Type;
+    comment?: string;
+}
+
+export interface TypeDefinitionByName {
+    [typeName: string]: CustomType;
+}
+
+export enum SupportedDocJson {
+    Doxity = 'DOXITY',
+    TypeDoc = 'TYPEDOC',
+}
+
+export interface ContractsByVersionByNetworkId {
+    [version: string]: {
+        [networkName: string]: {
+            [contractName: string]: string;
+        };
+    };
+}
+
+export interface DoxityDocObj {
+    [contractName: string]: DoxityContractObj;
+}
+
+export interface DoxityContractObj {
+    title: string;
+    fileName: string;
+    name: string;
+    abiDocs: DoxityAbiDoc[];
+}
+
+export interface DoxityAbiDoc {
+    constant: boolean;
+    inputs: DoxityInput[];
+    name: string;
+    outputs: DoxityOutput[];
+    payable: boolean;
+    type: string;
+    details?: string;
+    return?: string;
+}
+
+export interface DoxityOutput {
+    name: string;
+    type: string;
+}
+
+export interface DoxityInput {
+    name: string;
+    type: string;
+    description: string;
+    indexed?: boolean;
+}
+
+export interface AddressByContractName {
+    [contractName: string]: string;
+}
+
+export interface EnumValue {
+    name: string;
+    defaultValue?: string;
+}
+
+export enum AbiTypes {
+    Constructor = 'constructor',
+    Function = 'function',
+    Event = 'event',
+}
diff --git a/packages/react-docs/src/utils/constants.ts b/packages/react-docs/src/utils/constants.ts
new file mode 100644
index 000000000..c3c74fd11
--- /dev/null
+++ b/packages/react-docs/src/utils/constants.ts
@@ -0,0 +1,9 @@
+import { SupportedDocJson } from '../types';
+
+export const constants = {
+    TYPES_SECTION_NAME: 'types',
+    TYPE_TO_SYNTAX: {
+        [SupportedDocJson.Doxity]: 'solidity',
+        [SupportedDocJson.TypeDoc]: 'typescript',
+    } as { [supportedDocType: string]: string },
+};
diff --git a/packages/react-docs/src/utils/doxity_utils.ts b/packages/react-docs/src/utils/doxity_utils.ts
new file mode 100644
index 000000000..26dea6966
--- /dev/null
+++ b/packages/react-docs/src/utils/doxity_utils.ts
@@ -0,0 +1,175 @@
+import * as _ from 'lodash';
+
+import {
+    AbiTypes,
+    DocAgnosticFormat,
+    DocSection,
+    DoxityAbiDoc,
+    DoxityContractObj,
+    DoxityDocObj,
+    DoxityInput,
+    EventArg,
+    Parameter,
+    Property,
+    SolidityMethod,
+    Type,
+    TypeDocTypes,
+} from '../types';
+
+export const doxityUtils = {
+    convertToDocAgnosticFormat(doxityDocObj: DoxityDocObj): DocAgnosticFormat {
+        const docAgnosticFormat: DocAgnosticFormat = {};
+        _.each(doxityDocObj, (doxityContractObj: DoxityContractObj, contractName: string) => {
+            const doxityConstructor = _.find(doxityContractObj.abiDocs, (abiDoc: DoxityAbiDoc) => {
+                return abiDoc.type === AbiTypes.Constructor;
+            });
+            const constructors = [];
+            if (!_.isUndefined(doxityConstructor)) {
+                const constructor = {
+                    isConstructor: true,
+                    name: doxityContractObj.name,
+                    comment: doxityConstructor.details,
+                    returnComment: doxityConstructor.return,
+                    callPath: '',
+                    parameters: this._convertParameters(doxityConstructor.inputs),
+                    returnType: this._convertType(doxityContractObj.name),
+                };
+                constructors.push(constructor);
+            }
+
+            const doxityMethods: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
+                doxityContractObj.abiDocs,
+                (abiDoc: DoxityAbiDoc) => {
+                    return this._isMethod(abiDoc);
+                },
+            );
+            const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>(
+                doxityMethods,
+                (doxityMethod: DoxityAbiDoc) => {
+                    const outputs = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs : [];
+                    let returnTypeIfExists: Type;
+                    if (outputs.length === 0) {
+                        // no-op. It's already undefined
+                    } else if (outputs.length === 1) {
+                        const outputsType = outputs[0].type;
+                        returnTypeIfExists = this._convertType(outputsType);
+                    } else {
+                        const outputsType = `[${_.map(outputs, output => output.type).join(', ')}]`;
+                        returnTypeIfExists = this._convertType(outputsType);
+                    }
+                    // For ZRXToken, we want to convert it to zrxToken, rather then simply zRXToken
+                    const callPath =
+                        contractName !== 'ZRXToken'
+                            ? `${contractName[0].toLowerCase()}${contractName.slice(1)}.`
+                            : `${contractName.slice(0, 3).toLowerCase()}${contractName.slice(3)}.`;
+                    const method = {
+                        isConstructor: false,
+                        isConstant: doxityMethod.constant,
+                        isPayable: doxityMethod.payable,
+                        name: doxityMethod.name,
+                        comment: doxityMethod.details,
+                        returnComment: doxityMethod.return,
+                        callPath,
+                        parameters: this._convertParameters(doxityMethod.inputs),
+                        returnType: returnTypeIfExists,
+                    };
+                    return method;
+                },
+            );
+
+            const doxityProperties: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
+                doxityContractObj.abiDocs,
+                (abiDoc: DoxityAbiDoc) => {
+                    return this._isProperty(abiDoc);
+                },
+            );
+            const properties = _.map<DoxityAbiDoc, Property>(doxityProperties, (doxityProperty: DoxityAbiDoc) => {
+                // We assume that none of our functions return more then a single return value
+                let typeName = doxityProperty.outputs[0].type;
+                if (!_.isEmpty(doxityProperty.inputs)) {
+                    // Properties never have more then a single input
+                    typeName = `(${doxityProperty.inputs[0].type} => ${typeName})`;
+                }
+                const property = {
+                    name: doxityProperty.name,
+                    type: this._convertType(typeName),
+                    comment: doxityProperty.details,
+                };
+                return property;
+            });
+
+            const doxityEvents = _.filter(
+                doxityContractObj.abiDocs,
+                (abiDoc: DoxityAbiDoc) => abiDoc.type === AbiTypes.Event,
+            );
+            const events = _.map(doxityEvents, doxityEvent => {
+                const event = {
+                    name: doxityEvent.name,
+                    eventArgs: this._convertEventArgs(doxityEvent.inputs),
+                };
+                return event;
+            });
+
+            const docSection: DocSection = {
+                comment: doxityContractObj.title,
+                constructors,
+                methods,
+                properties,
+                types: [],
+                events,
+            };
+            docAgnosticFormat[contractName] = docSection;
+        });
+        return docAgnosticFormat;
+    },
+    _convertParameters(inputs: DoxityInput[]): Parameter[] {
+        const parameters = _.map(inputs, input => {
+            const parameter = {
+                name: input.name,
+                comment: input.description,
+                isOptional: false,
+                type: this._convertType(input.type),
+            };
+            return parameter;
+        });
+        return parameters;
+    },
+    _convertType(typeName: string): Type {
+        const type = {
+            name: typeName,
+            typeDocType: TypeDocTypes.Intrinsic,
+        };
+        return type;
+    },
+    _isMethod(abiDoc: DoxityAbiDoc) {
+        if (abiDoc.type !== AbiTypes.Function) {
+            return false;
+        }
+        const hasInputs = !_.isEmpty(abiDoc.inputs);
+        const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
+        const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
+        const isMethod = hasNamedOutputIfExists && !isNameAllCaps;
+        return isMethod;
+    },
+    _isProperty(abiDoc: DoxityAbiDoc) {
+        if (abiDoc.type !== AbiTypes.Function) {
+            return false;
+        }
+        const hasInputs = !_.isEmpty(abiDoc.inputs);
+        const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
+        const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
+        const isProperty = !hasNamedOutputIfExists || isNameAllCaps;
+        return isProperty;
+    },
+    _convertEventArgs(inputs: DoxityInput[]): EventArg[] {
+        const eventArgs = _.map(inputs, input => {
+            const eventArg = {
+                isIndexed: input.indexed,
+                name: input.name,
+                type: this._convertType(input.type),
+            };
+            return eventArg;
+        });
+        return eventArgs;
+    },
+};
diff --git a/packages/react-docs/src/utils/typedoc_utils.ts b/packages/react-docs/src/utils/typedoc_utils.ts
new file mode 100644
index 000000000..e4cea1e40
--- /dev/null
+++ b/packages/react-docs/src/utils/typedoc_utils.ts
@@ -0,0 +1,370 @@
+import * as _ from 'lodash';
+
+import { DocsInfo } from '../docs_info';
+import {
+    CustomType,
+    CustomTypeChild,
+    DocAgnosticFormat,
+    DocSection,
+    IndexSignature,
+    KindString,
+    Parameter,
+    Property,
+    SectionsMap,
+    Type,
+    TypeDocNode,
+    TypeDocType,
+    TypeParameter,
+    TypescriptMethod,
+} from '../types';
+import { utils } from '../utils/utils';
+
+export const typeDocUtils = {
+    isType(entity: TypeDocNode): boolean {
+        return (
+            entity.kindString === KindString.Interface ||
+            entity.kindString === KindString.Function ||
+            entity.kindString === KindString.TypeAlias ||
+            entity.kindString === KindString.Variable ||
+            entity.kindString === KindString.Enumeration
+        );
+    },
+    isMethod(entity: TypeDocNode): boolean {
+        return entity.kindString === KindString.Method;
+    },
+    isConstructor(entity: TypeDocNode): boolean {
+        return entity.kindString === KindString.Constructor;
+    },
+    isProperty(entity: TypeDocNode): boolean {
+        return entity.kindString === KindString.Property;
+    },
+    isPrivateOrProtectedProperty(propertyName: string): boolean {
+        return _.startsWith(propertyName, '_');
+    },
+    getModuleDefinitionsBySectionName(versionDocObj: TypeDocNode, configModulePaths: string[]): TypeDocNode[] {
+        const moduleDefinitions: TypeDocNode[] = [];
+        const jsonModules = versionDocObj.children;
+        _.each(jsonModules, jsonMod => {
+            _.each(configModulePaths, configModulePath => {
+                if (_.includes(configModulePath, jsonMod.name)) {
+                    moduleDefinitions.push(jsonMod);
+                }
+            });
+        });
+        return moduleDefinitions;
+    },
+    convertToDocAgnosticFormat(typeDocJson: TypeDocNode, docsInfo: DocsInfo): DocAgnosticFormat {
+        const subMenus = _.values(docsInfo.getMenu());
+        const orderedSectionNames = _.flatten(subMenus);
+        const docAgnosticFormat: DocAgnosticFormat = {};
+        _.each(orderedSectionNames, sectionName => {
+            const modulePathsIfExists = docsInfo.getModulePathsIfExists(sectionName);
+            if (_.isUndefined(modulePathsIfExists)) {
+                return; // no-op
+            }
+            const packageDefinitions = typeDocUtils.getModuleDefinitionsBySectionName(typeDocJson, modulePathsIfExists);
+            let packageDefinitionWithMergedChildren;
+            if (_.isEmpty(packageDefinitions)) {
+                return; // no-op
+            } else if (packageDefinitions.length === 1) {
+                packageDefinitionWithMergedChildren = packageDefinitions[0];
+            } else {
+                // HACK: For now, if there are two modules to display in a single section,
+                // we simply concat the children. This works for our limited use-case where
+                // we want to display types stored in two files under a single section
+                packageDefinitionWithMergedChildren = packageDefinitions[0];
+                for (let i = 1; i < packageDefinitions.length; i++) {
+                    packageDefinitionWithMergedChildren.children = [
+                        ...packageDefinitionWithMergedChildren.children,
+                        ...packageDefinitions[i].children,
+                    ];
+                }
+            }
+
+            // Since the `types.ts` file is the only file that does not export a module/class but
+            // instead has each type export itself, we do not need to go down two levels of nesting
+            // for it.
+            let entities;
+            let packageComment = '';
+            if (sectionName === docsInfo.sections.types) {
+                entities = packageDefinitionWithMergedChildren.children;
+            } else {
+                entities = packageDefinitionWithMergedChildren.children[0].children;
+                const commentObj = packageDefinitionWithMergedChildren.children[0].comment;
+                packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment;
+            }
+
+            const docSection = typeDocUtils._convertEntitiesToDocSection(entities, docsInfo, sectionName);
+            docSection.comment = packageComment;
+            docAgnosticFormat[sectionName] = docSection;
+        });
+        return docAgnosticFormat;
+    },
+    _convertEntitiesToDocSection(entities: TypeDocNode[], docsInfo: DocsInfo, sectionName: string) {
+        const docSection: DocSection = {
+            comment: '',
+            constructors: [],
+            methods: [],
+            properties: [],
+            types: [],
+        };
+
+        let isConstructor;
+        _.each(entities, entity => {
+            switch (entity.kindString) {
+                case KindString.Constructor:
+                    isConstructor = true;
+                    const constructor = typeDocUtils._convertMethod(
+                        entity,
+                        isConstructor,
+                        docsInfo.sections,
+                        sectionName,
+                        docsInfo.id,
+                    );
+                    docSection.constructors.push(constructor);
+                    break;
+
+                case KindString.Method:
+                    if (entity.flags.isPublic) {
+                        isConstructor = false;
+                        const method = typeDocUtils._convertMethod(
+                            entity,
+                            isConstructor,
+                            docsInfo.sections,
+                            sectionName,
+                            docsInfo.id,
+                        );
+                        docSection.methods.push(method);
+                    }
+                    break;
+
+                case KindString.Property:
+                    if (!typeDocUtils.isPrivateOrProtectedProperty(entity.name)) {
+                        const property = typeDocUtils._convertProperty(
+                            entity,
+                            docsInfo.sections,
+                            sectionName,
+                            docsInfo.id,
+                        );
+                        docSection.properties.push(property);
+                    }
+                    break;
+
+                case KindString.Interface:
+                case KindString.Function:
+                case KindString.Variable:
+                case KindString.Enumeration:
+                case KindString.TypeAlias:
+                    if (docsInfo.isPublicType(entity.name)) {
+                        const customType = typeDocUtils._convertCustomType(
+                            entity,
+                            docsInfo.sections,
+                            sectionName,
+                            docsInfo.id,
+                        );
+                        docSection.types.push(customType);
+                    }
+                    break;
+
+                default:
+                    throw utils.spawnSwitchErr('kindString', entity.kindString);
+            }
+        });
+        return docSection;
+    },
+    _convertCustomType(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): CustomType {
+        const typeIfExists = !_.isUndefined(entity.type)
+            ? typeDocUtils._convertType(entity.type, sections, sectionName, docId)
+            : undefined;
+        const isConstructor = false;
+        const methodIfExists = !_.isUndefined(entity.declaration)
+            ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId)
+            : undefined;
+        const doesIndexSignatureExist = !_.isUndefined(entity.indexSignature);
+        const isIndexSignatureArray = _.isArray(entity.indexSignature);
+        // HACK: TypeDoc Versions <0.9.0 indexSignature is of type TypeDocNode[]
+        // Versions >0.9.0 have it as type TypeDocNode
+        const indexSignature =
+            doesIndexSignatureExist && isIndexSignatureArray
+                ? (entity.indexSignature as TypeDocNode[])[0]
+                : (entity.indexSignature as TypeDocNode);
+        const indexSignatureIfExists = doesIndexSignatureExist
+            ? typeDocUtils._convertIndexSignature(indexSignature, sections, sectionName, docId)
+            : undefined;
+        const commentIfExists =
+            !_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText)
+                ? entity.comment.shortText
+                : undefined;
+
+        const childrenIfExist = !_.isUndefined(entity.children)
+            ? _.map(entity.children, (child: TypeDocNode) => {
+                  const childTypeIfExists = !_.isUndefined(child.type)
+                      ? typeDocUtils._convertType(child.type, sections, sectionName, docId)
+                      : undefined;
+                  const c: CustomTypeChild = {
+                      name: child.name,
+                      type: childTypeIfExists,
+                      defaultValue: child.defaultValue,
+                  };
+                  return c;
+              })
+            : undefined;
+
+        const customType = {
+            name: entity.name,
+            kindString: entity.kindString,
+            type: typeIfExists,
+            method: methodIfExists,
+            indexSignature: indexSignatureIfExists,
+            defaultValue: entity.defaultValue,
+            comment: commentIfExists,
+            children: childrenIfExist,
+        };
+        return customType;
+    },
+    _convertIndexSignature(
+        entity: TypeDocNode,
+        sections: SectionsMap,
+        sectionName: string,
+        docId: string,
+    ): IndexSignature {
+        const key = entity.parameters[0];
+        const indexSignature = {
+            keyName: key.name,
+            keyType: typeDocUtils._convertType(key.type, sections, sectionName, docId),
+            valueName: entity.type.name,
+        };
+        return indexSignature;
+    },
+    _convertProperty(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Property {
+        const source = entity.sources[0];
+        const commentIfExists = !_.isUndefined(entity.comment) ? entity.comment.shortText : undefined;
+        const property = {
+            name: entity.name,
+            type: typeDocUtils._convertType(entity.type, sections, sectionName, docId),
+            source: {
+                fileName: source.fileName,
+                line: source.line,
+            },
+            comment: commentIfExists,
+        };
+        return property;
+    },
+    _convertMethod(
+        entity: TypeDocNode,
+        isConstructor: boolean,
+        sections: SectionsMap,
+        sectionName: string,
+        docId: string,
+    ): TypescriptMethod {
+        const signature = entity.signatures[0];
+        const source = entity.sources[0];
+        const hasComment = !_.isUndefined(signature.comment);
+        const isStatic = _.isUndefined(entity.flags.isStatic) ? false : entity.flags.isStatic;
+
+        // HACK: we use the fact that the sectionName is the same as the property name at the top-level
+        // of the public interface. In the future, we shouldn't use this hack but rather get it from the JSON.
+        let callPath;
+        if (isConstructor || entity.name === '__type') {
+            callPath = '';
+            // TODO: Get rid of this 0x-specific logic
+        } else if (docId === 'ZERO_EX_JS') {
+            const topLevelInterface = isStatic ? 'ZeroEx.' : 'zeroEx.';
+            callPath =
+                !_.isUndefined(sections.zeroEx) && sectionName !== sections.zeroEx
+                    ? `${topLevelInterface}${sectionName}.`
+                    : topLevelInterface;
+        } else {
+            callPath = `${sectionName}.`;
+        }
+
+        const parameters = _.map(signature.parameters, param => {
+            return typeDocUtils._convertParameter(param, sections, sectionName, docId);
+        });
+        const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, docId);
+        const typeParameter = _.isUndefined(signature.typeParameter)
+            ? undefined
+            : typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, docId);
+
+        const method = {
+            isConstructor,
+            isStatic,
+            name: signature.name,
+            comment: hasComment ? signature.comment.shortText : undefined,
+            returnComment: hasComment && signature.comment.returns ? signature.comment.returns : undefined,
+            source: {
+                fileName: source.fileName,
+                line: source.line,
+            },
+            callPath,
+            parameters,
+            returnType,
+            typeParameter,
+        };
+        return method;
+    },
+    _convertTypeParameter(
+        entity: TypeDocNode,
+        sections: SectionsMap,
+        sectionName: string,
+        docId: string,
+    ): TypeParameter {
+        const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId);
+        const parameter = {
+            name: entity.name,
+            type,
+        };
+        return parameter;
+    },
+    _convertParameter(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Parameter {
+        let comment = '<No comment>';
+        if (entity.comment && entity.comment.shortText) {
+            comment = entity.comment.shortText;
+        } else if (entity.comment && entity.comment.text) {
+            comment = entity.comment.text;
+        }
+
+        const isOptional = !_.isUndefined(entity.flags.isOptional) ? entity.flags.isOptional : false;
+
+        const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId);
+
+        const parameter = {
+            name: entity.name,
+            comment,
+            isOptional,
+            type,
+        };
+        return parameter;
+    },
+    _convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, docId: string): Type {
+        const typeArguments = _.map(entity.typeArguments, typeArgument => {
+            return typeDocUtils._convertType(typeArgument, sections, sectionName, docId);
+        });
+        const types = _.map(entity.types, t => {
+            return typeDocUtils._convertType(t, sections, sectionName, docId);
+        });
+
+        const isConstructor = false;
+        const methodIfExists = !_.isUndefined(entity.declaration)
+            ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId)
+            : undefined;
+
+        const elementTypeIfExists = !_.isUndefined(entity.elementType)
+            ? {
+                  name: entity.elementType.name,
+                  typeDocType: entity.elementType.type,
+              }
+            : undefined;
+
+        const type = {
+            name: entity.name,
+            value: entity.value,
+            typeDocType: entity.type,
+            typeArguments,
+            elementType: elementTypeIfExists,
+            types,
+            method: methodIfExists,
+        };
+        return type;
+    },
+};
diff --git a/packages/react-docs/src/utils/utils.ts b/packages/react-docs/src/utils/utils.ts
new file mode 100644
index 000000000..8e1a80a44
--- /dev/null
+++ b/packages/react-docs/src/utils/utils.ts
@@ -0,0 +1,10 @@
+export const utils = {
+    consoleLog(message: string) {
+        /* tslint:disable */
+        console.log(message);
+        /* tslint:enable */
+    },
+    spawnSwitchErr(name: string, value: any) {
+        return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
+    },
+};
diff --git a/packages/react-docs/tsconfig.json b/packages/react-docs/tsconfig.json
index 44055a037..9af6638a2 100644
--- a/packages/react-docs/tsconfig.json
+++ b/packages/react-docs/tsconfig.json
@@ -9,5 +9,5 @@
             "*": ["node_modules/@types/*", "*"]
         }
     },
-    "include": ["./src/ts/**/*"]
+    "include": ["./src/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json
index adfbce52c..ac1d05f38 100644
--- a/packages/react-shared/package.json
+++ b/packages/react-shared/package.json
@@ -1,50 +1,53 @@
 {
-  "name": "@0xproject/react-shared",
-  "version": "0.0.1",
-  "description": "0x shared react components",
-  "main": "lib/index.js",
-  "types": "lib/index.d.ts",
-  "scripts": {
-    "lint": "tslint --project . 'src/ts/**/*.ts' 'src/ts/**/*.tsx'",
-    "build": "tsc",
-    "build:watch": "tsc -w",
-    "clean": "shx rm -rf lib"
-  },
-  "author": "Fabio Berger",
-  "license": "Apache-2.0",
-  "bugs": {
-      "url": "https://github.com/0xProject/0x-monorepo/issues"
-  },
-  "homepage": "https://github.com/0xProject/0x-monorepo/packages/react-shared/README.md",
-  "repository": {
-      "type": "git",
-      "url": "https://github.com/0xProject/0x-monorepo.git"
-  },
-  "devDependencies": {
-    "@0xproject/tslint-config": "^0.4.9",
-    "@types/lodash": "^4.14.86",
-    "@types/material-ui": "0.18.0",
-    "@types/node": "^8.0.53",
-    "@types/react": "^15.0.15",
-    "@types/react-dom": "^0.14.23",
-    "@types/react-scroll": "0.0.31",
-    "shx": "^0.2.2",
-    "tslint": "^5.9.1",
-    "typescript": "2.7.1"
-  },
-  "dependencies": {
-    "basscss": "^8.0.3",
-    "is-mobile": "^0.2.2",
-    "lodash": "^4.17.4",
-    "material-ui": "^0.17.1",
-    "react": "15.6.1",
-    "react-dom": "15.6.1",
-    "react-highlight": "0xproject/react-highlight",
-    "react-markdown": "^3.2.2",
-    "react-scroll": "^1.5.2",
-    "react-tap-event-plugin": "^2.0.1"
-  },
-  "publishConfig": {
-    "access": "public"
-  }
+    "name": "@0xproject/react-shared",
+    "version": "0.0.1",
+    "description": "0x shared react components",
+    "main": "lib/index.js",
+    "types": "lib/index.d.ts",
+    "scripts": {
+        "lint": "tslint --project . 'src/**/*.ts' 'src/**/*.tsx'",
+        "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
+        "build:watch": "tsc -w",
+        "clean": "shx rm -rf lib scripts"
+    },
+    "author": "Fabio Berger",
+    "license": "Apache-2.0",
+    "bugs": {
+        "url": "https://github.com/0xProject/0x-monorepo/issues"
+    },
+    "homepage": "https://github.com/0xProject/0x-monorepo/packages/react-shared/README.md",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/0xProject/0x-monorepo.git"
+    },
+    "devDependencies": {
+        "@0xproject/dev-utils": "^0.2.1",
+        "@0xproject/monorepo-scripts": "^0.1.12",
+        "@0xproject/tslint-config": "^0.4.9",
+        "@types/lodash": "^4.14.86",
+        "@types/material-ui": "0.18.0",
+        "@types/node": "^8.0.53",
+        "@types/react": "^15.0.15",
+        "@types/react-dom": "^0.14.23",
+        "@types/react-scroll": "0.0.31",
+        "copyfiles": "^1.2.0",
+        "shx": "^0.2.2",
+        "tslint": "^5.9.1",
+        "typescript": "2.7.1"
+    },
+    "dependencies": {
+        "basscss": "^8.0.3",
+        "is-mobile": "^0.2.2",
+        "lodash": "^4.17.4",
+        "material-ui": "^0.17.1",
+        "react": "15.6.1",
+        "react-dom": "15.6.1",
+        "react-highlight": "0xproject/react-highlight",
+        "react-markdown": "^3.2.2",
+        "react-scroll": "^1.5.2",
+        "react-tap-event-plugin": "^2.0.1"
+    },
+    "publishConfig": {
+        "access": "public"
+    }
 }
diff --git a/packages/react-shared/scripts/postpublish.js b/packages/react-shared/scripts/postpublish.js
deleted file mode 100644
index 639656c7e..000000000
--- a/packages/react-shared/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
diff --git a/packages/react-shared/src/components/anchor_title.tsx b/packages/react-shared/src/components/anchor_title.tsx
new file mode 100644
index 000000000..f44354097
--- /dev/null
+++ b/packages/react-shared/src/components/anchor_title.tsx
@@ -0,0 +1,87 @@
+import * as React from 'react';
+import { Link as ScrollLink } from 'react-scroll';
+
+import { HeaderSizes, Styles } from '../types';
+import { constants } from '../utils/constants';
+import { utils } from '../utils/utils';
+
+const headerSizeToScrollOffset: { [headerSize: string]: number } = {
+    h2: -20,
+    h3: 0,
+};
+
+export interface AnchorTitleProps {
+    title: string | React.ReactNode;
+    id: string;
+    headerSize: HeaderSizes;
+    shouldShowAnchor: boolean;
+}
+
+export interface AnchorTitleState {
+    isHovering: boolean;
+}
+
+const styles: Styles = {
+    anchor: {
+        fontSize: 20,
+        transform: 'rotate(45deg)',
+        cursor: 'pointer',
+    },
+    headers: {
+        WebkitMarginStart: 0,
+        WebkitMarginEnd: 0,
+        fontWeight: 'bold',
+        display: 'block',
+    },
+    h1: {
+        fontSize: '1.8em',
+    },
+    h2: {
+        fontSize: '1.5em',
+        fontWeight: 400,
+    },
+    h3: {
+        fontSize: '1.17em',
+    },
+};
+
+export class AnchorTitle extends React.Component<AnchorTitleProps, AnchorTitleState> {
+    constructor(props: AnchorTitleProps) {
+        super(props);
+        this.state = {
+            isHovering: false,
+        };
+    }
+    public render() {
+        let opacity = 0;
+        if (this.props.shouldShowAnchor) {
+            opacity = this.state.isHovering ? 0.6 : 1;
+        }
+        return (
+            <div className="relative flex" style={{ ...styles[this.props.headerSize], ...styles.headers }}>
+                <div className="inline-block" style={{ paddingRight: 4 }}>
+                    {this.props.title}
+                </div>
+                <ScrollLink
+                    to={this.props.id}
+                    offset={headerSizeToScrollOffset[this.props.headerSize]}
+                    duration={constants.DOCS_SCROLL_DURATION_MS}
+                    containerId={constants.DOCS_CONTAINER_ID}
+                >
+                    <i
+                        className="zmdi zmdi-link"
+                        onClick={utils.setUrlHash.bind(utils, this.props.id)}
+                        style={{ ...styles.anchor, opacity }}
+                        onMouseOver={this._setHoverState.bind(this, true)}
+                        onMouseOut={this._setHoverState.bind(this, false)}
+                    />
+                </ScrollLink>
+            </div>
+        );
+    }
+    private _setHoverState(isHovering: boolean) {
+        this.setState({
+            isHovering,
+        });
+    }
+}
diff --git a/packages/react-shared/src/components/markdown_code_block.tsx b/packages/react-shared/src/components/markdown_code_block.tsx
new file mode 100644
index 000000000..2070bb8e1
--- /dev/null
+++ b/packages/react-shared/src/components/markdown_code_block.tsx
@@ -0,0 +1,25 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+import * as HighLight from 'react-highlight';
+
+export interface MarkdownCodeBlockProps {
+    value: string;
+    language: string;
+}
+
+export interface MarkdownCodeBlockState {}
+
+export class MarkdownCodeBlock extends React.Component<MarkdownCodeBlockProps, MarkdownCodeBlockState> {
+    // Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying
+    // to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed.
+    public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) {
+        return nextProps.value !== this.props.value || nextProps.language !== this.props.language;
+    }
+    public render() {
+        return (
+            <span style={{ fontSize: 14 }}>
+                <HighLight className={this.props.language || 'javascript'}>{this.props.value}</HighLight>
+            </span>
+        );
+    }
+}
diff --git a/packages/react-shared/src/components/markdown_link_block.tsx b/packages/react-shared/src/components/markdown_link_block.tsx
new file mode 100644
index 000000000..8f5862249
--- /dev/null
+++ b/packages/react-shared/src/components/markdown_link_block.tsx
@@ -0,0 +1,47 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { constants } from '../utils/constants';
+import { utils } from '../utils/utils';
+
+export interface MarkdownLinkBlockProps {
+    href: string;
+}
+
+export interface MarkdownLinkBlockState {}
+
+export class MarkdownLinkBlock extends React.Component<MarkdownLinkBlockProps, MarkdownLinkBlockState> {
+    // Re-rendering a linkBlock causes it to remain unclickable.
+    // We therefore noop re-renders on this component if it's props haven't changed.
+    public shouldComponentUpdate(nextProps: MarkdownLinkBlockProps, nextState: MarkdownLinkBlockState) {
+        return nextProps.href !== this.props.href;
+    }
+    public render() {
+        const href = this.props.href;
+        const isLinkToSection = _.startsWith(href, '#');
+        // If protocol is http or https, we can open in a new tab, otherwise don't for security reasons
+        if (_.startsWith(href, 'http') || _.startsWith(href, 'https')) {
+            return (
+                <a href={href} target="_blank" rel="nofollow noreferrer noopener">
+                    {this.props.children}
+                </a>
+            );
+        } else if (isLinkToSection) {
+            return (
+                <a
+                    style={{ cursor: 'pointer', textDecoration: 'underline' }}
+                    onClick={this._onHashUrlClick.bind(this, href)}
+                >
+                    {this.props.children}
+                </a>
+            );
+        } else {
+            return <a href={href}>{this.props.children}</a>;
+        }
+    }
+    private _onHashUrlClick(href: string) {
+        const hash = href.split('#')[1];
+        utils.scrollToHash(hash, constants.SCROLL_CONTAINER_ID);
+        utils.setUrlHash(hash);
+    }
+}
diff --git a/packages/react-shared/src/components/markdown_section.tsx b/packages/react-shared/src/components/markdown_section.tsx
new file mode 100644
index 000000000..d24a43dcb
--- /dev/null
+++ b/packages/react-shared/src/components/markdown_section.tsx
@@ -0,0 +1,94 @@
+import * as _ from 'lodash';
+import RaisedButton from 'material-ui/RaisedButton';
+import * as React from 'react';
+import * as ReactMarkdown from 'react-markdown';
+import { Element as ScrollElement } from 'react-scroll';
+
+import { HeaderSizes } from '../types';
+import { colors } from '../utils/colors';
+import { utils } from '../utils/utils';
+
+import { AnchorTitle } from './anchor_title';
+import { MarkdownCodeBlock } from './markdown_code_block';
+import { MarkdownLinkBlock } from './markdown_link_block';
+
+export interface MarkdownSectionProps {
+    sectionName: string;
+    markdownContent: string;
+    headerSize?: HeaderSizes;
+    githubLink?: string;
+}
+
+interface DefaultMarkdownSectionProps {
+    headerSize: HeaderSizes;
+}
+
+type PropsWithDefaults = MarkdownSectionProps & DefaultMarkdownSectionProps;
+
+export interface MarkdownSectionState {
+    shouldShowAnchor: boolean;
+}
+
+export class MarkdownSection extends React.Component<MarkdownSectionProps, MarkdownSectionState> {
+    public static defaultProps: Partial<MarkdownSectionProps> = {
+        headerSize: HeaderSizes.H3,
+    };
+    constructor(props: MarkdownSectionProps) {
+        super(props);
+        this.state = {
+            shouldShowAnchor: false,
+        };
+    }
+    public render() {
+        const { sectionName, markdownContent, headerSize, githubLink } = this.props as PropsWithDefaults;
+
+        const id = utils.getIdFromName(sectionName);
+        return (
+            <div
+                className="md-px1 sm-px2 overflow-hidden"
+                onMouseOver={this._setAnchorVisibility.bind(this, true)}
+                onMouseOut={this._setAnchorVisibility.bind(this, false)}
+            >
+                <ScrollElement name={id}>
+                    <div className="clearfix pt3">
+                        <div className="col lg-col-8 md-col-8 sm-col-12">
+                            <span style={{ textTransform: 'capitalize', color: colors.grey700 }}>
+                                <AnchorTitle
+                                    headerSize={headerSize}
+                                    title={sectionName}
+                                    id={id}
+                                    shouldShowAnchor={this.state.shouldShowAnchor}
+                                />
+                            </span>
+                        </div>
+                        <div className="col col-4 sm-hide xs-hide right-align pr3" style={{ height: 28 }}>
+                            {!_.isUndefined(githubLink) && (
+                                <a
+                                    href={githubLink}
+                                    target="_blank"
+                                    style={{ color: colors.linkBlue, textDecoration: 'none', lineHeight: 2.1 }}
+                                >
+                                    Edit on Github
+                                </a>
+                            )}
+                        </div>
+                    </div>
+                    <hr style={{ border: `1px solid ${colors.lightestGrey}` }} />
+                    <ReactMarkdown
+                        source={markdownContent}
+                        escapeHtml={false}
+                        renderers={{
+                            code: MarkdownCodeBlock,
+                            link: MarkdownLinkBlock,
+                        }}
+                    />
+                </ScrollElement>
+            </div>
+        );
+    }
+    private _setAnchorVisibility(shouldShowAnchor: boolean) {
+        this.setState({
+            shouldShowAnchor,
+        });
+    }
+}
diff --git a/packages/react-shared/src/components/nested_sidebar_menu.tsx b/packages/react-shared/src/components/nested_sidebar_menu.tsx
new file mode 100644
index 000000000..2225bd197
--- /dev/null
+++ b/packages/react-shared/src/components/nested_sidebar_menu.tsx
@@ -0,0 +1,158 @@
+import * as _ from 'lodash';
+import MenuItem from 'material-ui/MenuItem';
+import * as React from 'react';
+import { Link as ScrollLink } from 'react-scroll';
+
+import { MenuSubsectionsBySection, Styles } from '../types';
+import { colors } from '../utils/colors';
+import { constants } from '../utils/constants';
+import { utils } from '../utils/utils';
+
+import { VersionDropDown } from './version_drop_down';
+
+export interface NestedSidebarMenuProps {
+    topLevelMenu: { [topLevel: string]: string[] };
+    menuSubsectionsBySection: MenuSubsectionsBySection;
+    sidebarHeader?: React.ReactNode;
+    shouldDisplaySectionHeaders?: boolean;
+    onMenuItemClick?: () => void;
+    selectedVersion?: string;
+    versions?: string[];
+    onVersionSelected?: (semver: string) => void;
+}
+
+export interface NestedSidebarMenuState {}
+
+const styles: Styles = {
+    menuItemWithHeaders: {
+        minHeight: 0,
+    },
+    menuItemWithoutHeaders: {
+        minHeight: 48,
+    },
+    menuItemInnerDivWithHeaders: {
+        color: colors.grey800,
+        fontSize: 14,
+        lineHeight: 2,
+        padding: 0,
+    },
+};
+
+export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, NestedSidebarMenuState> {
+    public static defaultProps: Partial<NestedSidebarMenuProps> = {
+        shouldDisplaySectionHeaders: true,
+        onMenuItemClick: _.noop,
+    };
+    public render() {
+        const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => {
+            const finalSectionName = sectionName.replace(/-/g, ' ');
+            if (this.props.shouldDisplaySectionHeaders) {
+                const id = utils.getIdFromName(sectionName);
+                return (
+                    <div key={`section-${sectionName}`} className="py1" style={{ color: colors.grey800 }}>
+                        <div style={{ fontWeight: 'bold', fontSize: 15 }} className="py1">
+                            {finalSectionName.toUpperCase()}
+                        </div>
+                        {this._renderMenuItems(menuItems)}
+                    </div>
+                );
+            } else {
+                return <div key={`section-${sectionName}`}>{this._renderMenuItems(menuItems)}</div>;
+            }
+        });
+        const maxWidthWithScrollbar = 307;
+        return (
+            <div>
+                {this.props.sidebarHeader}
+                {!_.isUndefined(this.props.versions) &&
+                    !_.isUndefined(this.props.selectedVersion) &&
+                    !_.isUndefined(this.props.onVersionSelected) && (
+                        <div style={{ maxWidth: maxWidthWithScrollbar }}>
+                            <VersionDropDown
+                                selectedVersion={this.props.selectedVersion}
+                                versions={this.props.versions}
+                                onVersionSelected={this.props.onVersionSelected}
+                            />
+                        </div>
+                    )}
+                <div className="pl1">{navigation}</div>
+            </div>
+        );
+    }
+    private _renderMenuItems(menuItemNames: string[]): React.ReactNode[] {
+        const menuItemStyles = this.props.shouldDisplaySectionHeaders
+            ? styles.menuItemWithHeaders
+            : styles.menuItemWithoutHeaders;
+        const menuItemInnerDivStyles = this.props.shouldDisplaySectionHeaders ? styles.menuItemInnerDivWithHeaders : {};
+        const menuItems = _.map(menuItemNames, menuItemName => {
+            const id = utils.getIdFromName(menuItemName);
+            return (
+                <div key={menuItemName}>
+                    <ScrollLink
+                        key={`menuItem-${menuItemName}`}
+                        to={id}
+                        offset={-10}
+                        duration={constants.DOCS_SCROLL_DURATION_MS}
+                        containerId={constants.DOCS_CONTAINER_ID}
+                    >
+                        <MenuItem
+                            onTouchTap={this._onMenuItemClick.bind(this, menuItemName)}
+                            style={menuItemStyles}
+                            innerDivStyle={menuItemInnerDivStyles}
+                        >
+                            <span style={{ textTransform: 'capitalize' }}>{menuItemName}</span>
+                        </MenuItem>
+                    </ScrollLink>
+                    {this._renderMenuItemSubsections(menuItemName)}
+                </div>
+            );
+        });
+        return menuItems;
+    }
+    private _renderMenuItemSubsections(menuItemName: string): React.ReactNode {
+        if (_.isUndefined(this.props.menuSubsectionsBySection[menuItemName])) {
+            return null;
+        }
+        return this._renderMenuSubsectionsBySection(menuItemName, this.props.menuSubsectionsBySection[menuItemName]);
+    }
+    private _renderMenuSubsectionsBySection(menuItemName: string, entityNames: string[]): React.ReactNode {
+        return (
+            <ul style={{ margin: 0, listStyleType: 'none', paddingLeft: 0 }} key={menuItemName}>
+                {_.map(entityNames, entityName => {
+                    const name = `${menuItemName}-${entityName}`;
+                    const id = utils.getIdFromName(name);
+                    return (
+                        <li key={`menuItem-${entityName}`}>
+                            <ScrollLink
+                                to={id}
+                                offset={0}
+                                duration={constants.DOCS_SCROLL_DURATION_MS}
+                                containerId={constants.DOCS_CONTAINER_ID}
+                                onTouchTap={this._onMenuItemClick.bind(this, name)}
+                            >
+                                <MenuItem
+                                    onTouchTap={this._onMenuItemClick.bind(this, name)}
+                                    style={{ minHeight: 35 }}
+                                    innerDivStyle={{
+                                        paddingLeft: 16,
+                                        fontSize: 14,
+                                        lineHeight: '35px',
+                                    }}
+                                >
+                                    {entityName}
+                                </MenuItem>
+                            </ScrollLink>
+                        </li>
+                    );
+                })}
+            </ul>
+        );
+    }
+    private _onMenuItemClick(name: string): void {
+        const id = utils.getIdFromName(name);
+        utils.setUrlHash(id);
+        if (!_.isUndefined(this.props.onMenuItemClick)) {
+            this.props.onMenuItemClick();
+        }
+    }
+}
diff --git a/packages/react-shared/src/components/section_header.tsx b/packages/react-shared/src/components/section_header.tsx
new file mode 100644
index 000000000..ee34a6c09
--- /dev/null
+++ b/packages/react-shared/src/components/section_header.tsx
@@ -0,0 +1,73 @@
+import * as React from 'react';
+import { Element as ScrollElement } from 'react-scroll';
+
+import { HeaderSizes } from '../types';
+import { colors } from '../utils/colors';
+import { utils } from '../utils/utils';
+
+import { AnchorTitle } from './anchor_title';
+
+export interface SectionHeaderProps {
+    sectionName: string;
+    headerSize?: HeaderSizes;
+}
+
+interface DefaultSectionHeaderProps {
+    headerSize: HeaderSizes;
+}
+
+type PropsWithDefaults = SectionHeaderProps & DefaultSectionHeaderProps;
+
+export interface SectionHeaderState {
+    shouldShowAnchor: boolean;
+}
+
+export class SectionHeader extends React.Component<SectionHeaderProps, SectionHeaderState> {
+    public static defaultProps: Partial<SectionHeaderProps> = {
+        headerSize: HeaderSizes.H2,
+    };
+    constructor(props: SectionHeaderProps) {
+        super(props);
+        this.state = {
+            shouldShowAnchor: false,
+        };
+    }
+    public render() {
+        const { sectionName, headerSize } = this.props as PropsWithDefaults;
+
+        const finalSectionName = this.props.sectionName.replace(/-/g, ' ');
+        const id = utils.getIdFromName(finalSectionName);
+        return (
+            <div
+                onMouseOver={this._setAnchorVisibility.bind(this, true)}
+                onMouseOut={this._setAnchorVisibility.bind(this, false)}
+            >
+                <ScrollElement name={id}>
+                    <AnchorTitle
+                        headerSize={headerSize}
+                        title={
+                            <span
+                                style={{
+                                    textTransform: 'uppercase',
+                                    color: colors.grey,
+                                    fontFamily: 'Roboto Mono',
+                                    fontWeight: 300,
+                                    fontSize: 27,
+                                }}
+                            >
+                                {finalSectionName}
+                            </span>
+                        }
+                        id={id}
+                        shouldShowAnchor={this.state.shouldShowAnchor}
+                    />
+                </ScrollElement>
+            </div>
+        );
+    }
+    private _setAnchorVisibility(shouldShowAnchor: boolean) {
+        this.setState({
+            shouldShowAnchor,
+        });
+    }
+}
diff --git a/packages/react-shared/src/components/version_drop_down.tsx b/packages/react-shared/src/components/version_drop_down.tsx
new file mode 100644
index 000000000..d9e49b205
--- /dev/null
+++ b/packages/react-shared/src/components/version_drop_down.tsx
@@ -0,0 +1,39 @@
+import * as _ from 'lodash';
+import DropDownMenu from 'material-ui/DropDownMenu';
+import MenuItem from 'material-ui/MenuItem';
+import * as React from 'react';
+
+import { utils } from '../utils/utils';
+
+export interface VersionDropDownProps {
+    selectedVersion: string;
+    versions: string[];
+    onVersionSelected: (semver: string) => void;
+}
+
+export interface VersionDropDownState {}
+
+export class VersionDropDown extends React.Component<VersionDropDownProps, VersionDropDownState> {
+    public render() {
+        return (
+            <div className="mx-auto" style={{ width: 120 }}>
+                <DropDownMenu
+                    maxHeight={300}
+                    value={this.props.selectedVersion}
+                    onChange={this._updateSelectedVersion.bind(this)}
+                >
+                    {this._renderDropDownItems()}
+                </DropDownMenu>
+            </div>
+        );
+    }
+    private _renderDropDownItems() {
+        const items = _.map(this.props.versions, version => {
+            return <MenuItem key={version} value={version} primaryText={`v${version}`} />;
+        });
+        return items;
+    }
+    private _updateSelectedVersion(e: any, index: number, semver: string) {
+        this.props.onVersionSelected(semver);
+    }
+}
diff --git a/packages/react-shared/src/globals.d.ts b/packages/react-shared/src/globals.d.ts
new file mode 100644
index 000000000..525563e23
--- /dev/null
+++ b/packages/react-shared/src/globals.d.ts
@@ -0,0 +1,14 @@
+declare module 'react-highlight';
+
+// is-mobile declarations
+declare function isMobile(): boolean;
+declare module 'is-mobile' {
+    export = isMobile;
+}
+
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/react-shared/src/index.ts b/packages/react-shared/src/index.ts
new file mode 100644
index 000000000..3b50c0117
--- /dev/null
+++ b/packages/react-shared/src/index.ts
@@ -0,0 +1,12 @@
+export { AnchorTitle } from './components/anchor_title';
+export { MarkdownLinkBlock } from './components/markdown_link_block';
+export { MarkdownCodeBlock } from './components/markdown_code_block';
+export { MarkdownSection } from './components/markdown_section';
+export { NestedSidebarMenu } from './components/nested_sidebar_menu';
+export { SectionHeader } from './components/section_header';
+
+export { HeaderSizes, Styles, MenuSubsectionsBySection, EtherscanLinkSuffixes, Networks } from './types';
+
+export { utils } from './utils/utils';
+export { constants } from './utils/constants';
+export { colors } from './utils/colors';
diff --git a/packages/react-shared/src/monorepo_scripts/postpublish.ts b/packages/react-shared/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/react-shared/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/react-shared/src/ts/components/anchor_title.tsx b/packages/react-shared/src/ts/components/anchor_title.tsx
deleted file mode 100644
index f44354097..000000000
--- a/packages/react-shared/src/ts/components/anchor_title.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-import * as React from 'react';
-import { Link as ScrollLink } from 'react-scroll';
-
-import { HeaderSizes, Styles } from '../types';
-import { constants } from '../utils/constants';
-import { utils } from '../utils/utils';
-
-const headerSizeToScrollOffset: { [headerSize: string]: number } = {
-    h2: -20,
-    h3: 0,
-};
-
-export interface AnchorTitleProps {
-    title: string | React.ReactNode;
-    id: string;
-    headerSize: HeaderSizes;
-    shouldShowAnchor: boolean;
-}
-
-export interface AnchorTitleState {
-    isHovering: boolean;
-}
-
-const styles: Styles = {
-    anchor: {
-        fontSize: 20,
-        transform: 'rotate(45deg)',
-        cursor: 'pointer',
-    },
-    headers: {
-        WebkitMarginStart: 0,
-        WebkitMarginEnd: 0,
-        fontWeight: 'bold',
-        display: 'block',
-    },
-    h1: {
-        fontSize: '1.8em',
-    },
-    h2: {
-        fontSize: '1.5em',
-        fontWeight: 400,
-    },
-    h3: {
-        fontSize: '1.17em',
-    },
-};
-
-export class AnchorTitle extends React.Component<AnchorTitleProps, AnchorTitleState> {
-    constructor(props: AnchorTitleProps) {
-        super(props);
-        this.state = {
-            isHovering: false,
-        };
-    }
-    public render() {
-        let opacity = 0;
-        if (this.props.shouldShowAnchor) {
-            opacity = this.state.isHovering ? 0.6 : 1;
-        }
-        return (
-            <div className="relative flex" style={{ ...styles[this.props.headerSize], ...styles.headers }}>
-                <div className="inline-block" style={{ paddingRight: 4 }}>
-                    {this.props.title}
-                </div>
-                <ScrollLink
-                    to={this.props.id}
-                    offset={headerSizeToScrollOffset[this.props.headerSize]}
-                    duration={constants.DOCS_SCROLL_DURATION_MS}
-                    containerId={constants.DOCS_CONTAINER_ID}
-                >
-                    <i
-                        className="zmdi zmdi-link"
-                        onClick={utils.setUrlHash.bind(utils, this.props.id)}
-                        style={{ ...styles.anchor, opacity }}
-                        onMouseOver={this._setHoverState.bind(this, true)}
-                        onMouseOut={this._setHoverState.bind(this, false)}
-                    />
-                </ScrollLink>
-            </div>
-        );
-    }
-    private _setHoverState(isHovering: boolean) {
-        this.setState({
-            isHovering,
-        });
-    }
-}
diff --git a/packages/react-shared/src/ts/components/markdown_code_block.tsx b/packages/react-shared/src/ts/components/markdown_code_block.tsx
deleted file mode 100644
index 2070bb8e1..000000000
--- a/packages/react-shared/src/ts/components/markdown_code_block.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-import * as HighLight from 'react-highlight';
-
-export interface MarkdownCodeBlockProps {
-    value: string;
-    language: string;
-}
-
-export interface MarkdownCodeBlockState {}
-
-export class MarkdownCodeBlock extends React.Component<MarkdownCodeBlockProps, MarkdownCodeBlockState> {
-    // Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying
-    // to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed.
-    public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) {
-        return nextProps.value !== this.props.value || nextProps.language !== this.props.language;
-    }
-    public render() {
-        return (
-            <span style={{ fontSize: 14 }}>
-                <HighLight className={this.props.language || 'javascript'}>{this.props.value}</HighLight>
-            </span>
-        );
-    }
-}
diff --git a/packages/react-shared/src/ts/components/markdown_link_block.tsx b/packages/react-shared/src/ts/components/markdown_link_block.tsx
deleted file mode 100644
index 8f5862249..000000000
--- a/packages/react-shared/src/ts/components/markdown_link_block.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { constants } from '../utils/constants';
-import { utils } from '../utils/utils';
-
-export interface MarkdownLinkBlockProps {
-    href: string;
-}
-
-export interface MarkdownLinkBlockState {}
-
-export class MarkdownLinkBlock extends React.Component<MarkdownLinkBlockProps, MarkdownLinkBlockState> {
-    // Re-rendering a linkBlock causes it to remain unclickable.
-    // We therefore noop re-renders on this component if it's props haven't changed.
-    public shouldComponentUpdate(nextProps: MarkdownLinkBlockProps, nextState: MarkdownLinkBlockState) {
-        return nextProps.href !== this.props.href;
-    }
-    public render() {
-        const href = this.props.href;
-        const isLinkToSection = _.startsWith(href, '#');
-        // If protocol is http or https, we can open in a new tab, otherwise don't for security reasons
-        if (_.startsWith(href, 'http') || _.startsWith(href, 'https')) {
-            return (
-                <a href={href} target="_blank" rel="nofollow noreferrer noopener">
-                    {this.props.children}
-                </a>
-            );
-        } else if (isLinkToSection) {
-            return (
-                <a
-                    style={{ cursor: 'pointer', textDecoration: 'underline' }}
-                    onClick={this._onHashUrlClick.bind(this, href)}
-                >
-                    {this.props.children}
-                </a>
-            );
-        } else {
-            return <a href={href}>{this.props.children}</a>;
-        }
-    }
-    private _onHashUrlClick(href: string) {
-        const hash = href.split('#')[1];
-        utils.scrollToHash(hash, constants.SCROLL_CONTAINER_ID);
-        utils.setUrlHash(hash);
-    }
-}
diff --git a/packages/react-shared/src/ts/components/markdown_section.tsx b/packages/react-shared/src/ts/components/markdown_section.tsx
deleted file mode 100644
index d24a43dcb..000000000
--- a/packages/react-shared/src/ts/components/markdown_section.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-import * as _ from 'lodash';
-import RaisedButton from 'material-ui/RaisedButton';
-import * as React from 'react';
-import * as ReactMarkdown from 'react-markdown';
-import { Element as ScrollElement } from 'react-scroll';
-
-import { HeaderSizes } from '../types';
-import { colors } from '../utils/colors';
-import { utils } from '../utils/utils';
-
-import { AnchorTitle } from './anchor_title';
-import { MarkdownCodeBlock } from './markdown_code_block';
-import { MarkdownLinkBlock } from './markdown_link_block';
-
-export interface MarkdownSectionProps {
-    sectionName: string;
-    markdownContent: string;
-    headerSize?: HeaderSizes;
-    githubLink?: string;
-}
-
-interface DefaultMarkdownSectionProps {
-    headerSize: HeaderSizes;
-}
-
-type PropsWithDefaults = MarkdownSectionProps & DefaultMarkdownSectionProps;
-
-export interface MarkdownSectionState {
-    shouldShowAnchor: boolean;
-}
-
-export class MarkdownSection extends React.Component<MarkdownSectionProps, MarkdownSectionState> {
-    public static defaultProps: Partial<MarkdownSectionProps> = {
-        headerSize: HeaderSizes.H3,
-    };
-    constructor(props: MarkdownSectionProps) {
-        super(props);
-        this.state = {
-            shouldShowAnchor: false,
-        };
-    }
-    public render() {
-        const { sectionName, markdownContent, headerSize, githubLink } = this.props as PropsWithDefaults;
-
-        const id = utils.getIdFromName(sectionName);
-        return (
-            <div
-                className="md-px1 sm-px2 overflow-hidden"
-                onMouseOver={this._setAnchorVisibility.bind(this, true)}
-                onMouseOut={this._setAnchorVisibility.bind(this, false)}
-            >
-                <ScrollElement name={id}>
-                    <div className="clearfix pt3">
-                        <div className="col lg-col-8 md-col-8 sm-col-12">
-                            <span style={{ textTransform: 'capitalize', color: colors.grey700 }}>
-                                <AnchorTitle
-                                    headerSize={headerSize}
-                                    title={sectionName}
-                                    id={id}
-                                    shouldShowAnchor={this.state.shouldShowAnchor}
-                                />
-                            </span>
-                        </div>
-                        <div className="col col-4 sm-hide xs-hide right-align pr3" style={{ height: 28 }}>
-                            {!_.isUndefined(githubLink) && (
-                                <a
-                                    href={githubLink}
-                                    target="_blank"
-                                    style={{ color: colors.linkBlue, textDecoration: 'none', lineHeight: 2.1 }}
-                                >
-                                    Edit on Github
-                                </a>
-                            )}
-                        </div>
-                    </div>
-                    <hr style={{ border: `1px solid ${colors.lightestGrey}` }} />
-                    <ReactMarkdown
-                        source={markdownContent}
-                        escapeHtml={false}
-                        renderers={{
-                            code: MarkdownCodeBlock,
-                            link: MarkdownLinkBlock,
-                        }}
-                    />
-                </ScrollElement>
-            </div>
-        );
-    }
-    private _setAnchorVisibility(shouldShowAnchor: boolean) {
-        this.setState({
-            shouldShowAnchor,
-        });
-    }
-}
diff --git a/packages/react-shared/src/ts/components/nested_sidebar_menu.tsx b/packages/react-shared/src/ts/components/nested_sidebar_menu.tsx
deleted file mode 100644
index 2225bd197..000000000
--- a/packages/react-shared/src/ts/components/nested_sidebar_menu.tsx
+++ /dev/null
@@ -1,158 +0,0 @@
-import * as _ from 'lodash';
-import MenuItem from 'material-ui/MenuItem';
-import * as React from 'react';
-import { Link as ScrollLink } from 'react-scroll';
-
-import { MenuSubsectionsBySection, Styles } from '../types';
-import { colors } from '../utils/colors';
-import { constants } from '../utils/constants';
-import { utils } from '../utils/utils';
-
-import { VersionDropDown } from './version_drop_down';
-
-export interface NestedSidebarMenuProps {
-    topLevelMenu: { [topLevel: string]: string[] };
-    menuSubsectionsBySection: MenuSubsectionsBySection;
-    sidebarHeader?: React.ReactNode;
-    shouldDisplaySectionHeaders?: boolean;
-    onMenuItemClick?: () => void;
-    selectedVersion?: string;
-    versions?: string[];
-    onVersionSelected?: (semver: string) => void;
-}
-
-export interface NestedSidebarMenuState {}
-
-const styles: Styles = {
-    menuItemWithHeaders: {
-        minHeight: 0,
-    },
-    menuItemWithoutHeaders: {
-        minHeight: 48,
-    },
-    menuItemInnerDivWithHeaders: {
-        color: colors.grey800,
-        fontSize: 14,
-        lineHeight: 2,
-        padding: 0,
-    },
-};
-
-export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, NestedSidebarMenuState> {
-    public static defaultProps: Partial<NestedSidebarMenuProps> = {
-        shouldDisplaySectionHeaders: true,
-        onMenuItemClick: _.noop,
-    };
-    public render() {
-        const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => {
-            const finalSectionName = sectionName.replace(/-/g, ' ');
-            if (this.props.shouldDisplaySectionHeaders) {
-                const id = utils.getIdFromName(sectionName);
-                return (
-                    <div key={`section-${sectionName}`} className="py1" style={{ color: colors.grey800 }}>
-                        <div style={{ fontWeight: 'bold', fontSize: 15 }} className="py1">
-                            {finalSectionName.toUpperCase()}
-                        </div>
-                        {this._renderMenuItems(menuItems)}
-                    </div>
-                );
-            } else {
-                return <div key={`section-${sectionName}`}>{this._renderMenuItems(menuItems)}</div>;
-            }
-        });
-        const maxWidthWithScrollbar = 307;
-        return (
-            <div>
-                {this.props.sidebarHeader}
-                {!_.isUndefined(this.props.versions) &&
-                    !_.isUndefined(this.props.selectedVersion) &&
-                    !_.isUndefined(this.props.onVersionSelected) && (
-                        <div style={{ maxWidth: maxWidthWithScrollbar }}>
-                            <VersionDropDown
-                                selectedVersion={this.props.selectedVersion}
-                                versions={this.props.versions}
-                                onVersionSelected={this.props.onVersionSelected}
-                            />
-                        </div>
-                    )}
-                <div className="pl1">{navigation}</div>
-            </div>
-        );
-    }
-    private _renderMenuItems(menuItemNames: string[]): React.ReactNode[] {
-        const menuItemStyles = this.props.shouldDisplaySectionHeaders
-            ? styles.menuItemWithHeaders
-            : styles.menuItemWithoutHeaders;
-        const menuItemInnerDivStyles = this.props.shouldDisplaySectionHeaders ? styles.menuItemInnerDivWithHeaders : {};
-        const menuItems = _.map(menuItemNames, menuItemName => {
-            const id = utils.getIdFromName(menuItemName);
-            return (
-                <div key={menuItemName}>
-                    <ScrollLink
-                        key={`menuItem-${menuItemName}`}
-                        to={id}
-                        offset={-10}
-                        duration={constants.DOCS_SCROLL_DURATION_MS}
-                        containerId={constants.DOCS_CONTAINER_ID}
-                    >
-                        <MenuItem
-                            onTouchTap={this._onMenuItemClick.bind(this, menuItemName)}
-                            style={menuItemStyles}
-                            innerDivStyle={menuItemInnerDivStyles}
-                        >
-                            <span style={{ textTransform: 'capitalize' }}>{menuItemName}</span>
-                        </MenuItem>
-                    </ScrollLink>
-                    {this._renderMenuItemSubsections(menuItemName)}
-                </div>
-            );
-        });
-        return menuItems;
-    }
-    private _renderMenuItemSubsections(menuItemName: string): React.ReactNode {
-        if (_.isUndefined(this.props.menuSubsectionsBySection[menuItemName])) {
-            return null;
-        }
-        return this._renderMenuSubsectionsBySection(menuItemName, this.props.menuSubsectionsBySection[menuItemName]);
-    }
-    private _renderMenuSubsectionsBySection(menuItemName: string, entityNames: string[]): React.ReactNode {
-        return (
-            <ul style={{ margin: 0, listStyleType: 'none', paddingLeft: 0 }} key={menuItemName}>
-                {_.map(entityNames, entityName => {
-                    const name = `${menuItemName}-${entityName}`;
-                    const id = utils.getIdFromName(name);
-                    return (
-                        <li key={`menuItem-${entityName}`}>
-                            <ScrollLink
-                                to={id}
-                                offset={0}
-                                duration={constants.DOCS_SCROLL_DURATION_MS}
-                                containerId={constants.DOCS_CONTAINER_ID}
-                                onTouchTap={this._onMenuItemClick.bind(this, name)}
-                            >
-                                <MenuItem
-                                    onTouchTap={this._onMenuItemClick.bind(this, name)}
-                                    style={{ minHeight: 35 }}
-                                    innerDivStyle={{
-                                        paddingLeft: 16,
-                                        fontSize: 14,
-                                        lineHeight: '35px',
-                                    }}
-                                >
-                                    {entityName}
-                                </MenuItem>
-                            </ScrollLink>
-                        </li>
-                    );
-                })}
-            </ul>
-        );
-    }
-    private _onMenuItemClick(name: string): void {
-        const id = utils.getIdFromName(name);
-        utils.setUrlHash(id);
-        if (!_.isUndefined(this.props.onMenuItemClick)) {
-            this.props.onMenuItemClick();
-        }
-    }
-}
diff --git a/packages/react-shared/src/ts/components/section_header.tsx b/packages/react-shared/src/ts/components/section_header.tsx
deleted file mode 100644
index ee34a6c09..000000000
--- a/packages/react-shared/src/ts/components/section_header.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import * as React from 'react';
-import { Element as ScrollElement } from 'react-scroll';
-
-import { HeaderSizes } from '../types';
-import { colors } from '../utils/colors';
-import { utils } from '../utils/utils';
-
-import { AnchorTitle } from './anchor_title';
-
-export interface SectionHeaderProps {
-    sectionName: string;
-    headerSize?: HeaderSizes;
-}
-
-interface DefaultSectionHeaderProps {
-    headerSize: HeaderSizes;
-}
-
-type PropsWithDefaults = SectionHeaderProps & DefaultSectionHeaderProps;
-
-export interface SectionHeaderState {
-    shouldShowAnchor: boolean;
-}
-
-export class SectionHeader extends React.Component<SectionHeaderProps, SectionHeaderState> {
-    public static defaultProps: Partial<SectionHeaderProps> = {
-        headerSize: HeaderSizes.H2,
-    };
-    constructor(props: SectionHeaderProps) {
-        super(props);
-        this.state = {
-            shouldShowAnchor: false,
-        };
-    }
-    public render() {
-        const { sectionName, headerSize } = this.props as PropsWithDefaults;
-
-        const finalSectionName = this.props.sectionName.replace(/-/g, ' ');
-        const id = utils.getIdFromName(finalSectionName);
-        return (
-            <div
-                onMouseOver={this._setAnchorVisibility.bind(this, true)}
-                onMouseOut={this._setAnchorVisibility.bind(this, false)}
-            >
-                <ScrollElement name={id}>
-                    <AnchorTitle
-                        headerSize={headerSize}
-                        title={
-                            <span
-                                style={{
-                                    textTransform: 'uppercase',
-                                    color: colors.grey,
-                                    fontFamily: 'Roboto Mono',
-                                    fontWeight: 300,
-                                    fontSize: 27,
-                                }}
-                            >
-                                {finalSectionName}
-                            </span>
-                        }
-                        id={id}
-                        shouldShowAnchor={this.state.shouldShowAnchor}
-                    />
-                </ScrollElement>
-            </div>
-        );
-    }
-    private _setAnchorVisibility(shouldShowAnchor: boolean) {
-        this.setState({
-            shouldShowAnchor,
-        });
-    }
-}
diff --git a/packages/react-shared/src/ts/components/version_drop_down.tsx b/packages/react-shared/src/ts/components/version_drop_down.tsx
deleted file mode 100644
index d9e49b205..000000000
--- a/packages/react-shared/src/ts/components/version_drop_down.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import * as _ from 'lodash';
-import DropDownMenu from 'material-ui/DropDownMenu';
-import MenuItem from 'material-ui/MenuItem';
-import * as React from 'react';
-
-import { utils } from '../utils/utils';
-
-export interface VersionDropDownProps {
-    selectedVersion: string;
-    versions: string[];
-    onVersionSelected: (semver: string) => void;
-}
-
-export interface VersionDropDownState {}
-
-export class VersionDropDown extends React.Component<VersionDropDownProps, VersionDropDownState> {
-    public render() {
-        return (
-            <div className="mx-auto" style={{ width: 120 }}>
-                <DropDownMenu
-                    maxHeight={300}
-                    value={this.props.selectedVersion}
-                    onChange={this._updateSelectedVersion.bind(this)}
-                >
-                    {this._renderDropDownItems()}
-                </DropDownMenu>
-            </div>
-        );
-    }
-    private _renderDropDownItems() {
-        const items = _.map(this.props.versions, version => {
-            return <MenuItem key={version} value={version} primaryText={`v${version}`} />;
-        });
-        return items;
-    }
-    private _updateSelectedVersion(e: any, index: number, semver: string) {
-        this.props.onVersionSelected(semver);
-    }
-}
diff --git a/packages/react-shared/src/ts/globals.d.ts b/packages/react-shared/src/ts/globals.d.ts
deleted file mode 100644
index 9b0bcf845..000000000
--- a/packages/react-shared/src/ts/globals.d.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-declare module 'react-highlight';
-
-// is-mobile declarations
-declare function isMobile(): boolean;
-declare module 'is-mobile' {
-    export = isMobile;
-}
diff --git a/packages/react-shared/src/ts/index.ts b/packages/react-shared/src/ts/index.ts
deleted file mode 100644
index 3b50c0117..000000000
--- a/packages/react-shared/src/ts/index.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-export { AnchorTitle } from './components/anchor_title';
-export { MarkdownLinkBlock } from './components/markdown_link_block';
-export { MarkdownCodeBlock } from './components/markdown_code_block';
-export { MarkdownSection } from './components/markdown_section';
-export { NestedSidebarMenu } from './components/nested_sidebar_menu';
-export { SectionHeader } from './components/section_header';
-
-export { HeaderSizes, Styles, MenuSubsectionsBySection, EtherscanLinkSuffixes, Networks } from './types';
-
-export { utils } from './utils/utils';
-export { constants } from './utils/constants';
-export { colors } from './utils/colors';
diff --git a/packages/react-shared/src/ts/types.ts b/packages/react-shared/src/ts/types.ts
deleted file mode 100644
index 88fadcc09..000000000
--- a/packages/react-shared/src/ts/types.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-export interface Styles {
-    [name: string]: React.CSSProperties;
-}
-
-export enum HeaderSizes {
-    H1 = 'h1',
-    H2 = 'h2',
-    H3 = 'h3',
-}
-
-export interface MenuSubsectionsBySection {
-    [section: string]: string[];
-}
-
-export enum EtherscanLinkSuffixes {
-    Address = 'address',
-    Tx = 'tx',
-}
-
-export enum Networks {
-    Mainnet = 'Mainnet',
-    Kovan = 'Kovan',
-    Ropsten = 'Ropsten',
-    Rinkeby = 'Rinkeby',
-}
diff --git a/packages/react-shared/src/ts/utils/colors.ts b/packages/react-shared/src/ts/utils/colors.ts
deleted file mode 100644
index 2eead95c7..000000000
--- a/packages/react-shared/src/ts/utils/colors.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { colors as materialUiColors } from 'material-ui/styles';
-
-export const colors = {
-    ...materialUiColors,
-    gray40: '#F8F8F8',
-    grey50: '#FAFAFA',
-    grey100: '#F5F5F5',
-    lightestGrey: '#F0F0F0',
-    greyishPink: '#E6E5E5',
-    grey300: '#E0E0E0',
-    beigeWhite: '#E4E4E4',
-    grey350: '#cacaca',
-    grey400: '#BDBDBD',
-    lightGrey: '#BBBBBB',
-    grey500: '#9E9E9E',
-    grey: '#A5A5A5',
-    darkGrey: '#818181',
-    landingLinkGrey: '#919191',
-    grey700: '#616161',
-    grey750: '#515151',
-    grey800: '#424242',
-    darkerGrey: '#393939',
-    heroGrey: '#404040',
-    projectsGrey: '#343333',
-    darkestGrey: '#272727',
-    dharmaDarkGrey: '#252525',
-    lightBlue: '#60A4F4',
-    lightBlueA700: '#0091EA',
-    linkBlue: '#1D5CDE',
-    darkBlue: '#4D5481',
-    turquois: '#058789',
-    lightPurple: '#A81CA6',
-    purple: '#690596',
-    red200: '#EF9A9A',
-    red: '#E91751',
-    red500: '#F44336',
-    red600: '#E53935',
-    limeGreen: '#66DE75',
-    lightGreen: '#4DC55C',
-    lightestGreen: '#89C774',
-    brightGreen: '#00C33E',
-    green400: '#66BB6A',
-    green: '#4DA24B',
-    amber600: '#FFB300',
-    orange: '#E69D00',
-    amber800: '#FF8F00',
-    darkYellow: '#caca03',
-};
diff --git a/packages/react-shared/src/ts/utils/constants.ts b/packages/react-shared/src/ts/utils/constants.ts
deleted file mode 100644
index 562ab776b..000000000
--- a/packages/react-shared/src/ts/utils/constants.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Networks } from '../types';
-
-export const constants = {
-    DOCS_SCROLL_DURATION_MS: 0,
-    DOCS_CONTAINER_ID: 'documentation',
-    SCROLL_CONTAINER_ID: 'documentation',
-    SCROLL_TOP_ID: 'pageScrollTop',
-    NETWORK_NAME_BY_ID: {
-        1: Networks.Mainnet,
-        3: Networks.Ropsten,
-        4: Networks.Rinkeby,
-        42: Networks.Kovan,
-    } as { [symbol: number]: string },
-    NETWORK_ID_BY_NAME: {
-        [Networks.Mainnet]: 1,
-        [Networks.Ropsten]: 3,
-        [Networks.Rinkeby]: 4,
-        [Networks.Kovan]: 42,
-    } as { [networkName: string]: number },
-};
diff --git a/packages/react-shared/src/ts/utils/utils.ts b/packages/react-shared/src/ts/utils/utils.ts
deleted file mode 100644
index b3acb081e..000000000
--- a/packages/react-shared/src/ts/utils/utils.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import isMobile = require('is-mobile');
-import * as _ from 'lodash';
-import { scroller } from 'react-scroll';
-
-import { EtherscanLinkSuffixes, Networks } from '../types';
-
-import { constants } from './constants';
-
-export const utils = {
-    setUrlHash(anchorId: string) {
-        window.location.hash = anchorId;
-    },
-    scrollToHash(hash: string, containerId: string): void {
-        let finalHash = hash;
-        if (_.isEmpty(hash)) {
-            finalHash = constants.SCROLL_TOP_ID; // scroll to the top
-        }
-
-        scroller.scrollTo(finalHash, {
-            duration: 0,
-            offset: 0,
-            containerId,
-        });
-    },
-    isUserOnMobile(): boolean {
-        const isUserOnMobile = isMobile();
-        return isUserOnMobile;
-    },
-    getIdFromName(name: string) {
-        const id = name.replace(/ /g, '-');
-        return id;
-    },
-    getEtherScanLinkIfExists(
-        addressOrTxHash: string,
-        networkId: number,
-        suffix: EtherscanLinkSuffixes,
-    ): string | undefined {
-        const networkName = constants.NETWORK_NAME_BY_ID[networkId];
-        if (_.isUndefined(networkName)) {
-            return undefined;
-        }
-        const etherScanPrefix = networkName === Networks.Mainnet ? '' : `${networkName.toLowerCase()}.`;
-        return `https://${etherScanPrefix}etherscan.io/${suffix}/${addressOrTxHash}`;
-    },
-};
diff --git a/packages/react-shared/src/types.ts b/packages/react-shared/src/types.ts
new file mode 100644
index 000000000..88fadcc09
--- /dev/null
+++ b/packages/react-shared/src/types.ts
@@ -0,0 +1,25 @@
+export interface Styles {
+    [name: string]: React.CSSProperties;
+}
+
+export enum HeaderSizes {
+    H1 = 'h1',
+    H2 = 'h2',
+    H3 = 'h3',
+}
+
+export interface MenuSubsectionsBySection {
+    [section: string]: string[];
+}
+
+export enum EtherscanLinkSuffixes {
+    Address = 'address',
+    Tx = 'tx',
+}
+
+export enum Networks {
+    Mainnet = 'Mainnet',
+    Kovan = 'Kovan',
+    Ropsten = 'Ropsten',
+    Rinkeby = 'Rinkeby',
+}
diff --git a/packages/react-shared/src/utils/colors.ts b/packages/react-shared/src/utils/colors.ts
new file mode 100644
index 000000000..2eead95c7
--- /dev/null
+++ b/packages/react-shared/src/utils/colors.ts
@@ -0,0 +1,48 @@
+import { colors as materialUiColors } from 'material-ui/styles';
+
+export const colors = {
+    ...materialUiColors,
+    gray40: '#F8F8F8',
+    grey50: '#FAFAFA',
+    grey100: '#F5F5F5',
+    lightestGrey: '#F0F0F0',
+    greyishPink: '#E6E5E5',
+    grey300: '#E0E0E0',
+    beigeWhite: '#E4E4E4',
+    grey350: '#cacaca',
+    grey400: '#BDBDBD',
+    lightGrey: '#BBBBBB',
+    grey500: '#9E9E9E',
+    grey: '#A5A5A5',
+    darkGrey: '#818181',
+    landingLinkGrey: '#919191',
+    grey700: '#616161',
+    grey750: '#515151',
+    grey800: '#424242',
+    darkerGrey: '#393939',
+    heroGrey: '#404040',
+    projectsGrey: '#343333',
+    darkestGrey: '#272727',
+    dharmaDarkGrey: '#252525',
+    lightBlue: '#60A4F4',
+    lightBlueA700: '#0091EA',
+    linkBlue: '#1D5CDE',
+    darkBlue: '#4D5481',
+    turquois: '#058789',
+    lightPurple: '#A81CA6',
+    purple: '#690596',
+    red200: '#EF9A9A',
+    red: '#E91751',
+    red500: '#F44336',
+    red600: '#E53935',
+    limeGreen: '#66DE75',
+    lightGreen: '#4DC55C',
+    lightestGreen: '#89C774',
+    brightGreen: '#00C33E',
+    green400: '#66BB6A',
+    green: '#4DA24B',
+    amber600: '#FFB300',
+    orange: '#E69D00',
+    amber800: '#FF8F00',
+    darkYellow: '#caca03',
+};
diff --git a/packages/react-shared/src/utils/constants.ts b/packages/react-shared/src/utils/constants.ts
new file mode 100644
index 000000000..562ab776b
--- /dev/null
+++ b/packages/react-shared/src/utils/constants.ts
@@ -0,0 +1,20 @@
+import { Networks } from '../types';
+
+export const constants = {
+    DOCS_SCROLL_DURATION_MS: 0,
+    DOCS_CONTAINER_ID: 'documentation',
+    SCROLL_CONTAINER_ID: 'documentation',
+    SCROLL_TOP_ID: 'pageScrollTop',
+    NETWORK_NAME_BY_ID: {
+        1: Networks.Mainnet,
+        3: Networks.Ropsten,
+        4: Networks.Rinkeby,
+        42: Networks.Kovan,
+    } as { [symbol: number]: string },
+    NETWORK_ID_BY_NAME: {
+        [Networks.Mainnet]: 1,
+        [Networks.Ropsten]: 3,
+        [Networks.Rinkeby]: 4,
+        [Networks.Kovan]: 42,
+    } as { [networkName: string]: number },
+};
diff --git a/packages/react-shared/src/utils/utils.ts b/packages/react-shared/src/utils/utils.ts
new file mode 100644
index 000000000..b3acb081e
--- /dev/null
+++ b/packages/react-shared/src/utils/utils.ts
@@ -0,0 +1,45 @@
+import isMobile = require('is-mobile');
+import * as _ from 'lodash';
+import { scroller } from 'react-scroll';
+
+import { EtherscanLinkSuffixes, Networks } from '../types';
+
+import { constants } from './constants';
+
+export const utils = {
+    setUrlHash(anchorId: string) {
+        window.location.hash = anchorId;
+    },
+    scrollToHash(hash: string, containerId: string): void {
+        let finalHash = hash;
+        if (_.isEmpty(hash)) {
+            finalHash = constants.SCROLL_TOP_ID; // scroll to the top
+        }
+
+        scroller.scrollTo(finalHash, {
+            duration: 0,
+            offset: 0,
+            containerId,
+        });
+    },
+    isUserOnMobile(): boolean {
+        const isUserOnMobile = isMobile();
+        return isUserOnMobile;
+    },
+    getIdFromName(name: string) {
+        const id = name.replace(/ /g, '-');
+        return id;
+    },
+    getEtherScanLinkIfExists(
+        addressOrTxHash: string,
+        networkId: number,
+        suffix: EtherscanLinkSuffixes,
+    ): string | undefined {
+        const networkName = constants.NETWORK_NAME_BY_ID[networkId];
+        if (_.isUndefined(networkName)) {
+            return undefined;
+        }
+        const etherScanPrefix = networkName === Networks.Mainnet ? '' : `${networkName.toLowerCase()}.`;
+        return `https://${etherScanPrefix}etherscan.io/${suffix}/${addressOrTxHash}`;
+    },
+};
diff --git a/packages/sra-report/package.json b/packages/sra-report/package.json
index abe305f52..86083d000 100644
--- a/packages/sra-report/package.json
+++ b/packages/sra-report/package.json
@@ -7,8 +7,8 @@
     "scripts": {
         "build:watch": "tsc -w",
         "lint": "tslint --project . 'src/**/*.ts'",
-        "clean": "shx rm -rf lib",
-        "build": "tsc"
+        "clean": "shx rm -rf lib scripts",
+        "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts"
     },
     "bin": {
         "sra-report": "lib/index.js"
@@ -34,10 +34,12 @@
         "yargs": "^10.0.3"
     },
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "@types/lodash": "^4.14.86",
         "@types/node": "^8.0.53",
         "@types/yargs": "^10.0.0",
+        "copyfiles": "^1.2.0",
         "shx": "^0.2.2",
         "tslint": "5.8.0",
         "typescript": "2.7.1"
diff --git a/packages/sra-report/scripts/postpublish.js b/packages/sra-report/scripts/postpublish.js
deleted file mode 100644
index 639656c7e..000000000
--- a/packages/sra-report/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
diff --git a/packages/sra-report/src/monorepo_scripts/postpublish.ts b/packages/sra-report/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/sra-report/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json
index c52484f82..1b30e18c0 100644
--- a/packages/subproviders/package.json
+++ b/packages/subproviders/package.json
@@ -6,8 +6,8 @@
     "license": "Apache-2.0",
     "scripts": {
         "build:watch": "tsc -w",
-        "clean": "shx rm -rf lib",
-        "build": "tsc",
+        "clean": "shx rm -rf lib scripts",
+        "build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
         "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'",
         "run_mocha_unit": "mocha lib/test/unit/**/*_test.js --timeout 10000 --bail --exit",
         "run_mocha_integration": "mocha lib/test/integration/**/*_test.js --timeout 10000 --bail --exit",
@@ -35,6 +35,7 @@
         "web3-typescript-typings": "^0.10.0"
     },
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "@0xproject/utils": "^0.4.1",
         "@types/lodash": "^4.14.86",
@@ -44,6 +45,7 @@
         "chai-as-promised": "^7.1.0",
         "chai-as-promised-typescript-typings": "^0.0.10",
         "chai-typescript-typings": "^0.0.4",
+        "copyfiles": "^1.2.0",
         "dirty-chai": "^2.0.1",
         "mocha": "^4.0.1",
         "npm-run-all": "^4.1.2",
diff --git a/packages/subproviders/scripts/postpublish.js b/packages/subproviders/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/subproviders/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/subproviders/src/globals.d.ts b/packages/subproviders/src/globals.d.ts
index d59ee9e67..e51801b5c 100644
--- a/packages/subproviders/src/globals.d.ts
+++ b/packages/subproviders/src/globals.d.ts
@@ -134,3 +134,10 @@ declare module 'hdkey' {
     }
     export = HDNode;
 }
+
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/subproviders/src/monorepo_scripts/postpublish.ts b/packages/subproviders/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/subproviders/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/tslint-config/monorepo_scripts/globals.d.ts b/packages/tslint-config/monorepo_scripts/globals.d.ts
new file mode 100644
index 000000000..94e63a32d
--- /dev/null
+++ b/packages/tslint-config/monorepo_scripts/globals.d.ts
@@ -0,0 +1,6 @@
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/tslint-config/monorepo_scripts/postpublish.ts b/packages/tslint-config/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/tslint-config/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/tslint-config/package.json b/packages/tslint-config/package.json
index b8398445f..13dcce87e 100644
--- a/packages/tslint-config/package.json
+++ b/packages/tslint-config/package.json
@@ -5,8 +5,8 @@
     "main": "tslint.json",
     "scripts": {
         "build:watch": "tsc -w",
-        "build": "tsc",
-        "clean": "shx rm -rf lib",
+        "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
+        "clean": "shx rm -rf lib scripts",
         "lint": "tslint --project . 'rules/**/*.ts'"
     },
     "repository": {
@@ -30,7 +30,9 @@
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/tslint-config/README.md",
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@types/lodash": "^4.14.86",
+        "copyfiles": "^1.2.0",
         "shx": "^0.2.2",
         "typescript": "2.7.1"
     },
diff --git a/packages/tslint-config/scripts/postpublish.js b/packages/tslint-config/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/tslint-config/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/tslint-config/tsconfig.json b/packages/tslint-config/tsconfig.json
index 15da53092..6e5f060a4 100644
--- a/packages/tslint-config/tsconfig.json
+++ b/packages/tslint-config/tsconfig.json
@@ -3,5 +3,5 @@
     "compilerOptions": {
         "outDir": "lib"
     },
-    "include": ["./rules/**/*"]
+    "include": ["./rules/**/*", "./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
 }
diff --git a/packages/types/package.json b/packages/types/package.json
index f4a587fc6..8dc03892e 100644
--- a/packages/types/package.json
+++ b/packages/types/package.json
@@ -6,8 +6,8 @@
     "types": "lib/index.d.ts",
     "scripts": {
         "build:watch": "tsc -w",
-        "build": "tsc",
-        "clean": "shx rm -rf lib",
+        "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
+        "clean": "shx rm -rf lib scripts",
         "lint": "tslint --project . 'src/**/*.ts'"
     },
     "license": "Apache-2.0",
@@ -20,7 +20,9 @@
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/types/README.md",
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
+        "copyfiles": "^1.2.0",
         "shx": "^0.2.2",
         "tslint": "5.8.0",
         "typescript": "2.7.1"
diff --git a/packages/types/scripts/postpublish.js b/packages/types/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/types/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/types/src/globals.d.ts b/packages/types/src/globals.d.ts
new file mode 100644
index 000000000..94e63a32d
--- /dev/null
+++ b/packages/types/src/globals.d.ts
@@ -0,0 +1,6 @@
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/types/src/monorepo_scripts/postpublish.ts b/packages/types/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/types/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/utils/package.json b/packages/utils/package.json
index 0cfd50178..b7c98b78e 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -6,8 +6,8 @@
     "types": "lib/index.d.ts",
     "scripts": {
         "build:watch": "tsc -w",
-        "build": "tsc",
-        "clean": "shx rm -rf lib",
+        "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
+        "clean": "shx rm -rf lib scripts",
         "lint": "tslint --project . 'src/**/*.ts'"
     },
     "license": "Apache-2.0",
@@ -20,8 +20,10 @@
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/utils/README.md",
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "@types/lodash": "^4.14.86",
+        "copyfiles": "^1.2.0",
         "npm-run-all": "^4.1.2",
         "shx": "^0.2.2",
         "tslint": "5.8.0",
diff --git a/packages/utils/scripts/postpublish.js b/packages/utils/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/utils/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/utils/src/globals.d.ts b/packages/utils/src/globals.d.ts
new file mode 100644
index 000000000..94e63a32d
--- /dev/null
+++ b/packages/utils/src/globals.d.ts
@@ -0,0 +1,6 @@
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/utils/src/monorepo_scripts/postpublish.ts b/packages/utils/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/utils/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/web3-typescript-typings/monorepo_scripts/globals.d.ts b/packages/web3-typescript-typings/monorepo_scripts/globals.d.ts
new file mode 100644
index 000000000..94e63a32d
--- /dev/null
+++ b/packages/web3-typescript-typings/monorepo_scripts/globals.d.ts
@@ -0,0 +1,6 @@
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/web3-typescript-typings/monorepo_scripts/postpublish.ts b/packages/web3-typescript-typings/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/web3-typescript-typings/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/web3-typescript-typings/package.json b/packages/web3-typescript-typings/package.json
index 0b04fe050..0825f646d 100644
--- a/packages/web3-typescript-typings/package.json
+++ b/packages/web3-typescript-typings/package.json
@@ -5,7 +5,9 @@
     "main": "index.d.ts",
     "types": "index.d.ts",
     "scripts": {
-        "lint": "tslint index.d.ts"
+        "lint": "tslint index.d.ts",
+        "build": "tsc && copyfiles -u 1 './lib/**/*' ./scripts",
+        "clean": "shx rm -rf scripts"
     },
     "repository": {
         "type": "git",
@@ -21,7 +23,10 @@
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/web3-typescript-typings#readme",
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@types/bignumber.js": "^4.0.2",
+        "copyfiles": "^1.2.0",
+        "shx": "^0.2.2",
         "tslint": "5.8.0",
         "tslint-config-0xproject": "^0.0.2",
         "typescript": "2.7.1"
diff --git a/packages/web3-typescript-typings/scripts/postpublish.js b/packages/web3-typescript-typings/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/web3-typescript-typings/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/web3-typescript-typings/tsconfig.json b/packages/web3-typescript-typings/tsconfig.json
new file mode 100644
index 000000000..2599d1b7c
--- /dev/null
+++ b/packages/web3-typescript-typings/tsconfig.json
@@ -0,0 +1,7 @@
+{
+    "extends": "../../tsconfig",
+    "compilerOptions": {
+        "outDir": "lib"
+    },
+    "include": ["./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+}
diff --git a/packages/web3-wrapper/package.json b/packages/web3-wrapper/package.json
index 2b545732e..6e569b993 100644
--- a/packages/web3-wrapper/package.json
+++ b/packages/web3-wrapper/package.json
@@ -6,8 +6,8 @@
     "types": "lib/index.d.ts",
     "scripts": {
         "build:watch": "tsc -w",
-        "build": "tsc",
-        "clean": "shx rm -rf lib",
+        "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
+        "clean": "shx rm -rf lib scripts",
         "lint": "tslint --project . 'src/**/*.ts'"
     },
     "license": "Apache-2.0",
@@ -20,8 +20,10 @@
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/web3-wrapper/README.md",
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
         "@types/lodash": "^4.14.86",
+        "copyfiles": "^1.2.0",
         "npm-run-all": "^4.1.2",
         "shx": "^0.2.2",
         "tslint": "5.8.0",
diff --git a/packages/web3-wrapper/scripts/postpublish.js b/packages/web3-wrapper/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/web3-wrapper/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/web3-wrapper/src/globals.d.ts b/packages/web3-wrapper/src/globals.d.ts
new file mode 100644
index 000000000..94e63a32d
--- /dev/null
+++ b/packages/web3-wrapper/src/globals.d.ts
@@ -0,0 +1,6 @@
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/web3-wrapper/src/monorepo_scripts/postpublish.ts b/packages/web3-wrapper/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..d5fcff9d0
--- /dev/null
+++ b/packages/web3-wrapper/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,6 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+
+const subPackageName = (packageJSON as any).name;
+postpublishUtils.standardPostPublishAsync(subPackageName);
-- 
cgit v1.2.3


From c3b4359e8751a9c98a6081659a364fc29e69653d Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 16:36:05 +0100
Subject: small fixes

---
 packages/dev-utils/src/index.ts                        | 1 -
 packages/dev-utils/src/monorepo_scripts/postpublish.ts | 2 +-
 packages/monorepo-scripts/package.json                 | 3 ++-
 packages/monorepo-scripts/tslint.json                  | 3 ---
 packages/react-docs-example/ts/globals.d.ts            | 6 ++++++
 packages/react-shared/tsconfig.json                    | 2 +-
 6 files changed, 10 insertions(+), 7 deletions(-)
 delete mode 100644 packages/monorepo-scripts/tslint.json
 create mode 100644 packages/react-docs-example/ts/globals.d.ts

diff --git a/packages/dev-utils/src/index.ts b/packages/dev-utils/src/index.ts
index cc3e668a1..e899ac206 100644
--- a/packages/dev-utils/src/index.ts
+++ b/packages/dev-utils/src/index.ts
@@ -2,4 +2,3 @@ export { RPC } from './rpc';
 export { BlockchainLifecycle } from './blockchain_lifecycle';
 export { web3Factory } from './web3_factory';
 export { constants as devConstants } from './constants';
-export { postpublishUtils } from './postpublish_utils';
diff --git a/packages/dev-utils/src/monorepo_scripts/postpublish.ts b/packages/dev-utils/src/monorepo_scripts/postpublish.ts
index 6bd94e71d..d5fcff9d0 100644
--- a/packages/dev-utils/src/monorepo_scripts/postpublish.ts
+++ b/packages/dev-utils/src/monorepo_scripts/postpublish.ts
@@ -1,4 +1,4 @@
-import { postpublishUtils } from '../postpublish_utils';
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
 
diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json
index 09a632c07..42b9d6c55 100644
--- a/packages/monorepo-scripts/package.json
+++ b/packages/monorepo-scripts/package.json
@@ -2,6 +2,8 @@
     "name": "@0xproject/monorepo-scripts",
     "version": "0.1.12",
     "description": "Helper scripts for the monorepo",
+    "main": "lib/index.js",
+    "types": "lib/index.d.ts",
     "scripts": {
         "build:watch": "tsc -w",
         "deps_versions": "node ./lib/deps_versions.js",
@@ -19,7 +21,6 @@
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/monorepo-scripts/README.md",
     "devDependencies": {
-        "@0xproject/tslint-config": "^0.4.10",
         "@types/glob": "^5.0.33",
         "@types/node": "^8.0.53",
         "shx": "^0.2.2",
diff --git a/packages/monorepo-scripts/tslint.json b/packages/monorepo-scripts/tslint.json
deleted file mode 100644
index ffaefe83a..000000000
--- a/packages/monorepo-scripts/tslint.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-    "extends": ["@0xproject/tslint-config"]
-}
diff --git a/packages/react-docs-example/ts/globals.d.ts b/packages/react-docs-example/ts/globals.d.ts
new file mode 100644
index 000000000..94e63a32d
--- /dev/null
+++ b/packages/react-docs-example/ts/globals.d.ts
@@ -0,0 +1,6 @@
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
diff --git a/packages/react-shared/tsconfig.json b/packages/react-shared/tsconfig.json
index de87aa45b..687bd1f4e 100644
--- a/packages/react-shared/tsconfig.json
+++ b/packages/react-shared/tsconfig.json
@@ -8,5 +8,5 @@
             "*": ["node_modules/@types/*", "*"]
         }
     },
-    "include": ["./src/ts/**/*"]
+    "include": ["./src/**/*"]
 }
-- 
cgit v1.2.3


From 67fbffc964a12c56c06e3262c9afdb1d2d01559c Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 16:55:35 +0100
Subject: Re-add linter to monorepo-scripts but with tslint-config dep at
 earlier version to avoid cyclical dependency

---
 packages/monorepo-scripts/package.json | 2 ++
 packages/monorepo-scripts/tslint.json  | 3 +++
 yarn.lock                              | 7 +++++++
 3 files changed, 12 insertions(+)
 create mode 100644 packages/monorepo-scripts/tslint.json

diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json
index 42b9d6c55..e0ca3cd1f 100644
--- a/packages/monorepo-scripts/package.json
+++ b/packages/monorepo-scripts/package.json
@@ -20,7 +20,9 @@
         "url": "https://github.com/0xProject/0x-monorepo/issues"
     },
     "homepage": "https://github.com/0xProject/0x-monorepo/packages/monorepo-scripts/README.md",
+    "comment": "// We purposefully use an older version of tslint-config here to avoid creating an import cycle",
     "devDependencies": {
+        "@0xproject/tslint-config": "0.4.8",
         "@types/glob": "^5.0.33",
         "@types/node": "^8.0.53",
         "shx": "^0.2.2",
diff --git a/packages/monorepo-scripts/tslint.json b/packages/monorepo-scripts/tslint.json
new file mode 100644
index 000000000..ffaefe83a
--- /dev/null
+++ b/packages/monorepo-scripts/tslint.json
@@ -0,0 +1,3 @@
+{
+    "extends": ["@0xproject/tslint-config"]
+}
diff --git a/yarn.lock b/yarn.lock
index 88532729b..821a22f10 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6,6 +6,13 @@
   version "0.3.9"
   resolved "https://registry.yarnpkg.com/8fold-marked/-/8fold-marked-0.3.9.tgz#bb89c645612f8ccfaffac1ca6e3c11f168c9cf59"
 
+"@0xproject/tslint-config@0.4.8":
+  version "0.4.8"
+  resolved "https://registry.yarnpkg.com/@0xproject/tslint-config/-/tslint-config-0.4.8.tgz#5a3dfb1fc94e17752184137b452c5b0b3287d822"
+  dependencies:
+    lodash "^4.17.4"
+    tslint-react "^3.2.0"
+
 "@ledgerhq/hw-app-eth@^4.3.0":
   version "4.3.0"
   resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-4.3.0.tgz#5f365a3560cd78e8cd711737ec56249390cbf5e5"
-- 
cgit v1.2.3


From a2e848a7fafbae4df51de6f05fd53a6abf78a593 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 16:55:50 +0100
Subject: Fix lint issues

---
 packages/abi-gen/src/monorepo_scripts/postpublish.ts                | 1 +
 packages/assert/src/monorepo_scripts/postpublish.ts                 | 1 +
 packages/base-contract/src/monorepo_scripts/postpublish.ts          | 1 +
 .../monorepo_scripts/postpublish.ts                                 | 1 +
 packages/chai-typescript-typings/monorepo_scripts/postpublish.ts    | 1 +
 packages/deployer/src/monorepo_scripts/postpublish.ts               | 1 +
 packages/dev-utils/src/monorepo_scripts/postpublish.ts              | 1 +
 packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts  | 1 +
 packages/json-schemas/src/monorepo_scripts/postpublish.ts           | 1 +
 packages/monorepo-scripts/src/postpublish_utils.ts                  | 6 +++---
 packages/react-docs/src/monorepo_scripts/postpublish.ts             | 1 +
 packages/react-shared/src/monorepo_scripts/postpublish.ts           | 1 +
 packages/sra-report/src/monorepo_scripts/postpublish.ts             | 1 +
 packages/subproviders/src/monorepo_scripts/postpublish.ts           | 1 +
 packages/tslint-config/monorepo_scripts/postpublish.ts              | 1 +
 packages/types/src/monorepo_scripts/postpublish.ts                  | 1 +
 packages/utils/src/monorepo_scripts/postpublish.ts                  | 1 +
 packages/web3-typescript-typings/monorepo_scripts/postpublish.ts    | 1 +
 packages/web3-wrapper/src/monorepo_scripts/postpublish.ts           | 1 +
 19 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/packages/abi-gen/src/monorepo_scripts/postpublish.ts b/packages/abi-gen/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/abi-gen/src/monorepo_scripts/postpublish.ts
+++ b/packages/abi-gen/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/assert/src/monorepo_scripts/postpublish.ts b/packages/assert/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/assert/src/monorepo_scripts/postpublish.ts
+++ b/packages/assert/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/base-contract/src/monorepo_scripts/postpublish.ts b/packages/base-contract/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/base-contract/src/monorepo_scripts/postpublish.ts
+++ b/packages/base-contract/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts b/packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts
+++ b/packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/chai-typescript-typings/monorepo_scripts/postpublish.ts b/packages/chai-typescript-typings/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/chai-typescript-typings/monorepo_scripts/postpublish.ts
+++ b/packages/chai-typescript-typings/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/deployer/src/monorepo_scripts/postpublish.ts b/packages/deployer/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/deployer/src/monorepo_scripts/postpublish.ts
+++ b/packages/deployer/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/dev-utils/src/monorepo_scripts/postpublish.ts b/packages/dev-utils/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/dev-utils/src/monorepo_scripts/postpublish.ts
+++ b/packages/dev-utils/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts b/packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts
+++ b/packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/json-schemas/src/monorepo_scripts/postpublish.ts b/packages/json-schemas/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/json-schemas/src/monorepo_scripts/postpublish.ts
+++ b/packages/json-schemas/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts
index 2f27e15cb..e04c31649 100644
--- a/packages/monorepo-scripts/src/postpublish_utils.ts
+++ b/packages/monorepo-scripts/src/postpublish_utils.ts
@@ -1,5 +1,5 @@
-import * as promisify from 'es6-promisify';
 import { execAsync } from 'async-child-process';
+import * as promisify from 'es6-promisify';
 import * as _ from 'lodash';
 import * as publishRelease from 'publish-release';
 import semverSort = require('semver-sort');
@@ -16,7 +16,7 @@ export interface TagAndVersion {
 }
 
 export const postpublishUtils = {
-    getLatestTagAndVersionAsync(subPackageName: string): Promise<TagAndVersion> {
+    async getLatestTagAndVersionAsync(subPackageName: string): Promise<TagAndVersion> {
         const subPackagePrefix = `${subPackageName}@`;
         const gitTagsCommand = `git tag -l "${subPackagePrefix}*"`;
         return execAsync(gitTagsCommand).then((result: any) => {
@@ -36,7 +36,7 @@ export const postpublishUtils = {
             };
         });
     },
-    publishReleaseNotesAsync(tag: string, releaseName: string, assets: string[]) {
+    async publishReleaseNotesAsync(tag: string, releaseName: string, assets: string[]) {
         utils.log('POSTPUBLISH: Releasing ', releaseName, '...');
         return publishReleaseAsync({
             token: githubPersonalAccessToken,
diff --git a/packages/react-docs/src/monorepo_scripts/postpublish.ts b/packages/react-docs/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/react-docs/src/monorepo_scripts/postpublish.ts
+++ b/packages/react-docs/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/react-shared/src/monorepo_scripts/postpublish.ts b/packages/react-shared/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/react-shared/src/monorepo_scripts/postpublish.ts
+++ b/packages/react-shared/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/sra-report/src/monorepo_scripts/postpublish.ts b/packages/sra-report/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/sra-report/src/monorepo_scripts/postpublish.ts
+++ b/packages/sra-report/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/subproviders/src/monorepo_scripts/postpublish.ts b/packages/subproviders/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/subproviders/src/monorepo_scripts/postpublish.ts
+++ b/packages/subproviders/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/tslint-config/monorepo_scripts/postpublish.ts b/packages/tslint-config/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/tslint-config/monorepo_scripts/postpublish.ts
+++ b/packages/tslint-config/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/types/src/monorepo_scripts/postpublish.ts b/packages/types/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/types/src/monorepo_scripts/postpublish.ts
+++ b/packages/types/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/utils/src/monorepo_scripts/postpublish.ts b/packages/utils/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/utils/src/monorepo_scripts/postpublish.ts
+++ b/packages/utils/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/web3-typescript-typings/monorepo_scripts/postpublish.ts b/packages/web3-typescript-typings/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/web3-typescript-typings/monorepo_scripts/postpublish.ts
+++ b/packages/web3-typescript-typings/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
diff --git a/packages/web3-wrapper/src/monorepo_scripts/postpublish.ts b/packages/web3-wrapper/src/monorepo_scripts/postpublish.ts
index d5fcff9d0..6e5aa050a 100644
--- a/packages/web3-wrapper/src/monorepo_scripts/postpublish.ts
+++ b/packages/web3-wrapper/src/monorepo_scripts/postpublish.ts
@@ -3,4 +3,5 @@ import { postpublishUtils } from '@0xproject/monorepo-scripts';
 import * as packageJSON from '../package.json';
 
 const subPackageName = (packageJSON as any).name;
+// tslint:disable-next-line:no-floating-promises
 postpublishUtils.standardPostPublishAsync(subPackageName);
-- 
cgit v1.2.3


From e1fa65f5ef8f34482381911f51e7d713345005c7 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 17:04:14 +0100
Subject: remove unused dep

---
 packages/abi-gen/package.json | 1 -
 1 file changed, 1 deletion(-)

diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json
index ffae67e22..9e0e53630 100644
--- a/packages/abi-gen/package.json
+++ b/packages/abi-gen/package.json
@@ -36,7 +36,6 @@
     "devDependencies": {
         "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.10",
-        "@0xproject/dev-utils": "^0.2.1",
         "@types/glob": "^5.0.33",
         "@types/handlebars": "^4.0.36",
         "@types/mkdirp": "^0.5.1",
-- 
cgit v1.2.3


From b3c1c0ccadff32bbe962588733222fccc121d10e Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 17:04:31 +0100
Subject: remove unneeded include

---
 packages/chai-as-promised-typescript-typings/tsconfig.json | 2 +-
 packages/chai-typescript-typings/tsconfig.json             | 2 +-
 packages/ethers-typescript-typings/tsconfig.json           | 2 +-
 packages/web3-typescript-typings/tsconfig.json             | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/packages/chai-as-promised-typescript-typings/tsconfig.json b/packages/chai-as-promised-typescript-typings/tsconfig.json
index 2599d1b7c..bc453af4b 100644
--- a/packages/chai-as-promised-typescript-typings/tsconfig.json
+++ b/packages/chai-as-promised-typescript-typings/tsconfig.json
@@ -3,5 +3,5 @@
     "compilerOptions": {
         "outDir": "lib"
     },
-    "include": ["./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+    "include": ["./monorepo_scripts/**/*"]
 }
diff --git a/packages/chai-typescript-typings/tsconfig.json b/packages/chai-typescript-typings/tsconfig.json
index 2599d1b7c..bc453af4b 100644
--- a/packages/chai-typescript-typings/tsconfig.json
+++ b/packages/chai-typescript-typings/tsconfig.json
@@ -3,5 +3,5 @@
     "compilerOptions": {
         "outDir": "lib"
     },
-    "include": ["./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+    "include": ["./monorepo_scripts/**/*"]
 }
diff --git a/packages/ethers-typescript-typings/tsconfig.json b/packages/ethers-typescript-typings/tsconfig.json
index 2599d1b7c..bc453af4b 100644
--- a/packages/ethers-typescript-typings/tsconfig.json
+++ b/packages/ethers-typescript-typings/tsconfig.json
@@ -3,5 +3,5 @@
     "compilerOptions": {
         "outDir": "lib"
     },
-    "include": ["./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+    "include": ["./monorepo_scripts/**/*"]
 }
diff --git a/packages/web3-typescript-typings/tsconfig.json b/packages/web3-typescript-typings/tsconfig.json
index 2599d1b7c..bc453af4b 100644
--- a/packages/web3-typescript-typings/tsconfig.json
+++ b/packages/web3-typescript-typings/tsconfig.json
@@ -3,5 +3,5 @@
     "compilerOptions": {
         "outDir": "lib"
     },
-    "include": ["./monorepo_scripts/**/*", "../../node_modules/web3-typescript-typings/index.d.ts"]
+    "include": ["./monorepo_scripts/**/*"]
 }
-- 
cgit v1.2.3


From a08ae722c112e3bbd257bcf1606e3cf962266eae Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 17:04:38 +0100
Subject: Move changelog entry

---
 packages/dev-utils/CHANGELOG.md        | 4 ----
 packages/monorepo-scripts/CHANGELOG.md | 5 +++++
 2 files changed, 5 insertions(+), 4 deletions(-)
 create mode 100644 packages/monorepo-scripts/CHANGELOG.md

diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md
index 6840a6a69..ecc5546ae 100644
--- a/packages/dev-utils/CHANGELOG.md
+++ b/packages/dev-utils/CHANGELOG.md
@@ -1,9 +1,5 @@
 # CHANGELOG
 
-## v0.2.1 - _TBD_
-
-    * Add postpublish utils
-
 ## v0.2.0 - _February 16, 2018_
 
     * Remove subproviders (#392)
diff --git a/packages/monorepo-scripts/CHANGELOG.md b/packages/monorepo-scripts/CHANGELOG.md
new file mode 100644
index 000000000..bb685a436
--- /dev/null
+++ b/packages/monorepo-scripts/CHANGELOG.md
@@ -0,0 +1,5 @@
+CHANGELOG
+
+## v0.1.13 - _TBD_
+
+    * Add postpublish utils
-- 
cgit v1.2.3


From ee29ed26ff1d754fa13576840c08267b8b5707ba Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 17:36:12 +0100
Subject: Use async/await instead of promise syntax

---
 packages/monorepo-scripts/src/postpublish_utils.ts | 29 +++++++++++-----------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts
index e04c31649..6c8771c6f 100644
--- a/packages/monorepo-scripts/src/postpublish_utils.ts
+++ b/packages/monorepo-scripts/src/postpublish_utils.ts
@@ -19,22 +19,21 @@ export const postpublishUtils = {
     async getLatestTagAndVersionAsync(subPackageName: string): Promise<TagAndVersion> {
         const subPackagePrefix = `${subPackageName}@`;
         const gitTagsCommand = `git tag -l "${subPackagePrefix}*"`;
-        return execAsync(gitTagsCommand).then((result: any) => {
-            if (!_.isEmpty(result.stderr)) {
-                throw new Error(result.stderr);
-            }
-            const tags = result.stdout.trim().split('\n');
-            const versions = tags.map((tag: string) => {
-                return tag.slice(subPackagePrefix.length);
-            });
-            const sortedVersions = semverSort.desc(versions);
-            const latestVersion = sortedVersions[0];
-            const latestTag = subPackagePrefix + latestVersion;
-            return {
-                tag: latestTag,
-                version: latestVersion,
-            };
+        const result = await execAsync(gitTagsCommand);
+        if (!_.isEmpty(result.stderr)) {
+            throw new Error(result.stderr);
+        }
+        const tags = result.stdout.trim().split('\n');
+        const versions = tags.map((tag: string) => {
+            return tag.slice(subPackagePrefix.length);
         });
+        const sortedVersions = semverSort.desc(versions);
+        const latestVersion = sortedVersions[0];
+        const latestTag = subPackagePrefix + latestVersion;
+        return {
+            tag: latestTag,
+            version: latestVersion,
+        };
     },
     async publishReleaseNotesAsync(tag: string, releaseName: string, assets: string[]) {
         utils.log('POSTPUBLISH: Releasing ', releaseName, '...');
-- 
cgit v1.2.3


From dba1b8a7e92ebd18132e0e714d5109f87b9ab7a9 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Tue, 13 Mar 2018 17:55:16 +0100
Subject: Consolidate docs generation and uploading logic

---
 packages/0x.js/src/monorepo_scripts/postpublish.ts | 17 +-------------
 packages/0x.js/src/monorepo_scripts/stagedocs.ts   | 15 ++-----------
 .../connect/src/monorepo_scripts/postpublish.ts    | 17 +-------------
 packages/connect/src/monorepo_scripts/stagedocs.ts | 14 ++----------
 packages/monorepo-scripts/src/postpublish_utils.ts | 26 ++++++++++++++++++++++
 5 files changed, 32 insertions(+), 57 deletions(-)

diff --git a/packages/0x.js/src/monorepo_scripts/postpublish.ts b/packages/0x.js/src/monorepo_scripts/postpublish.ts
index 8e2692c93..88be6444f 100644
--- a/packages/0x.js/src/monorepo_scripts/postpublish.ts
+++ b/packages/0x.js/src/monorepo_scripts/postpublish.ts
@@ -12,7 +12,6 @@ const subPackageName = (packageJSON as any).name;
 // So far, we only have @0xproject/types as part of 0x.js's public interface.
 const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts'];
 const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
-const projectFiles = fileIncludesAdjusted.join(' ');
 const S3BucketPath = 's3://0xjs-docs-jsons/';
 
 (async () => {
@@ -26,19 +25,5 @@ const S3BucketPath = 's3://0xjs-docs-jsons/';
 
     // tslint:disable-next-line:no-console
     console.log('POSTPUBLISH: Release successful, generating docs...');
-    const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
-
-    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
-        cwd,
-    });
-    if (!_.isEmpty(result.stderr)) {
-        throw new Error(result.stderr);
-    }
-    const fileName = `v${version}.json`;
-    // tslint:disable-next-line:no-console
-    console.log(`POSTPUBLISH: Doc generation successful, uploading docs... as ${fileName}`);
-    const s3Url = S3BucketPath + fileName;
-    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
-        cwd,
-    });
+    await postpublishUtils.generateAndUploadDocsAsync(__dirname, cwd, fileIncludesAdjusted, version, S3BucketPath);
 })().catch(console.error);
diff --git a/packages/0x.js/src/monorepo_scripts/stagedocs.ts b/packages/0x.js/src/monorepo_scripts/stagedocs.ts
index 20355c52c..525d6a96f 100644
--- a/packages/0x.js/src/monorepo_scripts/stagedocs.ts
+++ b/packages/0x.js/src/monorepo_scripts/stagedocs.ts
@@ -11,20 +11,9 @@ const S3BucketPath = 's3://staging-0xjs-docs-jsons/';
 // So far, we only have @0xproject/types as part of 0x.js's public interface.
 const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts'];
 const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
-const projectFiles = fileIncludesAdjusted.join(' ');
 const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
-const version = process.env.DOCS_VERSION;
+const version = process.env.DOCS_VERSION || '0.0.0';
 
 (async () => {
-    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
-        cwd,
-    });
-    if (!_.isEmpty(result.stderr)) {
-        throw new Error(result.stderr);
-    }
-    const fileName = `v${version}.json`;
-    const s3Url = S3BucketPath + fileName;
-    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
-        cwd,
-    });
+    await postpublishUtils.generateAndUploadDocsAsync(__dirname, cwd, fileIncludesAdjusted, version, S3BucketPath);
 })().catch(console.error);
diff --git a/packages/connect/src/monorepo_scripts/postpublish.ts b/packages/connect/src/monorepo_scripts/postpublish.ts
index 4cb8bf071..ecbd26872 100644
--- a/packages/connect/src/monorepo_scripts/postpublish.ts
+++ b/packages/connect/src/monorepo_scripts/postpublish.ts
@@ -11,7 +11,6 @@ const subPackageName = (packageJSON as any).name;
 // to this array so that TypeDoc picks it up and adds it to the Docs JSON
 const fileIncludes = [...(tsConfig as any).include];
 const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
-const projectFiles = fileIncludesAdjusted.join(' ');
 const S3BucketPath = 's3://connect-docs-jsons/';
 
 (async () => {
@@ -25,19 +24,5 @@ const S3BucketPath = 's3://connect-docs-jsons/';
 
     // tslint:disable-next-line:no-console
     console.log('POSTPUBLISH: Release successful, generating docs...');
-    const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
-
-    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
-        cwd,
-    });
-    if (!_.isEmpty(result.stderr)) {
-        throw new Error(result.stderr);
-    }
-    const fileName = `v${version}.json`;
-    // tslint:disable-next-line:no-console
-    console.log(`POSTPUBLISH: Doc generation successful, uploading docs... as ${fileName}`);
-    const s3Url = S3BucketPath + fileName;
-    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
-        cwd,
-    });
+    await postpublishUtils.generateAndUploadDocsAsync(__dirname, cwd, fileIncludesAdjusted, version, S3BucketPath);
 })().catch(console.error);
diff --git a/packages/connect/src/monorepo_scripts/stagedocs.ts b/packages/connect/src/monorepo_scripts/stagedocs.ts
index ae0383ed7..efd3ad62d 100644
--- a/packages/connect/src/monorepo_scripts/stagedocs.ts
+++ b/packages/connect/src/monorepo_scripts/stagedocs.ts
@@ -12,18 +12,8 @@ const fileIncludes = [...(tsConfig as any).include];
 const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
 const projectFiles = fileIncludesAdjusted.join(' ');
 const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
-const version = process.env.DOCS_VERSION;
+const version = process.env.DOCS_VERSION || '0.0.0';
 
 (async () => {
-    const result = await execAsync(`JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`, {
-        cwd,
-    });
-    if (!_.isEmpty(result.stderr)) {
-        throw new Error(result.stderr);
-    }
-    const fileName = `v${version}.json`;
-    const s3Url = S3BucketPath + fileName;
-    return execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
-        cwd,
-    });
+    await postpublishUtils.generateAndUploadDocsAsync(__dirname, cwd, fileIncludesAdjusted, version, S3BucketPath);
 })().catch(console.error);
diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts
index 6c8771c6f..a36408ccd 100644
--- a/packages/monorepo-scripts/src/postpublish_utils.ts
+++ b/packages/monorepo-scripts/src/postpublish_utils.ts
@@ -81,5 +81,31 @@ export const postpublishUtils = {
         });
         return fileIncludesAdjusted;
     },
+    async generateAndUploadDocsAsync(
+        dirname: string,
+        cwd: string,
+        includedFiles: string[],
+        version: string,
+        S3BucketPath: string,
+    ) {
+        const jsonFilePath = `${dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
+        const projectFiles = includedFiles.join(' ');
+        const result = await execAsync(
+            `JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`,
+            {
+                cwd,
+            },
+        );
+        if (!_.isEmpty(result.stderr)) {
+            throw new Error(result.stderr);
+        }
+        const fileName = `v${version}.json`;
+        utils.log(`POSTPUBLISH: Doc generation successful, uploading docs... as ${fileName}`);
+        const s3Url = S3BucketPath + fileName;
+        await execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
+            cwd,
+        });
+        utils.log(`POSTPUBLISH: Docs uploaded to S3 bucket: ${S3BucketPath}`);
+    },
     generatedDocsDirectoryName,
 };
-- 
cgit v1.2.3


From f7c1e10b5ac112866ee55e7fededdb37c890d30f Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Wed, 14 Mar 2018 14:07:24 +0100
Subject: Move configuration into package.json configs section

---
 packages/0x.js/package.json                        |  11 +-
 packages/0x.js/src/globals.d.ts                    |   1 -
 packages/0x.js/src/monorepo_scripts/postpublish.ts |  27 +---
 packages/0x.js/src/monorepo_scripts/stagedocs.ts   |  21 +--
 .../abi-gen/src/monorepo_scripts/postpublish.ts    |   5 +-
 .../assert/src/monorepo_scripts/postpublish.ts     |   5 +-
 .../src/monorepo_scripts/postpublish.ts            |   5 +-
 .../monorepo_scripts/postpublish.ts                |   5 +-
 .../monorepo_scripts/postpublish.ts                |   5 +-
 packages/connect/package.json                      |   9 ++
 .../connect/src/monorepo_scripts/postpublish.ts    |  26 +---
 packages/connect/src/monorepo_scripts/stagedocs.ts |  21 +--
 .../deployer/src/monorepo_scripts/postpublish.ts   |   5 +-
 .../dev-utils/src/monorepo_scripts/postpublish.ts  |   5 +-
 .../monorepo_scripts/postpublish.ts                |   5 +-
 .../src/monorepo_scripts/postpublish.ts            |   5 +-
 packages/monorepo-scripts/src/postpublish_utils.ts | 141 ++++++++++++++-------
 .../react-docs/src/monorepo_scripts/postpublish.ts |   5 +-
 .../src/monorepo_scripts/postpublish.ts            |   5 +-
 .../sra-report/src/monorepo_scripts/postpublish.ts |   5 +-
 .../src/monorepo_scripts/postpublish.ts            |   5 +-
 .../tslint-config/monorepo_scripts/postpublish.ts  |   5 +-
 packages/types/src/monorepo_scripts/postpublish.ts |   5 +-
 packages/utils/src/monorepo_scripts/postpublish.ts |   5 +-
 .../monorepo_scripts/postpublish.ts                |   5 +-
 .../src/monorepo_scripts/postpublish.ts            |   5 +-
 26 files changed, 185 insertions(+), 162 deletions(-)

diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json
index ec55bf1af..f99029b53 100644
--- a/packages/0x.js/package.json
+++ b/packages/0x.js/package.json
@@ -31,7 +31,15 @@
         "run_mocha": "mocha lib/test/**/*_test.js --timeout 10000 --bail --exit"
     },
     "config": {
-        "artifacts": "TokenTransferProxy Exchange TokenRegistry Token EtherToken"
+        "artifacts": "TokenTransferProxy Exchange TokenRegistry Token EtherToken",
+        "postpublish": {
+            "assets": ["_bundles/index.js", "_bundles/index.min.js"],
+            "docPublishConfigs": {
+                "extraFileIncludes": ["../types/src/index.ts"],
+                "s3BucketPath": "s3://0xjs-docs-jsons/",
+                "s3StagingBucketPath": "s3://staging-0xjs-docs-jsons/"
+            }
+        }
     },
     "repository": {
         "type": "git",
@@ -53,7 +61,6 @@
         "@types/node": "^8.0.53",
         "@types/sinon": "^2.2.2",
         "@types/uuid": "^3.4.2",
-        "async-child-process": "^1.1.1",
         "awesome-typescript-loader": "^3.1.3",
         "chai": "^4.0.1",
         "chai-as-promised": "^7.1.0",
diff --git a/packages/0x.js/src/globals.d.ts b/packages/0x.js/src/globals.d.ts
index f37ac7cb0..e2c321f38 100644
--- a/packages/0x.js/src/globals.d.ts
+++ b/packages/0x.js/src/globals.d.ts
@@ -4,7 +4,6 @@ declare module 'dirty-chai';
 declare module 'request-promise-native';
 declare module 'web3-provider-engine';
 declare module 'web3-provider-engine/subproviders/rpc';
-declare module 'async-child-process';
 declare module 'publish-release';
 
 // semver-sort declarations
diff --git a/packages/0x.js/src/monorepo_scripts/postpublish.ts b/packages/0x.js/src/monorepo_scripts/postpublish.ts
index 88be6444f..dcb99d0f7 100644
--- a/packages/0x.js/src/monorepo_scripts/postpublish.ts
+++ b/packages/0x.js/src/monorepo_scripts/postpublish.ts
@@ -1,29 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
-import { execAsync } from 'async-child-process';
-import * as _ from 'lodash';
 
 import * as packageJSON from '../package.json';
-import * as tsConfig from '../tsconfig.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
 const cwd = `${__dirname}/..`;
-const subPackageName = (packageJSON as any).name;
-// Include any external packages that are part of the 0x.js public interface
-// to this array so that TypeDoc picks it up and adds it to the Docs JSON
-// So far, we only have @0xproject/types as part of 0x.js's public interface.
-const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts'];
-const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
-const S3BucketPath = 's3://0xjs-docs-jsons/';
-
-(async () => {
-    const tagAndVersion = await postpublishUtils.getLatestTagAndVersionAsync(subPackageName);
-    const tag = tagAndVersion.tag;
-    const version = tagAndVersion.version;
-
-    const releaseName = postpublishUtils.getReleaseName(subPackageName, version);
-    const assets = [`${__dirname}/../_bundles/index.js`, `${__dirname}/../_bundles/index.min.js`];
-    const release = await postpublishUtils.publishReleaseNotesAsync(tag, releaseName, assets);
-
-    // tslint:disable-next-line:no-console
-    console.log('POSTPUBLISH: Release successful, generating docs...');
-    await postpublishUtils.generateAndUploadDocsAsync(__dirname, cwd, fileIncludesAdjusted, version, S3BucketPath);
-})().catch(console.error);
+// tslint:disable-next-line:no-floating-promises
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/0x.js/src/monorepo_scripts/stagedocs.ts b/packages/0x.js/src/monorepo_scripts/stagedocs.ts
index 525d6a96f..e732ac8eb 100644
--- a/packages/0x.js/src/monorepo_scripts/stagedocs.ts
+++ b/packages/0x.js/src/monorepo_scripts/stagedocs.ts
@@ -1,19 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
-import { execAsync } from 'async-child-process';
-import * as _ from 'lodash';
 
-import * as tsConfig from '../tsconfig.json';
+import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const cwd = __dirname + '/..';
-const S3BucketPath = 's3://staging-0xjs-docs-jsons/';
-// Include any external packages that are part of the 0x.js public interface
-// to this array so that TypeDoc picks it up and adds it to the Docs JSON
-// So far, we only have @0xproject/types as part of 0x.js's public interface.
-const fileIncludes = [...(tsConfig as any).include, '../types/src/index.ts'];
-const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
-const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
-const version = process.env.DOCS_VERSION || '0.0.0';
-
-(async () => {
-    await postpublishUtils.generateAndUploadDocsAsync(__dirname, cwd, fileIncludesAdjusted, version, S3BucketPath);
-})().catch(console.error);
+const cwd = `${__dirname}/..`;
+// tslint:disable-next-line:no-floating-promises
+postpublishUtils.publishDocsToStagingAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/abi-gen/src/monorepo_scripts/postpublish.ts b/packages/abi-gen/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/abi-gen/src/monorepo_scripts/postpublish.ts
+++ b/packages/abi-gen/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/assert/src/monorepo_scripts/postpublish.ts b/packages/assert/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/assert/src/monorepo_scripts/postpublish.ts
+++ b/packages/assert/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/base-contract/src/monorepo_scripts/postpublish.ts b/packages/base-contract/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/base-contract/src/monorepo_scripts/postpublish.ts
+++ b/packages/base-contract/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts b/packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts
+++ b/packages/chai-as-promised-typescript-typings/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/chai-typescript-typings/monorepo_scripts/postpublish.ts b/packages/chai-typescript-typings/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/chai-typescript-typings/monorepo_scripts/postpublish.ts
+++ b/packages/chai-typescript-typings/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/connect/package.json b/packages/connect/package.json
index 0c4db7f60..8b3b24fcd 100644
--- a/packages/connect/package.json
+++ b/packages/connect/package.json
@@ -23,6 +23,15 @@
         "test": "run-s clean build copy_test_fixtures run_mocha",
         "test:circleci": "yarn test"
     },
+    "config": {
+        "postpublish": {
+            "assets": ["_bundles/index.js", "_bundles/index.min.js"],
+            "docPublishConfigs": {
+                "s3BucketPath": "s3://connect-docs-jsons/",
+                "s3StagingBucketPath": "s3://staging-connect-docs-jsons/"
+            }
+        }
+    },
     "repository": {
         "type": "git",
         "url": "https://github.com/0xProject/0x-monorepo.git"
diff --git a/packages/connect/src/monorepo_scripts/postpublish.ts b/packages/connect/src/monorepo_scripts/postpublish.ts
index ecbd26872..dcb99d0f7 100644
--- a/packages/connect/src/monorepo_scripts/postpublish.ts
+++ b/packages/connect/src/monorepo_scripts/postpublish.ts
@@ -1,28 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
-import { execAsync } from 'async-child-process';
-import * as _ from 'lodash';
 
 import * as packageJSON from '../package.json';
-import * as tsConfig from '../tsconfig.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
 const cwd = `${__dirname}/..`;
-const subPackageName = (packageJSON as any).name;
-// Include any external packages that are part of the @0xproject/connect public interface
-// to this array so that TypeDoc picks it up and adds it to the Docs JSON
-const fileIncludes = [...(tsConfig as any).include];
-const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
-const S3BucketPath = 's3://connect-docs-jsons/';
-
-(async () => {
-    const tagAndVersion = await postpublishUtils.getLatestTagAndVersionAsync(subPackageName);
-    const tag = tagAndVersion.tag;
-    const version = tagAndVersion.version;
-
-    const releaseName = postpublishUtils.getReleaseName(subPackageName, version);
-    const assets = [`${__dirname}/../_bundles/index.js`, `${__dirname}/../_bundles/index.min.js`];
-    const release = await postpublishUtils.publishReleaseNotesAsync(tag, releaseName, assets);
-
-    // tslint:disable-next-line:no-console
-    console.log('POSTPUBLISH: Release successful, generating docs...');
-    await postpublishUtils.generateAndUploadDocsAsync(__dirname, cwd, fileIncludesAdjusted, version, S3BucketPath);
-})().catch(console.error);
+// tslint:disable-next-line:no-floating-promises
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/connect/src/monorepo_scripts/stagedocs.ts b/packages/connect/src/monorepo_scripts/stagedocs.ts
index efd3ad62d..e732ac8eb 100644
--- a/packages/connect/src/monorepo_scripts/stagedocs.ts
+++ b/packages/connect/src/monorepo_scripts/stagedocs.ts
@@ -1,19 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
-import { execAsync } from 'async-child-process';
-import * as _ from 'lodash';
 
-import * as tsConfig from '../tsconfig.json';
+import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const cwd = __dirname + '/..';
-const S3BucketPath = 's3://staging-connect-docs-jsons/';
-// Include any external packages that are part of the @0xproject/connect public interface
-// to this array so that TypeDoc picks it up and adds it to the Docs JSON
-const fileIncludes = [...(tsConfig as any).include];
-const fileIncludesAdjusted = postpublishUtils.adjustFileIncludePaths(fileIncludes, __dirname);
-const projectFiles = fileIncludesAdjusted.join(' ');
-const jsonFilePath = `${__dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
-const version = process.env.DOCS_VERSION || '0.0.0';
-
-(async () => {
-    await postpublishUtils.generateAndUploadDocsAsync(__dirname, cwd, fileIncludesAdjusted, version, S3BucketPath);
-})().catch(console.error);
+const cwd = `${__dirname}/..`;
+// tslint:disable-next-line:no-floating-promises
+postpublishUtils.publishDocsToStagingAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/deployer/src/monorepo_scripts/postpublish.ts b/packages/deployer/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/deployer/src/monorepo_scripts/postpublish.ts
+++ b/packages/deployer/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/dev-utils/src/monorepo_scripts/postpublish.ts b/packages/dev-utils/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/dev-utils/src/monorepo_scripts/postpublish.ts
+++ b/packages/dev-utils/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts b/packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts
+++ b/packages/ethers-typescript-typings/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/json-schemas/src/monorepo_scripts/postpublish.ts b/packages/json-schemas/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/json-schemas/src/monorepo_scripts/postpublish.ts
+++ b/packages/json-schemas/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts
index a36408ccd..55c44ca63 100644
--- a/packages/monorepo-scripts/src/postpublish_utils.ts
+++ b/packages/monorepo-scripts/src/postpublish_utils.ts
@@ -10,37 +10,95 @@ const publishReleaseAsync = promisify(publishRelease);
 const githubPersonalAccessToken = process.env.GITHUB_PERSONAL_ACCESS_TOKEN_0X_JS;
 const generatedDocsDirectoryName = 'generated_docs';
 
-export interface TagAndVersion {
-    tag: string;
+export interface PostpublishConfigs {
+    cwd: string;
+    packageName: string;
     version: string;
+    assets: string[];
+    docPublishConfigs: DocPublishConfigs;
+}
+
+export interface DocPublishConfigs {
+    fileIncludes: string[];
+    s3BucketPath: string;
+    s3StagingBucketPath: string;
 }
 
 export const postpublishUtils = {
-    async getLatestTagAndVersionAsync(subPackageName: string): Promise<TagAndVersion> {
-        const subPackagePrefix = `${subPackageName}@`;
-        const gitTagsCommand = `git tag -l "${subPackagePrefix}*"`;
-        const result = await execAsync(gitTagsCommand);
-        if (!_.isEmpty(result.stderr)) {
-            throw new Error(result.stderr);
+    generateConfig(packageJSON: any, tsConfigJSON: any, cwd: string): PostpublishConfigs {
+        if (_.isUndefined(packageJSON.name)) {
+            throw new Error('name field required in package.json. Cannot publish release notes to Github.');
         }
-        const tags = result.stdout.trim().split('\n');
-        const versions = tags.map((tag: string) => {
-            return tag.slice(subPackagePrefix.length);
-        });
-        const sortedVersions = semverSort.desc(versions);
-        const latestVersion = sortedVersions[0];
-        const latestTag = subPackagePrefix + latestVersion;
-        return {
-            tag: latestTag,
-            version: latestVersion,
+        if (_.isUndefined(packageJSON.version)) {
+            throw new Error('version field required in package.json. Cannot publish release notes to Github.');
+        }
+        const postpublishConfig = _.get(packageJSON, 'config.postpublish', {});
+        const configs: PostpublishConfigs = {
+            cwd,
+            packageName: packageJSON.name,
+            version: packageJSON.version,
+            assets: _.get(postpublishConfig, 'assets', []),
+            docPublishConfigs: {
+                // Include any external packages that are part of the 0x.js public interface
+                // to this array so that TypeDoc picks it up and adds it to the Docs JSON
+                // So far, we only have @0xproject/types as part of 0x.js's public interface.
+                fileIncludes: [
+                    ...(tsConfigJSON as any).include,
+                    ..._.get(postpublishConfig, 'docPublishConfigs.extraFileIncludes', []),
+                ],
+                s3BucketPath: _.get(postpublishConfig, 'docPublishConfigs.s3BucketPath'),
+                s3StagingBucketPath: _.get(postpublishConfig, 'docPublishConfigs.s3StagingBucketPath'),
+            },
         };
+        return configs;
+    },
+    async runAsync(packageJSON: any, tsConfigJSON: any, cwd: string): Promise<void> {
+        const configs = this.generateConfig(packageJSON, tsConfigJSON, cwd);
+        const release = await this.publishReleaseNotesAsync(
+            configs.cwd,
+            configs.packageName,
+            configs.version,
+            configs.assets,
+        );
+        if (
+            !_.isUndefined(configs.docPublishConfigs.s3BucketPath) ||
+            !_.isUndefined(configs.docPublishConfigs.s3StagingBucketPath)
+        ) {
+            utils.log('POSTPUBLISH: Release successful, generating docs...');
+            await postpublishUtils.generateAndUploadDocsAsync(
+                configs.cwd,
+                configs.docPublishConfigs.fileIncludes,
+                configs.version,
+                configs.docPublishConfigs.s3BucketPath,
+            );
+        } else {
+            utils.log(`POSTPUBLISH: No S3Bucket config found for ${packageJSON.name}. Skipping doc JSON generation.`);
+        }
+    },
+    async publishDocsToStagingAsync(packageJSON: any, tsConfigJSON: any, cwd: string) {
+        const configs = this.generateConfig(packageJSON, tsConfigJSON, cwd);
+        if (_.isUndefined(configs.docPublishConfigs.s3StagingBucketPath)) {
+            utils.log('config.postpublish.docPublishConfigs.s3StagingBucketPath entry in package.json not found!');
+            return;
+        }
+
+        utils.log('POSTPUBLISH: Generating docs...');
+        await postpublishUtils.generateAndUploadDocsAsync(
+            configs.cwd,
+            configs.docPublishConfigs.fileIncludes,
+            configs.version,
+            configs.docPublishConfigs.s3StagingBucketPath,
+        );
     },
-    async publishReleaseNotesAsync(tag: string, releaseName: string, assets: string[]) {
+    async publishReleaseNotesAsync(cwd: string, packageName: string, version: string, assets: string[]): Promise<void> {
+        const releaseName = this.getReleaseName(packageName, version);
+        const tag = this.getTag(packageName, version);
         utils.log('POSTPUBLISH: Releasing ', releaseName, '...');
-        return publishReleaseAsync({
+        const finalAssets = this.adjustAssetPaths(cwd, assets);
+        const result = await publishReleaseAsync({
             token: githubPersonalAccessToken,
             owner: '0xProject',
-            repo: '0x.js',
+            repo: '0x-monorepo',
             tag,
             name: releaseName,
             notes: 'N/A',
@@ -51,26 +109,23 @@ export const postpublishUtils = {
             assets,
         });
     },
+    getTag(packageName: string, version: string) {
+        return `${packageName}@${version}`;
+    },
     getReleaseName(subPackageName: string, version: string): string {
         const releaseName = `${subPackageName} v${version}`;
         return releaseName;
     },
-    async standardPostPublishAsync(subPackageName: string): Promise<void> {
-        const result: TagAndVersion = await this.getLatestTagAndVersionAsync(subPackageName);
-        const releaseName = this.getReleaseName(subPackageName, result.version);
-        const assets: string[] = [];
-        await this.publishReleaseNotesAsync(result.tag, releaseName, assets);
+    adjustAssetPaths(cwd: string, assets: string[]) {
+        const finalAssets: string[] = [];
+        _.each(assets, (asset: string) => {
+            finalAssets.push(`${cwd}/${asset}`);
+        });
+        return finalAssets;
     },
     adjustFileIncludePaths(fileIncludes: string[], cwd: string): string[] {
         const fileIncludesAdjusted = _.map(fileIncludes, fileInclude => {
-            let path;
-            if (_.startsWith(fileInclude, '../')) {
-                path = `${cwd}/../${fileInclude}`;
-            } else if (_.startsWith(fileInclude, './')) {
-                path = `${cwd}/../${fileInclude.substr(2)}`;
-            } else {
-                path = `${cwd}/${fileInclude}`;
-            }
+            let path = _.startsWith(fileInclude, './') ? `${cwd}/${fileInclude.substr(2)}` : `${cwd}/${fileInclude}`;
 
             // HACK: tsconfig.json needs wildcard directory endings as `/**/*`
             // but TypeDoc needs it as `/**` in order to pick up files at the root
@@ -81,15 +136,10 @@ export const postpublishUtils = {
         });
         return fileIncludesAdjusted;
     },
-    async generateAndUploadDocsAsync(
-        dirname: string,
-        cwd: string,
-        includedFiles: string[],
-        version: string,
-        S3BucketPath: string,
-    ) {
-        const jsonFilePath = `${dirname}/../${postpublishUtils.generatedDocsDirectoryName}/index.json`;
-        const projectFiles = includedFiles.join(' ');
+    async generateAndUploadDocsAsync(cwd: string, fileIncludes: string[], version: string, S3BucketPath: string) {
+        const fileIncludesAdjusted = this.adjustFileIncludePaths(fileIncludes, cwd);
+        const projectFiles = fileIncludesAdjusted.join(' ');
+        const jsonFilePath = `${cwd}/${generatedDocsDirectoryName}/index.json`;
         const result = await execAsync(
             `JSON_FILE_PATH=${jsonFilePath} PROJECT_FILES="${projectFiles}" yarn docs:json`,
             {
@@ -105,7 +155,10 @@ export const postpublishUtils = {
         await execAsync(`S3_URL=${s3Url} yarn upload_docs_json`, {
             cwd,
         });
+        // Remove the generated docs directory
+        await execAsync(`rm -rf ${generatedDocsDirectoryName}`, {
+            cwd,
+        });
         utils.log(`POSTPUBLISH: Docs uploaded to S3 bucket: ${S3BucketPath}`);
     },
-    generatedDocsDirectoryName,
 };
diff --git a/packages/react-docs/src/monorepo_scripts/postpublish.ts b/packages/react-docs/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/react-docs/src/monorepo_scripts/postpublish.ts
+++ b/packages/react-docs/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/react-shared/src/monorepo_scripts/postpublish.ts b/packages/react-shared/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/react-shared/src/monorepo_scripts/postpublish.ts
+++ b/packages/react-shared/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/sra-report/src/monorepo_scripts/postpublish.ts b/packages/sra-report/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/sra-report/src/monorepo_scripts/postpublish.ts
+++ b/packages/sra-report/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/subproviders/src/monorepo_scripts/postpublish.ts b/packages/subproviders/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/subproviders/src/monorepo_scripts/postpublish.ts
+++ b/packages/subproviders/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/tslint-config/monorepo_scripts/postpublish.ts b/packages/tslint-config/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/tslint-config/monorepo_scripts/postpublish.ts
+++ b/packages/tslint-config/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/types/src/monorepo_scripts/postpublish.ts b/packages/types/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/types/src/monorepo_scripts/postpublish.ts
+++ b/packages/types/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/utils/src/monorepo_scripts/postpublish.ts b/packages/utils/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/utils/src/monorepo_scripts/postpublish.ts
+++ b/packages/utils/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/web3-typescript-typings/monorepo_scripts/postpublish.ts b/packages/web3-typescript-typings/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/web3-typescript-typings/monorepo_scripts/postpublish.ts
+++ b/packages/web3-typescript-typings/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/web3-wrapper/src/monorepo_scripts/postpublish.ts b/packages/web3-wrapper/src/monorepo_scripts/postpublish.ts
index 6e5aa050a..dcb99d0f7 100644
--- a/packages/web3-wrapper/src/monorepo_scripts/postpublish.ts
+++ b/packages/web3-wrapper/src/monorepo_scripts/postpublish.ts
@@ -1,7 +1,8 @@
 import { postpublishUtils } from '@0xproject/monorepo-scripts';
 
 import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
 
-const subPackageName = (packageJSON as any).name;
+const cwd = `${__dirname}/..`;
 // tslint:disable-next-line:no-floating-promises
-postpublishUtils.standardPostPublishAsync(subPackageName);
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
-- 
cgit v1.2.3


From 538ac604a88c2f7ae2dbb1970d464425624a3cd9 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Wed, 14 Mar 2018 14:27:36 +0100
Subject: Add postpublish script to sol-cov

---
 packages/sol-cov/package.json                        | 3 ++-
 packages/sol-cov/scripts/postpublish.js              | 5 -----
 packages/sol-cov/src/globals.d.ts                    | 8 ++++++++
 packages/sol-cov/src/monorepo_scripts/postpublish.ts | 8 ++++++++
 4 files changed, 18 insertions(+), 6 deletions(-)
 delete mode 100644 packages/sol-cov/scripts/postpublish.js
 create mode 100644 packages/sol-cov/src/monorepo_scripts/postpublish.ts

diff --git a/packages/sol-cov/package.json b/packages/sol-cov/package.json
index af6be13f2..48d798fa3 100644
--- a/packages/sol-cov/package.json
+++ b/packages/sol-cov/package.json
@@ -7,7 +7,7 @@
     "scripts": {
         "build:watch": "tsc -w",
         "lint": "tslint --project . 'src/**/*.ts'",
-        "clean": "shx rm -rf lib",
+        "clean": "shx rm -rf lib scripts",
         "build": "tsc"
     },
     "repository": {
@@ -33,6 +33,7 @@
         "web3": "^0.20.0"
     },
     "devDependencies": {
+        "@0xproject/monorepo-scripts": "^0.1.12",
         "@0xproject/tslint-config": "^0.4.9",
         "@types/istanbul": "^0.4.29",
         "@types/node": "^8.0.53",
diff --git a/packages/sol-cov/scripts/postpublish.js b/packages/sol-cov/scripts/postpublish.js
deleted file mode 100644
index b3e5407c8..000000000
--- a/packages/sol-cov/scripts/postpublish.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const postpublish_utils = require('../../../scripts/postpublish_utils');
-const packageJSON = require('../package.json');
-
-const subPackageName = packageJSON.name;
-postpublish_utils.standardPostPublishAsync(subPackageName);
\ No newline at end of file
diff --git a/packages/sol-cov/src/globals.d.ts b/packages/sol-cov/src/globals.d.ts
index 54ee64684..3e457f0b5 100644
--- a/packages/sol-cov/src/globals.d.ts
+++ b/packages/sol-cov/src/globals.d.ts
@@ -1,4 +1,12 @@
 // tslint:disable:completed-docs
+
+declare module '*.json' {
+    const json: any;
+    /* tslint:disable */
+    export default json;
+    /* tslint:enable */
+}
+
 declare module 'solidity-parser-antlr' {
     export interface BaseASTNode {
         range: [number, number];
diff --git a/packages/sol-cov/src/monorepo_scripts/postpublish.ts b/packages/sol-cov/src/monorepo_scripts/postpublish.ts
new file mode 100644
index 000000000..dcb99d0f7
--- /dev/null
+++ b/packages/sol-cov/src/monorepo_scripts/postpublish.ts
@@ -0,0 +1,8 @@
+import { postpublishUtils } from '@0xproject/monorepo-scripts';
+
+import * as packageJSON from '../package.json';
+import * as tsConfigJSON from '../tsconfig.json';
+
+const cwd = `${__dirname}/..`;
+// tslint:disable-next-line:no-floating-promises
+postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
-- 
cgit v1.2.3


From 32d15d79f10470d764b2645574884573cd3beeaa Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Wed, 14 Mar 2018 14:30:15 +0100
Subject: Add script copying to build command

---
 packages/sol-cov/package.json | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/sol-cov/package.json b/packages/sol-cov/package.json
index 48d798fa3..84e58f8d8 100644
--- a/packages/sol-cov/package.json
+++ b/packages/sol-cov/package.json
@@ -8,7 +8,7 @@
         "build:watch": "tsc -w",
         "lint": "tslint --project . 'src/**/*.ts'",
         "clean": "shx rm -rf lib scripts",
-        "build": "tsc"
+        "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts"
     },
     "repository": {
         "type": "git",
@@ -37,6 +37,7 @@
         "@0xproject/tslint-config": "^0.4.9",
         "@types/istanbul": "^0.4.29",
         "@types/node": "^8.0.53",
+        "copyfiles": "^1.2.0",
         "npm-run-all": "^4.1.2",
         "shx": "^0.2.2",
         "tslint": "5.8.0",
-- 
cgit v1.2.3


From 28abcef1cac095e61d4eb94d42870d3f608d9a97 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Wed, 14 Mar 2018 14:32:45 +0100
Subject: Remove outdated comment

---
 packages/monorepo-scripts/src/postpublish_utils.ts | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts
index 55c44ca63..d90d50fba 100644
--- a/packages/monorepo-scripts/src/postpublish_utils.ts
+++ b/packages/monorepo-scripts/src/postpublish_utils.ts
@@ -39,9 +39,6 @@ export const postpublishUtils = {
             version: packageJSON.version,
             assets: _.get(postpublishConfig, 'assets', []),
             docPublishConfigs: {
-                // Include any external packages that are part of the 0x.js public interface
-                // to this array so that TypeDoc picks it up and adds it to the Docs JSON
-                // So far, we only have @0xproject/types as part of 0x.js's public interface.
                 fileIncludes: [
                     ...(tsConfigJSON as any).include,
                     ..._.get(postpublishConfig, 'docPublishConfigs.extraFileIncludes', []),
-- 
cgit v1.2.3


From 83ae7ba08d55fa964bf7b7a985aea0fe1520c5c7 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Wed, 14 Mar 2018 14:49:09 +0100
Subject: Fix linter issuesx

---
 packages/monorepo-scripts/src/postpublish_utils.ts | 2 +-
 packages/subproviders/src/globals.d.ts             | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/packages/monorepo-scripts/src/postpublish_utils.ts b/packages/monorepo-scripts/src/postpublish_utils.ts
index d90d50fba..898b00c47 100644
--- a/packages/monorepo-scripts/src/postpublish_utils.ts
+++ b/packages/monorepo-scripts/src/postpublish_utils.ts
@@ -40,7 +40,7 @@ export const postpublishUtils = {
             assets: _.get(postpublishConfig, 'assets', []),
             docPublishConfigs: {
                 fileIncludes: [
-                    ...(tsConfigJSON as any).include,
+                    ...tsConfigJSON.include,
                     ..._.get(postpublishConfig, 'docPublishConfigs.extraFileIncludes', []),
                 ],
                 s3BucketPath: _.get(postpublishConfig, 'docPublishConfigs.s3BucketPath'),
diff --git a/packages/subproviders/src/globals.d.ts b/packages/subproviders/src/globals.d.ts
index b3dcd4ed3..2c86346f5 100644
--- a/packages/subproviders/src/globals.d.ts
+++ b/packages/subproviders/src/globals.d.ts
@@ -144,5 +144,6 @@ declare module 'ganache-core' {
         networkId: number;
         mnemonic: string;
     }
+    // tslint:disable-next-line:completed-docs
     export function provider(opts: GanacheOpts): Web3.Provider;
 }
-- 
cgit v1.2.3