diff --git a/lib/datasource/hex/index.js b/lib/datasource/hex/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..4b14939f58899c72cbfae100056bde479d99dc9f
--- /dev/null
+++ b/lib/datasource/hex/index.js
@@ -0,0 +1,69 @@
+const URL = require('url');
+
+const got = require('../../util/got');
+const hostRules = require('../../util/host-rules');
+
+module.exports = {
+  getPkgReleases,
+};
+
+function getHostOpts(url) {
+  const { host } = URL.parse(url);
+  const opts = hostRules.find({ platform: 'hex', host }, { json: true });
+  if (opts && opts.token) {
+    opts.hearders = { Authorization: opts.token };
+    delete opts.token;
+  }
+  return opts;
+}
+
+async function getPkgReleases({ lookupName }) {
+  const hexUrl = `https://hex.pm/api/packages/${lookupName}`;
+  try {
+    const opts = getHostOpts(hexUrl);
+    const res = (await got(hexUrl, {
+      json: true,
+      ...opts,
+    })).body;
+    if (!(res && res.releases && res.name)) {
+      logger.warn({ lookupName }, `Received invalid hex package data`);
+      return null;
+    }
+    const result = {
+      releases: [],
+    };
+    if (res.releases) {
+      result.releases = res.releases.map(version => ({
+        version: version.version,
+      }));
+    }
+    if (res.meta && res.meta.links) {
+      result.sourceUrl = res.meta.links.Github;
+    }
+    result.homepage = res.html_url;
+    return result;
+  } catch (err) {
+    if (err.statusCode === 401) {
+      logger.info({ lookupName }, `Authorization failure: not authorized`);
+      logger.debug(
+        {
+          err,
+        },
+        'Authorization error'
+      );
+      return null;
+    }
+    if (err.statusCode === 404) {
+      logger.info({ lookupName }, `Dependency lookup failure: not found`);
+      logger.debug(
+        {
+          err,
+        },
+        'Package lookup error'
+      );
+      return null;
+    }
+    logger.warn({ err, lookupName }, 'hex lookup failure: Unknown error');
+    return null;
+  }
+}
diff --git a/lib/datasource/index.js b/lib/datasource/index.js
index f6942bd0215a4ac4a9d5e6b22fe7eac153a4fcbc..403cbb85e84572f691aa6f408dec7c4d7e88dd18 100644
--- a/lib/datasource/index.js
+++ b/lib/datasource/index.js
@@ -3,6 +3,7 @@ const versioning = require('../versioning');
 
 const cargo = require('./cargo');
 const docker = require('./docker');
+const hex = require('./hex');
 const github = require('./github');
 const gitlab = require('./gitlab');
 const go = require('./go');
@@ -20,6 +21,7 @@ const terraform = require('./terraform');
 const datasources = {
   cargo,
   docker,
+  hex,
   github,
   gitlab,
   go,
diff --git a/test/_fixtures/hex/certifi.json b/test/_fixtures/hex/certifi.json
new file mode 100644
index 0000000000000000000000000000000000000000..dafae0044fc706b49e48cf13862883befca103e0
--- /dev/null
+++ b/test/_fixtures/hex/certifi.json
@@ -0,0 +1,133 @@
+{
+    "docs_html_url": null,
+    "downloads": {
+        "all": 7801231,
+        "day": 4550,
+        "recent": 1186862,
+        "week": 107546
+    },
+    "html_url": "https://hex.pm/packages/certifi",
+    "inserted_at": "2015-09-10T13:58:43.376194Z",
+    "meta": {
+        "description": "CA bundle adapted from Mozilla by https://certifi.io",
+        "licenses": [
+            "BSD"
+        ],
+        "links": {
+            "Github": "https://github.com/certifi/erlang-certifi"
+        },
+        "maintainers": [
+            "Benoit Chesneau"
+        ]
+    },
+    "name": "certifi",
+    "owners": [
+        {
+            "email": "bchesneau@gmail.com",
+            "url": "https://hex.pm/api/users/benoitc",
+            "username": "benoitc"
+        }
+    ],
+    "releases": [
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/2.5.1",
+            "version": "2.5.1"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/2.4.2",
+            "version": "2.4.2"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/2.4.1",
+            "version": "2.4.1"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/2.3.1",
+            "version": "2.3.1"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/2.3.0",
+            "version": "2.3.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/2.2.0",
+            "version": "2.2.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/2.1.0",
+            "version": "2.1.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/2.0.0",
+            "version": "2.0.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/1.2.1",
+            "version": "1.2.1"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/1.2.0",
+            "version": "1.2.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/1.1.0",
+            "version": "1.1.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/1.0.0",
+            "version": "1.0.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/0.7.0",
+            "version": "0.7.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/0.6.0",
+            "version": "0.6.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/0.5.0",
+            "version": "0.5.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/0.4.0",
+            "version": "0.4.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/0.3.0",
+            "version": "0.3.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/0.2.0",
+            "version": "0.2.0"
+        },
+        {
+            "has_docs": false,
+            "url": "https://hex.pm/api/packages/certifi/releases/0.1.1",
+            "version": "0.1.1"
+        }
+    ],
+    "repository": "hexpm",
+    "retirements": {
+    },
+    "updated_at": "2019-01-28T20:35:23.869888Z",
+    "url": "https://hex.pm/api/packages/certifi"
+}
diff --git a/test/datasource/__snapshots__/hex.spec.js.snap b/test/datasource/__snapshots__/hex.spec.js.snap
new file mode 100644
index 0000000000000000000000000000000000000000..328b0147280ada397b4245d8272b2594e0be48a9
--- /dev/null
+++ b/test/datasource/__snapshots__/hex.spec.js.snap
@@ -0,0 +1,133 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`datasource/hex getPkgReleases process public repo without auth 1`] = `
+Object {
+  "homepage": "https://hex.pm/packages/certifi",
+  "releases": Array [
+    Object {
+      "version": "2.5.1",
+    },
+    Object {
+      "version": "2.4.2",
+    },
+    Object {
+      "version": "2.4.1",
+    },
+    Object {
+      "version": "2.3.1",
+    },
+    Object {
+      "version": "2.3.0",
+    },
+    Object {
+      "version": "2.2.0",
+    },
+    Object {
+      "version": "2.1.0",
+    },
+    Object {
+      "version": "2.0.0",
+    },
+    Object {
+      "version": "1.2.1",
+    },
+    Object {
+      "version": "1.2.0",
+    },
+    Object {
+      "version": "1.1.0",
+    },
+    Object {
+      "version": "1.0.0",
+    },
+    Object {
+      "version": "0.7.0",
+    },
+    Object {
+      "version": "0.6.0",
+    },
+    Object {
+      "version": "0.5.0",
+    },
+    Object {
+      "version": "0.4.0",
+    },
+    Object {
+      "version": "0.3.0",
+    },
+    Object {
+      "version": "0.2.0",
+    },
+    Object {
+      "version": "0.1.1",
+    },
+  ],
+  "sourceUrl": "https://github.com/certifi/erlang-certifi",
+}
+`;
+
+exports[`datasource/hex getPkgReleases processes real data 1`] = `
+Object {
+  "homepage": "https://hex.pm/packages/certifi",
+  "releases": Array [
+    Object {
+      "version": "2.5.1",
+    },
+    Object {
+      "version": "2.4.2",
+    },
+    Object {
+      "version": "2.4.1",
+    },
+    Object {
+      "version": "2.3.1",
+    },
+    Object {
+      "version": "2.3.0",
+    },
+    Object {
+      "version": "2.2.0",
+    },
+    Object {
+      "version": "2.1.0",
+    },
+    Object {
+      "version": "2.0.0",
+    },
+    Object {
+      "version": "1.2.1",
+    },
+    Object {
+      "version": "1.2.0",
+    },
+    Object {
+      "version": "1.1.0",
+    },
+    Object {
+      "version": "1.0.0",
+    },
+    Object {
+      "version": "0.7.0",
+    },
+    Object {
+      "version": "0.6.0",
+    },
+    Object {
+      "version": "0.5.0",
+    },
+    Object {
+      "version": "0.4.0",
+    },
+    Object {
+      "version": "0.3.0",
+    },
+    Object {
+      "version": "0.2.0",
+    },
+    Object {
+      "version": "0.1.1",
+    },
+  ],
+  "sourceUrl": "https://github.com/certifi/erlang-certifi",
+}
+`;
diff --git a/test/datasource/hex.spec.js b/test/datasource/hex.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..ba1094575d21cc9542a57b9fd129e216395a8ea0
--- /dev/null
+++ b/test/datasource/hex.spec.js
@@ -0,0 +1,81 @@
+const fs = require('fs');
+const got = require('../../lib/util/got');
+const hostRules = require('../../lib/util/host-rules');
+const { getPkgReleases } = require('../../lib/datasource/hex');
+
+let res1 = fs.readFileSync('test/_fixtures/hex/certifi.json', 'utf8');
+res1 = JSON.parse(res1);
+
+jest.mock('../../lib/util/got');
+jest.mock('../../lib/util/host-rules');
+
+describe('datasource/hex', () => {
+  describe('getPkgReleases', () => {
+    beforeEach(() => {
+      global.repoCache = {};
+    });
+    it('returns null for empty result', async () => {
+      got.mockReturnValueOnce(null);
+      expect(
+        await getPkgReleases({ lookupName: 'non_existent_package' })
+      ).toBeNull();
+    });
+    it('returns null for missing fields', async () => {
+      got.mockReturnValueOnce({ res: {} });
+      expect(
+        await getPkgReleases({ lookupName: 'non_existent_package' })
+      ).toBeNull();
+    });
+    it('returns null for 404', async () => {
+      got.mockImplementationOnce(() =>
+        Promise.reject({
+          statusCode: 404,
+        })
+      );
+      expect(await getPkgReleases({ lookupName: 'some_package' })).toBeNull();
+    });
+    it('returns null for 401', async () => {
+      got.mockImplementationOnce(() =>
+        Promise.reject({
+          statusCode: 401,
+        })
+      );
+      expect(await getPkgReleases({ lookupName: 'some_package' })).toBeNull();
+    });
+    it('returns null for unknown error', async () => {
+      got.mockImplementationOnce(() => {
+        throw new Error();
+      });
+      expect(await getPkgReleases('some_package')).toBeNull();
+    });
+    it('returns null with wrong auth token', async () => {
+      hostRules.find.mockReturnValueOnce({ token: 'this_simple_token' });
+      got.mockReturnValueOnce(
+        Promise.reject({
+          statusCode: 401,
+        })
+      );
+      const res = await getPkgReleases({ lookupName: 'certifi' });
+      expect(res).toBeNull();
+    });
+    it('processes real data', async () => {
+      got.mockReturnValueOnce({
+        body: res1,
+      });
+      const res = await getPkgReleases({ lookupName: 'certifi' });
+      expect(res).toMatchSnapshot();
+      expect(res).not.toBeNull();
+      expect(res).toBeDefined();
+    });
+    it('process public repo without auth', async () => {
+      hostRules.find.mockReturnValueOnce(null);
+      got.mockReturnValueOnce({
+        body: res1,
+      });
+      const res = await getPkgReleases({ lookupName: 'certifi' });
+      expect(res).toMatchSnapshot();
+      expect(res).not.toBeNull();
+      expect(res).toBeDefined();
+    });
+  });
+});