diff --git a/.eslintrc b/.eslintrc
index 64cc9dafb5c0079852a694eb28f91cfabe6f03f9..35fcf812c52bbe09b314d5fc27dcbd243e139f55 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -10,3 +10,4 @@ rules:
   "guard-for-in": 0
   "no-undefined": 0
   "no-nested-ternary": 0
+  "no-extend-native": ["error", { "exceptions": ["String"] }]
diff --git a/README.md b/README.md
index 0e89f18e9fb3765b38b10518805596a5bf36209f..83857c3a682cfd9827f9b7eb7bcb264ba88a5239 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,7 @@
 
 - Add modes - For example add a night layer and style
 - Updates selected node or list (incl. image stats cache-breaker) - not only overview tables
+- Node filter is implemented
 - Zoom level if you click a node (`nodeZoom`) - Zoom level 22 available, but it is to close for a click
 - Formatted Code
 - Translation support - https://crowdin.com/project/meshviewer
diff --git a/app.js b/app.js
index 6e8875f37e06d1660c70bcb7894e1d65454e37a7..040129310f2b1f2263823ab1cfdb6beeb2c6ae30 100644
--- a/app.js
+++ b/app.js
@@ -1,4 +1,10 @@
 'use strict';
+// Node search polyfill for mobile browsers and IE
+if (!String.prototype.includes) {
+  String.prototype.includes = function () {
+    return String.prototype.indexOf.apply(this, arguments) !== -1;
+  };
+}
 
 require.config({
   baseUrl: 'lib',
diff --git a/assets/icons/fonts/icon.ttf b/assets/icons/fonts/icon.ttf
index 8b8d8221cc5bfa2d9530bb615bce4ea55a9ed94d..bf938cc1ca9d7e1c1cff49c6fb6ba71676618cde 100644
Binary files a/assets/icons/fonts/icon.ttf and b/assets/icons/fonts/icon.ttf differ
diff --git a/assets/icons/fonts/icon.woff b/assets/icons/fonts/icon.woff
index 7cc19f45434c92dfaadee96d32043182541c9272..ef0bc9e665b038c8791e022cb2cf25f55ac21e1d 100644
Binary files a/assets/icons/fonts/icon.woff and b/assets/icons/fonts/icon.woff differ
diff --git a/assets/icons/fonts/icon.woff2 b/assets/icons/fonts/icon.woff2
index 0377338e069c95378c91bcf8ce06f6efe4592d5a..6d92253e7578fafaddf0164cbe174567eb2b03d3 100644
Binary files a/assets/icons/fonts/icon.woff2 and b/assets/icons/fonts/icon.woff2 differ
diff --git a/assets/icons/icon.scss b/assets/icons/icon.scss
index d589691b6fc75c35c4106eff41c4d9922dc9b5c2..89ca76aa73094550f65ba855208400ebf6cbeff0 100644
--- a/assets/icons/icon.scss
+++ b/assets/icons/icon.scss
@@ -43,3 +43,4 @@
 @include icon('android-remove', '\f2f4');
 @include icon('ios-person', '\f47e');
 @include icon('layer', '\f229');
+@include icon('filter', '\f38B');
diff --git a/lib/filters/hostname.js b/lib/filters/hostname.js
new file mode 100644
index 0000000000000000000000000000000000000000..b311c076afb51b56367a3a25aefe3fc5dd240512
--- /dev/null
+++ b/lib/filters/hostname.js
@@ -0,0 +1,41 @@
+define(function () {
+  'use strict';
+
+  return function () {
+    var refreshFunctions = [];
+    var timer;
+    var input = document.createElement('input');
+
+    function refresh() {
+      clearTimeout(timer);
+      timer = setTimeout(function () {
+        refreshFunctions.forEach(function (f) {
+          f();
+        });
+      }, 250);
+    }
+
+    function run(d) {
+      return (d.nodeinfo !== undefined ? d.nodeinfo.hostname.toLowerCase().includes(input.value.toLowerCase()) : '');
+    }
+
+    function setRefresh(f) {
+      refreshFunctions.push(f);
+    }
+
+    function render(el) {
+      input.type = 'search';
+      input.placeholder = _.t('sidebar.nodeFilter');
+      input.addEventListener('input', refresh);
+      el.classList.add('filter-node');
+      el.classList.add('ion-filter');
+      el.appendChild(input);
+    }
+
+    return {
+      run: run,
+      setRefresh: setRefresh,
+      render: render
+    };
+  };
+});
diff --git a/lib/gui.js b/lib/gui.js
index 815a839a8db449185c0a661ca43a3eccb4efd36e..b195a7515501f4c2026ecfa558751d129f58323a 100644
--- a/lib/gui.js
+++ b/lib/gui.js
@@ -1,10 +1,10 @@
 define(['chroma-js', 'map', 'sidebar', 'tabs', 'container', 'legend',
   'linklist', 'nodelist', 'simplenodelist', 'infobox/main',
   'proportions', 'forcegraph', 'title', 'about', 'datadistributor',
-  'filters/filtergui'],
+  'filters/filtergui', 'filters/hostname'],
   function (chroma, Map, Sidebar, Tabs, Container, Legend, Linklist,
             Nodelist, SimpleNodelist, Infobox, Proportions, ForceGraph,
-            Title, About, DataDistributor, FilterGUI) {
+            Title, About, DataDistributor, FilterGUI, HostnameFilter) {
     'use strict';
 
     return function (config, router) {
@@ -105,6 +105,9 @@ define(['chroma-js', 'map', 'sidebar', 'tabs', 'container', 'legend',
       fanout.watchFilters(filterGUI);
       header.add(filterGUI);
 
+      var hostnameFilter = new HostnameFilter();
+      fanout.addFilter(hostnameFilter);
+
       sidebar.add(tabs);
       tabs.add('sidebar.actual', overview);
       tabs.add('node.nodes', nodelist);
diff --git a/locale/de.json b/locale/de.json
index 9034e425049f82e5671aa6d941b71294c0bc527c..0eadaa610ea123c335c051828c114536d1fbdc86 100644
--- a/locale/de.json
+++ b/locale/de.json
@@ -39,6 +39,7 @@
     "copy":"Kopieren"
   },
   "sidebar":{
+    "nodeFilter": "Knotenfilter",
     "nodes":"%{total} Knoten, davon %{online} Knoten online",
     "clients":"mit %{smart_count} Nutzer |||| mit %{smart_count} Nutzern",
     "gateway":"auf %{smart_count} Gateway |||| auf %{smart_count} Gateways",
diff --git a/locale/en.json b/locale/en.json
index 1b4ec56d3e794924e15e9105fd1e462fbc408e7b..e3ec0ac3466d721bfb2c48ca0b86dfb53f6388bf 100644
--- a/locale/en.json
+++ b/locale/en.json
@@ -39,6 +39,7 @@
     "copy": "Copy"
   },
   "sidebar": {
+    "nodeFilter": "Node filter",
     "nodes": "%{total} nodes, including %{online} nodes online",
     "clients": "with %{smart_count} client |||| with %{smart_count} clients",
     "gateway": "on %{smart_count} gateway |||| on %{smart_count} gateways",
diff --git a/scss/modules/_filter.scss b/scss/modules/_filter.scss
index 4e690dc330ed77d891bafb944f3788a917bf521b..8e209b05e391ad98c5fa9eae40ac6a5464d62e66 100644
--- a/scss/modules/_filter.scss
+++ b/scss/modules/_filter.scss
@@ -37,4 +37,30 @@
       }
     }
   }
+
+  .filter-node {
+    border: 0;
+    padding: 0 5px;
+    width: 100%;
+
+    &::before {
+      font-size: 1.8em;
+    }
+
+    input {
+      background: transparent;
+      border: 0;
+      border-bottom: 1px solid $color-primary;
+      font-family: $font-family;
+      font-size: $font-size;
+      margin: 0 15px 0 3px;
+      outline: none;
+      padding: 0 2px;
+      width: 100%;
+    }
+
+    button {
+      display: none;
+    }
+  }
 }
diff --git a/scss/night.scss b/scss/night.scss
index ddaa1ce2ee4cd6cd29036cfcac6988c5e9a65eb7..a7c8bf399c0c22562d1aadf940ffd77eb7e4b76a 100644
--- a/scss/night.scss
+++ b/scss/night.scss
@@ -35,6 +35,13 @@ html {
     }
   }
 
+  //@import 'modules/filter';
+  .filter-node {
+    input {
+      color: $color-black;
+    }
+  }
+
   //@import 'modules/sidebar';
   .sidebar {
     .infobox, .container {