diff --git a/misc/instasearch.css b/misc/instasearch.css
new file mode 100644
index 0000000..e7c3365
--- /dev/null
+++ b/misc/instasearch.css
@@ -0,0 +1,10 @@
+/* $Id$ */
+
+.instasearch-irrelevant,
+.instasearch-no-contents {
+  display:none;
+}
+
+.instasearch-no-results {
+  padding:0 0 16px 0;
+}
diff --git a/misc/instasearch.js b/misc/instasearch.js
new file mode 100644
index 0000000..bcc5d57
--- /dev/null
+++ b/misc/instasearch.js
@@ -0,0 +1,116 @@
+// $Id$
+
+(function ($) {
+
+Drupal.instasearch = function (container) {
+  var data = { items: undefined, index: undefined };
+
+  var textfield = container.find('.instasearch-textfield');
+
+  var text = function (elem) {
+    var ret = '';
+    if (!$(elem).is('.instasearch-ignore'))
+      for (var i = 0; i < elem.childNodes.length; i++)
+        if (elem.childNodes[i].nodeType != 8)
+          ret += elem.childNodes[i].nodeType != 1 ?
+            elem.childNodes[i].nodeValue :
+            text(elem.childNodes[i]);
+    return ret;
+  };
+
+  var rebuildIndex = function () {
+    data.items = container.find('.instasearch-item');
+    data.index = $.map(data.items, function (elem) {
+      return text(elem).toLowerCase();
+    });
+    container.find('.instasearch-group').data('instasearch:group', undefined);
+    data.groups = $.map(data.items, function (elem) {
+      var group = $(elem).closest('.instasearch-group');
+      if (group.length) {
+        var x = group.data('instasearch:group');
+        if (x === undefined) {
+          group.data('instasearch:group', x = { group: group, total: 0 });
+        }
+        x.total++;
+        return x;
+      }
+    });
+  };
+
+  var addPlaceholder = function() {
+    if (!container.find('.instasearch-no-results').length)
+      textfield.closest('.form-item').after($('<p class="instasearch-no-results"></p>').text(Drupal.t('There were no results.')));
+  };
+
+  var removePlaceholder = function () {
+    container.find('.instasearch-no-results').remove();
+  };
+
+  var filter = function () {
+    if (data.index === undefined) {
+      rebuildIndex();
+    }
+
+    var value = $.trim(textfield.val().toLowerCase());
+    if (value !== '') {
+      var results = 0;
+      $.each($.unique(data.groups), function () {
+        this.current = 0;
+      });
+      $.each(data.index, function (i, text) {
+        var match = text.indexOf(value) >= 0;
+        results += match;
+        data.groups[i].current += match;
+        data.items.eq(i)
+          [match ? 'addClass' : 'removeClass']('instasearch-match')
+          [match ? 'removeClass' : 'addClass']('instasearch-irrelevant');
+      });
+      $.each($.unique(data.groups), function () {
+        this.group
+          [this.current ? 'addClass' : 'removeClass']('instasearch-has-contents')
+          [this.current ? 'removeClass' : 'addClass']('instasearch-no-contents');
+      });
+      if (results) {
+        removePlaceholder();
+      }
+      else {
+        addPlaceholder();
+      }
+    }
+    else {
+      // Take sure, that every item is displayed.
+      container.find('.instasearch-no-contents').removeClass('instasearch-no-contents');
+      data.items.removeClass('instasearch-match').removeClass('instasearch-irrelevant');
+      removePlaceholder();
+    }
+
+    container.trigger('instasearch');
+  };
+
+  textfield.bind('click keyup', filter);
+
+  if (textfield[0]) {
+    textfield[0].type = 'search';
+    textfield.attr('results', 5);
+  }
+
+  return data;
+};
+
+Drupal.behaviors.instasearch = {
+  attach: function (context) {
+    $('.instasearch-container', context).once('instasearch', function () {
+      var container = $(this);
+      container.data('instasearch', Drupal.instasearch(container));
+    });
+
+    $(context).closest('.instasearch-container').each(function () {
+      var data = $(this).data('instasearch');
+      if (data) {
+        data.index = undefined;
+      }
+    });
+  }
+};
+
+})(jQuery);
diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc
index 99f1e2d..72a5298 100644
--- a/modules/system/system.admin.inc
+++ b/modules/system/system.admin.inc
@@ -749,6 +749,7 @@ function system_modules($form, $form_state = array()) {
       '#title' => t($package),
       '#collapsible' => TRUE,
       '#theme' => 'system_modules_fieldset',
+      '#attributes' => array('class' => array('instasearch-group')),
       '#header' => array(
         array('data' => t('Enabled'), 'class' => array('checkbox')),
         t('Name'),
@@ -763,6 +764,24 @@ function system_modules($form, $form_state = array()) {
     '#value' => t('Save configuration'),
   );
   $form['#action'] = url('admin/config/modules/list/confirm');
+  $form['#attributes']['class'] = 'instasearch-container';
+  $form['#attached_js']['misc/instasearch.js'] = array();
+  $form['instasearch'] = array(
+    '#type' => 'textfield',
+    '#weight' => -5,
+    '#input' => FALSE,
+    '#title' => t('Filter modules'),
+    '#name' => 'instasearch',
+    '#size' => 30,
+    '#value' => '',
+    '#description' => t('Enter the name of a module to filter the list.'),
+    '#attributes' => array('class' => array('instasearch-textfield')),
+    '#attached' => array(
+      'js' => array('misc/instasearch.js'),
+      'css' => array('misc/instasearch.css'),
+    ),
+  );
+
 
   return $form;
 }
@@ -2322,7 +2341,7 @@ function theme_system_modules_fieldset($variables) {
       $description .= '<div class="admin-requirements">' . t('Required by: !module-list', array('!module-list' => implode(', ', $module['#required_by']))) . '</div>';
     }
     $row[] = array('data' => $description, 'class' => array('description'));
-    $rows[] = $row;
+    $rows[] = array('data' => $row, 'class' => array('instasearch-item'));
   }
 
   return theme('table', array('header' => $form['#header'], 'rows' => $rows));
