diff --git a/layouts/css/_utils.scss b/layouts/css/_utils.scss
index 47bb272352fe8..92b230207c0d9 100644
--- a/layouts/css/_utils.scss
+++ b/layouts/css/_utils.scss
@@ -25,3 +25,7 @@
   white-space: nowrap;
   border: none;
 }
+
+.hidden {
+  display: none;
+}
diff --git a/layouts/css/page-modules/_contributor-card.scss b/layouts/css/page-modules/_contributor-card.scss
new file mode 100644
index 0000000000000..699608986bed2
--- /dev/null
+++ b/layouts/css/page-modules/_contributor-card.scss
@@ -0,0 +1,32 @@
+.contributor-card {
+  display: flex;
+  align-items: center;
+  min-height: 42px;
+  width: 300px;
+  padding: 1.5em 1em;
+  margin: 1em auto;
+  border: 1px solid $white;
+  border-radius: 3px;
+
+  > a {
+    height: 40px;
+    width: 40px;
+    flex: 0 0 auto;
+  }
+
+  p {
+    padding-left: 1em;
+    margin: 0;
+    flex: 1 1 1px;
+  }
+
+  .spinner-border {
+    margin: 5px;
+  }
+}
+
+@media (max-width: 350px) {
+  .contributor-card {
+    width: auto;
+  }
+}
diff --git a/layouts/css/page-modules/_header.scss b/layouts/css/page-modules/_header.scss
index 955a41604d85e..1f173bc48a22d 100644
--- a/layouts/css/page-modules/_header.scss
+++ b/layouts/css/page-modules/_header.scss
@@ -52,10 +52,6 @@ header {
     margin: 0;
     padding: 0;
 
-    &.hidden {
-      display: none;
-    }
-
     a {
       color: $light-gray2;
     }
diff --git a/layouts/css/page-modules/_jsfoundation.scss b/layouts/css/page-modules/_jsfoundation.scss
index 02a34906accd4..588c3efb4115e 100644
--- a/layouts/css/page-modules/_jsfoundation.scss
+++ b/layouts/css/page-modules/_jsfoundation.scss
@@ -22,6 +22,21 @@
   margin-left: auto;
 }
 
+.thanking-contributor {
+  max-width: 300px;
+  display: flex;
+  align-items: center;
+  padding: .5em 1em;
+  margin-top: 1em;
+  border: 1px solid $white;
+  border-radius: 3px;
+
+  img {
+    border-radius: 50%;
+    margin-right: 1em;
+  }
+}
+
 @media screen and (max-width: 700px) {
   .issue-link-container {
     flex-wrap: wrap;
diff --git a/layouts/css/page-modules/spinner.scss b/layouts/css/page-modules/spinner.scss
new file mode 100644
index 0000000000000..b3756d56dc702
--- /dev/null
+++ b/layouts/css/page-modules/spinner.scss
@@ -0,0 +1,18 @@
+// borrowed from Bootstrap
+@keyframes spinner-border {
+  to {
+    transform: rotate(360deg);
+  }
+}
+
+.spinner-border {
+  box-sizing: border-box;
+  display: inline-block;
+  width: 2rem;
+  height: 2rem;
+  vertical-align: text-bottom;
+  border: .25em solid currentColor;
+  border-right-color: transparent;
+  border-radius: 50%;
+  animation: spinner-border .75s linear infinite;
+}
diff --git a/layouts/css/styles.scss b/layouts/css/styles.scss
index de05e1251db62..971838040c6ee 100644
--- a/layouts/css/styles.scss
+++ b/layouts/css/styles.scss
@@ -21,6 +21,8 @@
 @import "page-modules/prev-next-navigation";
 @import "page-modules/release-schedule";
 @import "page-modules/resources";
+@import "page-modules/contributor-card";
+@import "page-modules/spinner";
 @import "vendor/prism-tomorrow";
 
 article a {
diff --git a/layouts/partials/contributor-card.hbs b/layouts/partials/contributor-card.hbs
new file mode 100644
index 0000000000000..ea68ef996eb92
--- /dev/null
+++ b/layouts/partials/contributor-card.hbs
@@ -0,0 +1,15 @@
+<div class="contributor-card">
+  <a href="#" rel="nofollow noopener noreferrer">
+    <div class="spinner-border" role="status">
+      <span class="sr-only">Loading...</span>
+    </div>
+    <img id="contributor-avatar" class="hidden" src="/static/images/logos/js-green.svg" alt="Avatar of a Node.js contributor" width="40" height="40">
+  </a>
+
+  <p>
+    Thank you <a href="#" id="contributor-username" rel="nofollow noopener noreferrer">username</a> for being a <a href="https://github.com/nodejs/node/graphs/contributors" rel="nofollow noopener noreferrer" title="List of all Node.js contributors">Node.js contributor</a>
+    <a href="https://github.com/nodejs/node/graphs/contributors" rel="nofollow noopener noreferrer">
+      <strong id="contributor-contributions">0 contributions</strong>
+    </a>
+  </p>
+</div>
diff --git a/layouts/partials/footer.hbs b/layouts/partials/footer.hbs
index 8d074ee2dd7f0..f11b640b7156e 100644
--- a/layouts/partials/footer.hbs
+++ b/layouts/partials/footer.hbs
@@ -20,6 +20,9 @@
       <p>
         <a href="https://raw.githubusercontent.com/nodejs/node/master/LICENSE">Node.js Project Licensing Information</a>.
       </p>
+
+      {{> contributor-card }}
+
     </div>
   </div>
 
diff --git a/layouts/partials/html-head.hbs b/layouts/partials/html-head.hbs
index 6b330d9569fe7..bcbdc0f869c57 100644
--- a/layouts/partials/html-head.hbs
+++ b/layouts/partials/html-head.hbs
@@ -4,6 +4,7 @@
 
   <link rel="dns-prefetch" href="https://fonts.googleapis.com">
   <link rel="dns-prefetch" href="https://fonts.gstatic.com">
+  <link rel="dns-prefetch" href="https://api.github.com">
 
   <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600&display=fallback">
   <link rel="stylesheet" href="/static/css/styles.css">
diff --git a/static/js/main.js b/static/js/main.js
index ba994763a3a15..b66d44b671d02 100644
--- a/static/js/main.js
+++ b/static/js/main.js
@@ -49,6 +49,135 @@
   })
 })()
 
+;(function () {
+  var contributorCard = document.querySelector('.contributor-card')
+
+  if (!contributorCard) {
+    return
+  }
+
+  var contributorAvatar = contributorCard.querySelector('#contributor-avatar')
+  var contributorUsername = contributorCard.querySelector('#contributor-username')
+  var contributorContributions = contributorCard.querySelector('#contributor-contributions')
+  var loadingSpinner = contributorCard.querySelector('.spinner-border')
+
+  if (window.IntersectionObserver) {
+    var observer = new window.IntersectionObserver(function (entries) {
+      entries.forEach(function (entry) {
+        if (entry.intersectionRatio > 0.5) {
+          // In viewport, fetch a random contributor
+          fetchRandomContributor()
+
+          observer.unobserve(entry.target)
+        }
+      })
+    },
+    { threshold: 0.5 }
+    )
+
+    observer.observe(document.querySelector('footer'))
+  } else {
+    // Does not support IntersectionObserver
+    fetchRandomContributor()
+  }
+
+  function fetchRandomContributor () {
+    var maxContributors
+    var fetchDate
+    var needToRefetch = false
+
+    if (window.localStorage) {
+      maxContributors = window.localStorage.getItem('max_contributors')
+      fetchDate = parseInt(window.localStorage.getItem('fetch_date'), 10)
+    }
+
+    // If fetch date is a month old (2592000000 ms === 30 days)
+    if (Date.now() - fetchDate >= 2592000000) {
+      needToRefetch = true
+    }
+
+    // If localStorage and data is less than 1 month old, fetch 1 time
+    if (maxContributors && !needToRefetch) {
+      getContributor(Math.floor(Math.random() * Math.floor(parseInt(maxContributors))) + 1)
+    } else {
+      getMaxContributors(function (randomPage, lastPage) {
+        getContributor(randomPage)
+
+        if (window.localStorage) {
+          window.localStorage.setItem('max_contributors', lastPage)
+        }
+      })
+    }
+  }
+
+  function getMaxContributors (callback) {
+    var xhr = new window.XMLHttpRequest()
+    xhr.open('GET', 'https://api.github.com/repos/nodejs/node/contributors?per_page=1', true)
+
+    xhr.onreadystatechange = function () {
+      if (xhr.readyState === 4) {
+        if (xhr.status === 200) {
+          // Get Headers Links last page to generate a random contributor
+          var links = linkParser(xhr.getResponseHeader('Link'))
+          var randomPage = Math.floor(Math.random() * Math.floor(parseInt(links.last.page, 10))) + 1
+
+          if (window.localStorage) {
+            window.localStorage.setItem('fetch_date', Date.now())
+          }
+          callback(randomPage, links.last.page)
+        } else {
+          return contributorCard.parentNode.removeChild(contributorCard)
+        }
+      }
+    }
+
+    xhr.send()
+  }
+
+  function getContributor (randomPage) {
+    var xhr = new window.XMLHttpRequest()
+    xhr.open('GET', 'https://api.github.com/repos/nodejs/node/contributors?per_page=1&page=' + randomPage, true)
+
+    xhr.onreadystatechange = function () {
+      if (xhr.readyState === 4) {
+        if (xhr.status === 200) {
+          var contributor = JSON.parse(xhr.responseText)[0]
+
+          // Remove loading spinner and show avatar
+          loadingSpinner.parentNode.removeChild(loadingSpinner)
+          contributorAvatar.classList.remove('hidden')
+          // Set new values
+          contributorAvatar.src = contributor.avatar_url + '&s=80'
+          contributorAvatar.parentElement.href = contributor.html_url
+          contributorUsername.textContent = contributor.login
+          contributorUsername.href = contributor.html_url
+          contributorContributions.textContent = contributor.contributions + ' contributions'
+          contributorContributions.parentElement.href = 'https://github.com/nodejs/node/commits?author=' + contributor.login
+        } else {
+          return contributorCard.parentNode.removeChild(contributorCard)
+        }
+      }
+    }
+
+    xhr.send()
+  }
+
+  function linkParser (linkHeader) {
+    var regex = /<([^?]+\?per_page=1&[a-z]+=([\d]+))>;[\s]*rel="([a-z]+)"/g
+    var array = []
+    var object = {}
+
+    while ((array = regex.exec(linkHeader)) !== null) {
+      object[array[3]] = {
+        url: array[1],
+        page: array[2]
+      }
+    }
+
+    return object
+  }
+})()
+
 ;(function (d, n) {
   'use strict'