diff --git a/packages/github/README.md b/packages/github/README.md
index ce606c1945..eb034088d5 100644
--- a/packages/github/README.md
+++ b/packages/github/README.md
@@ -4,7 +4,7 @@
 
 ## Usage
 
-Returns an authenticated Octokit client that follows the machine [proxy settings](https://help.github.com/en/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners). See https://octokit.github.io/rest.js for the API.
+Returns an authenticated Octokit client that follows the machine [proxy settings](https://help.github.com/en/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners) and correctly sets GHES base urls. See https://octokit.github.io/rest.js for the API.
 
 ```js
 const github = require('@actions/github');
@@ -17,7 +17,10 @@ async function run() {
     // https://help.github.com/en/actions/automating-your-workflow-with-github-actions/authenticating-with-the-github_token#about-the-github_token-secret
     const myToken = core.getInput('myToken');
 
-    const octokit = new github.GitHub(myToken);
+    const octokit = github.getOctokit(token)
+
+    // You can also pass in additional options as a second parameter to getOctokit
+    // const octokit = github.getOctokit(myToken, {userAgent: "MyActionVersion1"});
 
     const { data: pullRequest } = await octokit.pulls.get({
         owner: 'octokit',
@@ -34,8 +37,6 @@ async function run() {
 run();
 ```
 
-You can pass client options, as specified by [Octokit](https://octokit.github.io/rest.js/), as a second argument to the `GitHub` constructor.
-
 You can also make GraphQL requests. See https://github.com/octokit/graphql.js for the API.
 
 ```js
@@ -72,3 +73,25 @@ if (github.context.eventName === 'push') {
   core.info(`The head commit is: ${pushPayload.head}`)
 }
 ```
+
+## Extending the Octokit instance
+`@octokit/core` now supports the [plugin architecture](https://github.com/octokit/core.js#plugins). You can extend the GitHub instance using plugins. 
+
+For example, using the `@octokit/plugin-enterprise-server` you can now access enterprise admin apis on GHES instances.
+
+```ts
+import { GitHub, getOctokitOptions } from '@actions/github/lib/utils'
+import { enterpriseServer220Admin } from '@octokit/plugin-enterprise-server'
+
+const octokit = GitHub.plugin(enterpriseServer220Admin)
+// or override some of the default values as well 
+// const octokit = GitHub.plugin(enterpriseServer220Admin).defaults({userAgent: "MyNewUserAgent"})
+
+const myToken = core.getInput('myToken');
+const myOctokit = new octokit(getOctokitOptions(token))
+// Create a new user
+myOctokit.enterpriseAdmin.createUser({
+  login: "testuser",
+  email: "testuser@test.com",
+});
+```
diff --git a/packages/github/__tests__/github.proxy.test.ts b/packages/github/__tests__/github.proxy.test.ts
new file mode 100644
index 0000000000..5da06582cd
--- /dev/null
+++ b/packages/github/__tests__/github.proxy.test.ts
@@ -0,0 +1,109 @@
+import * as http from 'http'
+import * as https from 'https'
+import proxy from 'proxy'
+
+// Default values are set when the module is imported, so we need to set proxy first.
+const proxyUrl = 'http://127.0.0.1:8081'
+const originalProxyUrl = process.env['https_proxy']
+process.env['https_proxy'] = proxyUrl
+// eslint-disable-next-line import/first
+import {getOctokit} from '../src/github'
+
+describe('@actions/github', () => {
+  let proxyConnects: string[]
+  let proxyServer: http.Server
+  let first = true
+
+  beforeAll(async () => {
+    // Start proxy server
+    proxyServer = proxy()
+    await new Promise(resolve => {
+      const port = Number(proxyUrl.split(':')[2])
+      proxyServer.listen(port, () => resolve())
+    })
+    proxyServer.on('connect', req => {
+      proxyConnects.push(req.url)
+    })
+  })
+
+  beforeEach(() => {
+    proxyConnects = []
+  })
+
+  afterAll(async () => {
+    // Stop proxy server
+    await new Promise(resolve => {
+      proxyServer.once('close', () => resolve())
+      proxyServer.close()
+    })
+
+    if (originalProxyUrl) {
+      process.env['https_proxy'] = originalProxyUrl
+    }
+  })
+
+  it('basic REST client with proxy', async () => {
+    const token = getToken()
+    if (!token) {
+      return
+    }
+
+    const octokit = getOctokit(token)
+    const branch = await octokit.repos.getBranch({
+      owner: 'actions',
+      repo: 'toolkit',
+      branch: 'master'
+    })
+    expect(branch.data.name).toBe('master')
+    expect(proxyConnects).toEqual(['api.github.com:443'])
+  })
+
+  it('basic GraphQL client with proxy', async () => {
+    const token = getToken()
+    if (!token) {
+      return
+    }
+    process.env['https_proxy'] = proxyUrl
+    const octokit = getOctokit(token)
+
+    const repository = await octokit.graphql(
+      '{repository(owner:"actions", name:"toolkit"){name}}'
+    )
+    expect(repository).toEqual({repository: {name: 'toolkit'}})
+    expect(proxyConnects).toEqual(['api.github.com:443'])
+  })
+
+  it('should only use default agent if one is not provided', async () => {
+    const token = getToken()
+    if (!token) {
+      return
+    }
+
+    // Valid token
+    const octokit = getOctokit(token, {
+      request: {
+        agent: new https.Agent()
+      }
+    })
+    const branch = await octokit.repos.getBranch({
+      owner: 'actions',
+      repo: 'toolkit',
+      branch: 'master'
+    })
+    expect(branch.data.name).toBe('master')
+    expect(proxyConnects).toHaveLength(0)
+  })
+
+  function getToken(): string {
+    const token = process.env['GITHUB_TOKEN'] || ''
+    if (!token && first) {
+      /* eslint-disable-next-line no-console */
+      console.warn(
+        'Skipping GitHub tests. Set $GITHUB_TOKEN to run REST client and GraphQL client tests'
+      )
+      first = false
+    }
+
+    return token
+  }
+})
diff --git a/packages/github/__tests__/github.test.ts b/packages/github/__tests__/github.test.ts
index bf81b07ace..4e02c7b316 100644
--- a/packages/github/__tests__/github.test.ts
+++ b/packages/github/__tests__/github.test.ts
@@ -1,6 +1,7 @@
 import * as http from 'http'
 import proxy from 'proxy'
-import {GitHub} from '../src/github'
+import {getOctokit} from '../src/github'
+import {GitHub, getOctokitOptions} from '../src/utils'
 
 describe('@actions/github', () => {
   const proxyUrl = 'http://127.0.0.1:8080'
@@ -43,8 +44,22 @@ describe('@actions/github', () => {
     if (!token) {
       return
     }
+    const octokit = new GitHub(getOctokitOptions(token))
+    const branch = await octokit.repos.getBranch({
+      owner: 'actions',
+      repo: 'toolkit',
+      branch: 'master'
+    })
+    expect(branch.data.name).toBe('master')
+    expect(proxyConnects).toHaveLength(0)
+  })
 
-    const octokit = new GitHub(token)
+  it('basic getOctokit client', async () => {
+    const token = getToken()
+    if (!token) {
+      return
+    }
+    const octokit = getOctokit(token)
     const branch = await octokit.repos.getBranch({
       owner: 'actions',
       repo: 'toolkit',
@@ -85,30 +100,13 @@ describe('@actions/github', () => {
     expect(failed).toBeTruthy()
   })
 
-  it('basic REST client with proxy', async () => {
-    const token = getToken()
-    if (!token) {
-      return
-    }
-
-    process.env['https_proxy'] = proxyUrl
-    const octokit = new GitHub(token)
-    const branch = await octokit.repos.getBranch({
-      owner: 'actions',
-      repo: 'toolkit',
-      branch: 'master'
-    })
-    expect(branch.data.name).toBe('master')
-    expect(proxyConnects).toEqual(['api.github.com:443'])
-  })
-
   it('basic GraphQL client', async () => {
     const token = getToken()
     if (!token) {
       return
     }
 
-    const octokit = new GitHub(token)
+    const octokit = getOctokit(token)
     const repository = await octokit.graphql(
       '{repository(owner:"actions", name:"toolkit"){name}}'
     )
@@ -123,7 +121,7 @@ describe('@actions/github', () => {
     }
 
     // Valid token
-    let octokit = new GitHub(token)
+    let octokit = getOctokit(token)
     const repository = await octokit.graphql(
       '{repository(owner:"actions", name:"toolkit"){name}}'
     )
@@ -143,21 +141,6 @@ describe('@actions/github', () => {
     expect(failed).toBeTruthy()
   })
 
-  it('basic GraphQL client with proxy', async () => {
-    const token = getToken()
-    if (!token) {
-      return
-    }
-
-    process.env['https_proxy'] = proxyUrl
-    const octokit = new GitHub(token)
-    const repository = await octokit.graphql(
-      '{repository(owner:"actions", name:"toolkit"){name}}'
-    )
-    expect(repository).toEqual({repository: {name: 'toolkit'}})
-    expect(proxyConnects).toEqual(['api.github.com:443'])
-  })
-
   function getToken(): string {
     const token = process.env['GITHUB_TOKEN'] || ''
     if (!token && first) {
diff --git a/packages/github/package-lock.json b/packages/github/package-lock.json
index a075eac212..5d0ed1b3d6 100644
--- a/packages/github/package-lock.json
+++ b/packages/github/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "@actions/github",
-  "version": "2.2.0",
+  "version": "3.0.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -464,130 +464,105 @@
         "@octokit/types": "^2.0.0"
       }
     },
-    "@octokit/endpoint": {
-      "version": "5.5.1",
-      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.5.1.tgz",
-      "integrity": "sha512-nBFhRUb5YzVTCX/iAK1MgQ4uWo89Gu0TH00qQHoYRCsE12dWcG1OiLd7v2EIo2+tpUKPMOQ62QFy9hy9Vg2ULg==",
+    "@octokit/core": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-2.5.2.tgz",
+      "integrity": "sha512-+hEKCEGvbS902uuSk/TyVnI7eWDEKVm1BIPnbKy8gsxjTYaybEU8EG73B3Ju5cMj2/OIZ0uHoQWD1nGWhWsj2g==",
       "requires": {
+        "@octokit/auth-token": "^2.4.0",
+        "@octokit/graphql": "^4.3.1",
+        "@octokit/request": "^5.4.0",
         "@octokit/types": "^2.0.0",
+        "before-after-hook": "^2.1.0",
+        "universal-user-agent": "^5.0.0"
+      }
+    },
+    "@octokit/endpoint": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.1.tgz",
+      "integrity": "sha512-pOPHaSz57SFT/m3R5P8MUu4wLPszokn5pXcB/pzavLTQf2jbU+6iayTvzaY6/BiotuRS0qyEUkx3QglT4U958A==",
+      "requires": {
+        "@octokit/types": "^2.11.1",
         "is-plain-object": "^3.0.0",
-        "universal-user-agent": "^4.0.0"
-      },
-      "dependencies": {
-        "universal-user-agent": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
-          "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==",
-          "requires": {
-            "os-name": "^3.1.0"
-          }
-        }
+        "universal-user-agent": "^5.0.0"
       }
     },
     "@octokit/graphql": {
-      "version": "4.3.1",
-      "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.3.1.tgz",
-      "integrity": "sha512-hCdTjfvrK+ilU2keAdqNBWOk+gm1kai1ZcdjRfB30oA3/T6n53UVJb7w0L5cR3/rhU91xT3HSqCd+qbvH06yxA==",
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.4.0.tgz",
+      "integrity": "sha512-Du3hAaSROQ8EatmYoSAJjzAz3t79t9Opj/WY1zUgxVUGfIKn0AEjg+hlOLscF6fv6i/4y/CeUvsWgIfwMkTccw==",
       "requires": {
         "@octokit/request": "^5.3.0",
         "@octokit/types": "^2.0.0",
-        "universal-user-agent": "^4.0.0"
+        "universal-user-agent": "^5.0.0"
+      }
+    },
+    "@octokit/plugin-paginate-rest": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.2.0.tgz",
+      "integrity": "sha512-KoNxC3PLNar8UJwR+1VMQOw2IoOrrFdo5YOiDKnBhpVbKpw+zkBKNMNKwM44UWL25Vkn0Sl3nYIEGKY+gW5ebw==",
+      "requires": {
+        "@octokit/types": "^2.12.1"
       },
       "dependencies": {
-        "universal-user-agent": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
-          "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==",
+        "@octokit/types": {
+          "version": "2.12.2",
+          "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.12.2.tgz",
+          "integrity": "sha512-1GHLI/Jll3j6F0GbYyZPFTcHZMGjAiRfkTEoRUyaVVk2IWbDdwEiClAJvXzfXCDayuGSNCqAUH8lpjZtqW9GDw==",
           "requires": {
-            "os-name": "^3.1.0"
+            "@types/node": ">= 8"
           }
         }
       }
     },
-    "@octokit/plugin-paginate-rest": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz",
-      "integrity": "sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==",
-      "requires": {
-        "@octokit/types": "^2.0.1"
-      }
-    },
-    "@octokit/plugin-request-log": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.0.tgz",
-      "integrity": "sha512-ywoxP68aOT3zHCLgWZgwUJatiENeHE7xJzYjfz8WI0goynp96wETBF+d95b8g/uL4QmS6owPVlaxiz3wyMAzcw=="
-    },
     "@octokit/plugin-rest-endpoint-methods": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz",
-      "integrity": "sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==",
+      "version": "3.10.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-3.10.0.tgz",
+      "integrity": "sha512-Z2DBsdnkWKuVBVFiLoEUKP/82ylH4Ij5F1Mss106hnQYXTxDfCWAyHW+hJ6ophuHVJ9Flaaue3fYn4CggzkHTg==",
       "requires": {
-        "@octokit/types": "^2.0.1",
+        "@octokit/types": "^2.14.0",
         "deprecation": "^2.3.1"
+      },
+      "dependencies": {
+        "@octokit/types": {
+          "version": "2.14.0",
+          "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.14.0.tgz",
+          "integrity": "sha512-1w2wxpN45rEXPDFeB7rGain7wcJ/aTRg8bdILITVnS0O7a4zEGELa3JmIe+jeLdekQjvZRbVfNPqS+mi5fKCKQ==",
+          "requires": {
+            "@types/node": ">= 8"
+          }
+        }
       }
     },
     "@octokit/request": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.3.1.tgz",
-      "integrity": "sha512-5/X0AL1ZgoU32fAepTfEoggFinO3rxsMLtzhlUX+RctLrusn/CApJuGFCd0v7GMFhF+8UiCsTTfsu7Fh1HnEJg==",
+      "version": "5.4.2",
+      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.2.tgz",
+      "integrity": "sha512-zKdnGuQ2TQ2vFk9VU8awFT4+EYf92Z/v3OlzRaSh4RIP0H6cvW1BFPXq4XYvNez+TPQjqN+0uSkCYnMFFhcFrw==",
       "requires": {
-        "@octokit/endpoint": "^5.5.0",
-        "@octokit/request-error": "^1.0.1",
-        "@octokit/types": "^2.0.0",
+        "@octokit/endpoint": "^6.0.1",
+        "@octokit/request-error": "^2.0.0",
+        "@octokit/types": "^2.11.1",
         "deprecation": "^2.0.0",
         "is-plain-object": "^3.0.0",
         "node-fetch": "^2.3.0",
         "once": "^1.4.0",
-        "universal-user-agent": "^4.0.0"
-      },
-      "dependencies": {
-        "universal-user-agent": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
-          "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==",
-          "requires": {
-            "os-name": "^3.1.0"
-          }
-        }
+        "universal-user-agent": "^5.0.0"
       }
     },
     "@octokit/request-error": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.0.tgz",
-      "integrity": "sha512-DNBhROBYjjV/I9n7A8kVkmQNkqFAMem90dSxqvPq57e2hBr7mNTX98y3R2zDpqMQHVRpBDjsvsfIGgBzy+4PAg==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.0.tgz",
+      "integrity": "sha512-rtYicB4Absc60rUv74Rjpzek84UbVHGHJRu4fNVlZ1mCcyUPPuzFfG9Rn6sjHrd95DEsmjSt1Axlc699ZlbDkw==",
       "requires": {
         "@octokit/types": "^2.0.0",
         "deprecation": "^2.0.0",
         "once": "^1.4.0"
       }
     },
-    "@octokit/rest": {
-      "version": "16.43.1",
-      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.1.tgz",
-      "integrity": "sha512-gfFKwRT/wFxq5qlNjnW2dh+qh74XgTQ2B179UX5K1HYCluioWj8Ndbgqw2PVqa1NnVJkGHp2ovMpVn/DImlmkw==",
-      "requires": {
-        "@octokit/auth-token": "^2.4.0",
-        "@octokit/plugin-paginate-rest": "^1.1.1",
-        "@octokit/plugin-request-log": "^1.0.0",
-        "@octokit/plugin-rest-endpoint-methods": "2.4.0",
-        "@octokit/request": "^5.2.0",
-        "@octokit/request-error": "^1.0.2",
-        "atob-lite": "^2.0.0",
-        "before-after-hook": "^2.0.0",
-        "btoa-lite": "^1.0.0",
-        "deprecation": "^2.0.0",
-        "lodash.get": "^4.4.2",
-        "lodash.set": "^4.3.2",
-        "lodash.uniq": "^4.5.0",
-        "octokit-pagination-methods": "^1.1.0",
-        "once": "^1.4.0",
-        "universal-user-agent": "^4.0.0"
-      }
-    },
     "@octokit/types": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.0.2.tgz",
-      "integrity": "sha512-StASIL2lgT3TRjxv17z9pAqbnI7HGu9DrJlg3sEBFfCLaMEqp+O3IQPUF6EZtQ4xkAu2ml6kMBBCtGxjvmtmuQ==",
+      "version": "2.16.2",
+      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.16.2.tgz",
+      "integrity": "sha512-O75k56TYvJ8WpAakWwYRN8Bgu60KrmX0z1KqFp1kNiFNkgW+JW+9EBKZ+S33PU6SLvbihqd+3drvPxKK68Ee8Q==",
       "requires": {
         "@types/node": ">= 8"
       }
@@ -921,11 +896,6 @@
       "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
       "dev": true
     },
-    "atob-lite": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz",
-      "integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY="
-    },
     "aws-sign2": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -1124,11 +1094,6 @@
         "node-int64": "^0.4.0"
       }
     },
-    "btoa-lite": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
-      "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc="
-    },
     "buffer-from": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@@ -3031,27 +2996,12 @@
       "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
       "dev": true
     },
-    "lodash.get": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
-      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
-    },
-    "lodash.set": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
-      "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM="
-    },
     "lodash.sortby": {
       "version": "4.7.0",
       "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
       "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
       "dev": true
     },
-    "lodash.uniq": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
-      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M="
-    },
     "lolex": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz",
@@ -3413,11 +3363,6 @@
         }
       }
     },
-    "octokit-pagination-methods": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz",
-      "integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ=="
-    },
     "once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -4615,9 +4560,9 @@
       }
     },
     "universal-user-agent": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
-      "integrity": "sha512-eM8knLpev67iBDizr/YtqkJsF3GK8gzDc6st/WKzrTuPtcsOKW/0IdL4cnMBsU69pOx0otavLWBDGTwg+dB0aA==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-5.0.0.tgz",
+      "integrity": "sha512-B5TPtzZleXyPrUMKCpEHFmVhMN6EhmJYjG5PQna9s7mXeSqGTLap4OpqLl5FCEFUI3UBmllkETwKf/db66Y54Q==",
       "requires": {
         "os-name": "^3.1.0"
       }
@@ -4813,9 +4758,9 @@
       "dev": true
     },
     "windows-release": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz",
-      "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==",
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.0.tgz",
+      "integrity": "sha512-2HetyTg1Y+R+rUgrKeUEhAG/ZuOmTrI1NBb3ZyAGQMYmOJjBBPe4MTodghRkmLJZHwkuPi02anbeGP+Zf401LQ==",
       "requires": {
         "execa": "^1.0.0"
       }
diff --git a/packages/github/package.json b/packages/github/package.json
index ef58523ba6..1eab9a75c2 100644
--- a/packages/github/package.json
+++ b/packages/github/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@actions/github",
-  "version": "2.2.0",
+  "version": "3.0.0",
   "description": "Actions github lib",
   "keywords": [
     "github",
@@ -38,8 +38,9 @@
   },
   "dependencies": {
     "@actions/http-client": "^1.0.3",
-    "@octokit/graphql": "^4.3.1",
-    "@octokit/rest": "^16.43.1"
+    "@octokit/core": "^2.5.1",
+    "@octokit/plugin-paginate-rest": "^2.2.0",
+    "@octokit/plugin-rest-endpoint-methods": "^3.10.0"
   },
   "devDependencies": {
     "jest": "^25.1.0",
diff --git a/packages/github/src/github.ts b/packages/github/src/github.ts
index 699998dc69..bada7e522d 100644
--- a/packages/github/src/github.ts
+++ b/packages/github/src/github.ts
@@ -1,158 +1,20 @@
-// Originally pulled from https://github.com/JasonEtco/actions-toolkit/blob/master/src/github.ts
-import {graphql} from '@octokit/graphql'
-
-// we need this type to set up a property on the GitHub object
-// that has token authorization
-// (it is not exported from octokit by default)
-import {
-  graphql as GraphQL,
-  RequestParameters as GraphQLRequestParameters
-} from '@octokit/graphql/dist-types/types'
-
-import {Octokit} from '@octokit/rest'
 import * as Context from './context'
-import * as http from 'http'
-import * as httpClient from '@actions/http-client'
+import {GitHub, getOctokitOptions} from './utils'
 
-// We need this in order to extend Octokit
-Octokit.prototype = new Octokit()
+// octokit + plugins
+import {OctokitOptions} from '@octokit/core/dist-types/types'
 
 export const context = new Context.Context()
 
-export class GitHub extends Octokit {
-  graphql: GraphQL
-
-  /* eslint-disable no-dupe-class-members */
-  // Disable no-dupe-class-members due to false positive for method overload
-  // https://github.com/typescript-eslint/typescript-eslint/issues/291
-
-  /**
-   * Sets up the REST client and GraphQL client with auth and proxy support.
-   * The parameter `token` or `opts.auth` must be supplied. The GraphQL client
-   * authorization is not setup when `opts.auth` is a function or object.
-   *
-   * @param token  Auth token
-   * @param opts   Octokit options
-   */
-  constructor(token: string, opts?: Omit<Octokit.Options, 'auth'>)
-  constructor(opts: Octokit.Options)
-  constructor(token: string | Octokit.Options, opts?: Octokit.Options) {
-    super(GitHub.getOctokitOptions(GitHub.disambiguate(token, opts)))
-
-    this.graphql = GitHub.getGraphQL(GitHub.disambiguate(token, opts))
-  }
-
-  /**
-   * Disambiguates the constructor overload parameters
-   */
-  private static disambiguate(
-    token: string | Octokit.Options,
-    opts?: Octokit.Options
-  ): [string, Octokit.Options] {
-    return [
-      typeof token === 'string' ? token : '',
-      typeof token === 'object' ? token : opts || {}
-    ]
-  }
-
-  private static getOctokitOptions(
-    args: [string, Octokit.Options]
-  ): Octokit.Options {
-    const token = args[0]
-    const options = {...args[1]} // Shallow clone - don't mutate the object provided by the caller
-
-    // Base URL - GHES or Dotcom
-    options.baseUrl = options.baseUrl || this.getApiBaseUrl()
-
-    // Auth
-    const auth = GitHub.getAuthString(token, options)
-    if (auth) {
-      options.auth = auth
-    }
-
-    // Proxy
-    const agent = GitHub.getProxyAgent(options.baseUrl, options)
-    if (agent) {
-      // Shallow clone - don't mutate the object provided by the caller
-      options.request = options.request ? {...options.request} : {}
-
-      // Set the agent
-      options.request.agent = agent
-    }
-
-    return options
-  }
-
-  private static getGraphQL(args: [string, Octokit.Options]): GraphQL {
-    const defaults: GraphQLRequestParameters = {}
-    defaults.baseUrl = this.getGraphQLBaseUrl()
-    const token = args[0]
-    const options = args[1]
-
-    // Authorization
-    const auth = this.getAuthString(token, options)
-    if (auth) {
-      defaults.headers = {
-        authorization: auth
-      }
-    }
-
-    // Proxy
-    const agent = GitHub.getProxyAgent(defaults.baseUrl, options)
-    if (agent) {
-      defaults.request = {agent}
-    }
-
-    return graphql.defaults(defaults)
-  }
-
-  private static getAuthString(
-    token: string,
-    options: Octokit.Options
-  ): string | undefined {
-    // Validate args
-    if (!token && !options.auth) {
-      throw new Error('Parameter token or opts.auth is required')
-    } else if (token && options.auth) {
-      throw new Error(
-        'Parameters token and opts.auth may not both be specified'
-      )
-    }
-
-    return typeof options.auth === 'string' ? options.auth : `token ${token}`
-  }
-
-  private static getProxyAgent(
-    destinationUrl: string,
-    options: Octokit.Options
-  ): http.Agent | undefined {
-    if (!options.request?.agent) {
-      if (httpClient.getProxyUrl(destinationUrl)) {
-        const hc = new httpClient.HttpClient()
-        return hc.getAgent(destinationUrl)
-      }
-    }
-
-    return undefined
-  }
-
-  private static getApiBaseUrl(): string {
-    return process.env['GITHUB_API_URL'] || 'https://api.github.com'
-  }
-
-  private static getGraphQLBaseUrl(): string {
-    let url =
-      process.env['GITHUB_GRAPHQL_URL'] || 'https://api.github.com/graphql'
-
-    // Shouldn't be a trailing slash, but remove if so
-    if (url.endsWith('/')) {
-      url = url.substr(0, url.length - 1)
-    }
-
-    // Remove trailing "/graphql"
-    if (url.toUpperCase().endsWith('/GRAPHQL')) {
-      url = url.substr(0, url.length - '/graphql'.length)
-    }
-    return url
-  }
+/**
+ * Returns a hydrated octokit ready to use for GitHub Actions
+ *
+ * @param     token    the repo PAT or GITHUB_TOKEN
+ * @param     options  other options to set
+ */
+export function getOctokit(
+  token: string,
+  options?: OctokitOptions
+): InstanceType<typeof GitHub> {
+  return new GitHub(getOctokitOptions(token, options))
 }
diff --git a/packages/github/src/internal/utils.ts b/packages/github/src/internal/utils.ts
new file mode 100644
index 0000000000..ea5ec382fe
--- /dev/null
+++ b/packages/github/src/internal/utils.ts
@@ -0,0 +1,25 @@
+import * as http from 'http'
+import * as httpClient from '@actions/http-client'
+import {OctokitOptions} from '@octokit/core/dist-types/types'
+
+export function getAuthString(
+  token: string,
+  options: OctokitOptions
+): string | undefined {
+  if (!token && !options.auth) {
+    throw new Error('Parameter token or opts.auth is required')
+  } else if (token && options.auth) {
+    throw new Error('Parameters token and opts.auth may not both be specified')
+  }
+
+  return typeof options.auth === 'string' ? options.auth : `token ${token}`
+}
+
+export function getProxyAgent(destinationUrl: string): http.Agent {
+  const hc = new httpClient.HttpClient()
+  return hc.getAgent(destinationUrl)
+}
+
+export function getApiBaseUrl(): string {
+  return process.env['GITHUB_API_URL'] || 'https://api.github.com'
+}
diff --git a/packages/github/src/utils.ts b/packages/github/src/utils.ts
new file mode 100644
index 0000000000..bbc71c10fe
--- /dev/null
+++ b/packages/github/src/utils.ts
@@ -0,0 +1,44 @@
+import * as Context from './context'
+import * as Utils from './internal/utils'
+
+// octokit + plugins
+import {Octokit} from '@octokit/core'
+import {OctokitOptions} from '@octokit/core/dist-types/types'
+import {restEndpointMethods} from '@octokit/plugin-rest-endpoint-methods'
+import {paginateRest} from '@octokit/plugin-paginate-rest'
+
+export const context = new Context.Context()
+
+const baseUrl = Utils.getApiBaseUrl()
+const defaults = {
+  baseUrl,
+  request: {
+    agent: Utils.getProxyAgent(baseUrl)
+  }
+}
+
+export const GitHub = Octokit.plugin(
+  restEndpointMethods,
+  paginateRest
+).defaults(defaults)
+
+/**
+ * Convience function to correctly format Octokit Options to pass into the constructor.
+ *
+ * @param     token    the repo PAT or GITHUB_TOKEN
+ * @param     options  other options to set
+ */
+export function getOctokitOptions(
+  token: string,
+  options?: OctokitOptions
+): OctokitOptions {
+  const opts = Object.assign({}, options || {}) // Shallow clone - don't mutate the object provided by the caller
+
+  // Auth
+  const auth = Utils.getAuthString(token, opts)
+  if (auth) {
+    opts.auth = auth
+  }
+
+  return opts
+}
