diff --git modules/system/admin.css modules/system/admin.css
index 0a4d01a..3fb8b7e 100644
--- modules/system/admin.css
+++ modules/system/admin.css
@@ -135,3 +135,23 @@ table.screenshot {
 html.js .custom-container label {
   visibility: hidden;
 }
+
+/**
+ * Formatting of the modules form.
+ */
+#system-modules #edit-search {
+  margin-bottom: 0;
+  border-bottom: none;
+}
+
+#system-modules #edit-search #edit-search-string-wrapper, #system-modules #edit-search #edit-search-submit {
+  float: left;
+}
+
+#system-modules #edit-search #edit-search-string-wrapper {
+  margin: 0 1em 0 0;
+}
+
+#system-modules div.vertical-tabs {
+  margin-top: 0;
+}
\ No newline at end of file
diff --git modules/system/system.admin.inc modules/system/system.admin.inc
index 82eef0a..06d38a3 100644
--- modules/system/system.admin.inc
+++ modules/system/system.admin.inc
@@ -570,11 +570,44 @@ function _system_is_incompatible(&$incompatible, $files, $file) {
  *   The form array.
  */
 function system_modules($form_state = array()) {
-  // Clear all caches.
-  registry_rebuild();
-  drupal_theme_rebuild();
-  node_types_rebuild();
-  cache_clear_all('schema', 'cache');
+  drupal_add_js(drupal_get_path('module', 'system') . '/system.js');
+  drupal_add_js('misc/vertical-tabs.js', array('weight' => 0));
+  drupal_add_css('misc/vertical-tabs.css');
+
+  // Clear all caches, but not when searching the modules page to save time.
+  if (!isset($form_state['storage']['search_string'])) {
+    registry_rebuild();
+    drupal_theme_rebuild();
+    node_types_rebuild();
+    cache_clear_all('schema', 'cache');
+  }
+
+  // Fieldset to search the modules form.
+  $form['search'] = array(
+    '#type' => 'fieldset',
+    '#weight' => -5,
+    '#collapsible' => FALSE,
+    '#title' => t('Search modules'),
+  );
+
+  $form['search']['search_string'] = array(
+    '#type' => 'textfield',
+  );
+
+  $form['search']['search_submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Search'),
+    '#submit' => array('system_modules_search_submit'),
+    '#ahah' => array(
+      'callback' => 'system_modules_search_js',
+      'wrapper' => 'edit-modules-search-pane',
+      'method' => 'replace',
+      'success_callback' => 'moduleFormSearch',
+      'keypress' => TRUE,
+      'event' => 'click',
+    ),
+  );
+
   // Get current list of modules.
   $files = module_rebuild_cache();
 
@@ -591,17 +624,133 @@ function system_modules($form_state = array()) {
   // and if there are unfilled required modules, then form_state['storage'] is
   // filled, triggering a rebuild. In this case we need to display a
   // confirmation form.
-  if (!empty($form_state['storage'])) {
+  if (!empty($form_state['storage']) && !isset($form_state['storage']['search_string'])) {
     return system_modules_confirm_form($files, $form_state['storage']);
   }
 
   $modules = array();
-  $form['modules'] = array('#tree' => TRUE);
+  $form['modules'] = array(
+    '#tree' => TRUE,
+    '#prefix' => '<div class="vertical-tabs-panes" id="modules-form-wrapper">',
+    '#suffix' => '</div>',
+  );
+
+  // Add dependencies and additional information to the files array.
+  $files = _system_modules_build_files_for_form($files);
+
+  // If the search button was clicked, add the search fieldset with matching modules.
+  if (isset($form_state['storage']['search_string'])) {
+    $form['modules']['search_pane'] = _system_modules_search_form($files, $form_state['storage']['search_string']);
+  }
+  // Otherwise, add all modules, with a fieldset for each category.
+  else {
+    // Iterate through each of the modules.
+    foreach ($files as $filename => $module) {
+      $form['modules'][$module->info['package']][$filename] = _system_modules_build_row($module->info, $module->extra);
+    }
+
+    // Add basic information to the fieldsets.
+    foreach (element_children($form['modules']) as $package) {
+      $form['modules'][$package] += array(
+        '#type' => 'fieldset',
+        '#title' => t($package),
+        '#theme' => 'system_modules_fieldset',
+        '#header' => array(
+          array('data' => t('Enabled'), 'class' => 'checkbox'),
+          t('Name'),
+          t('Version'),
+          t('Description'),
+        ),
+      );
+    }
+  }
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save configuration'),
+  );
+  $form['#action'] = url('admin/build/modules/list/confirm');
+
+  return $form;
+}
 
+/**
+ * Submit callback for the search button on the modules form.
+ *
+ * If a search string is present, store it in $form_state['storage'].
+ */
+function system_modules_search_submit($form, &$form_state) {
+  if (isset($form_state['values']['search_string'])) {
+    $form_state['storage']['search_string'] = $form_state['values']['search_string'];
+  }
+  else {
+    unset($form_state['storage']['search_string']);
+  }
+}
+
+/**
+ * AHAH callback for the search button on the modules form.
+ */
+function system_modules_search_js($form, &$form_state) {
+  if (isset($form['modules']['search_pane'])) {
+    $search_form = $form['modules']['search_pane'];
+    drupal_json(array('status' => TRUE, 'data' => drupal_render($search_form)));
+  }
+}
+
+/**
+ * Creates the search result fieldset for the modules form.
+ *
+ * This returns a fieldset similar to the normal module category fieldsets,
+ * but containing modules whose names or descriptions match $search_string.
+ */
+function _system_modules_search_form($files, $search_string) {
+  $search_form = array(
+    '#type' => 'fieldset',
+    '#weight' => 9999,
+    '#title' => t('Search results'),
+  );
+
+  if (!empty($search_string)) {
+    // Iterate over the module files, and add rows for matching names or
+    // descriptions.
+    foreach ($files as $filename => $module) {
+      if (stripos($module->info['name'], $search_string) !== FALSE ||
+          stripos($module->info['description'], $search_string) !== FALSE ||
+          stripos($module->filename, $search_string) !== FALSE) {
+        $search_form[$filename] = _system_modules_build_row($module->info, $module->extra);
+      }
+    }
+  }
+
+  if (element_children($search_form)) {
+    $search_form += array(
+      '#theme' => 'system_modules_fieldset',
+      '#header' => array(
+        array('data' => t('Enabled'), 'class' => 'checkbox'),
+        t('Name'),
+        t('Version'),
+        t('Description'),
+      ),
+    );
+  }
+  else {
+    $search_form['info']['#markup'] = t('Your search did not return any results.');
+  }
+
+  return $search_form;
+}
+
+/**
+ * Add information to the module files array that is needed on the modules form.
+ *
+ * Iterates over the module files and adds dependency information to be used
+ * in the modules form.
+ */
+function _system_modules_build_files_for_form($files) {
   // Used when checking if module implements a help page.
   $help_arg = module_exists('help') ? drupal_help_arg() : FALSE;
 
-  // Iterate through each of the modules.
   foreach ($files as $filename => $module) {
     $extra = array();
     $extra['enabled'] = (bool) $module->status;
@@ -641,31 +790,9 @@ function system_modules($form_state = array()) {
         }
       }
     }
-    $form['modules'][$module->info['package']][$filename] = _system_modules_build_row($module->info, $extra);
+    $files[$filename]->extra = $extra;
   }
-  // Add basic information to the fieldsets.
-  foreach (element_children($form['modules']) as $package) {
-    $form['modules'][$package] += array(
-      '#type' => 'fieldset',
-      '#title' => t($package),
-      '#collapsible' => TRUE,
-      '#theme' => 'system_modules_fieldset',
-      '#header' => array(
-        array('data' => t('Enabled'), 'class' => 'checkbox'),
-        t('Name'),
-        t('Version'),
-        t('Description'),
-      ),
-    );
-  }
-
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save configuration'),
-  );
-  $form['#action'] = url('admin/build/modules/list/confirm');
-
-  return $form;
+  return $files;
 }
 
 /**
@@ -800,7 +927,7 @@ function system_modules_submit($form, &$form_state) {
   include_once DRUPAL_ROOT . '/includes/install.inc';
   $modules = array();
   // If we're not coming from the confirmation form, build the list of modules.
-  if (!isset($form_state['storage'])) {
+  if (!isset($form_state['storage']['modules'])) {
     foreach ($form_state['values']['modules'] as $group_name => $group) {
       foreach ($group as $module => $enabled) {
         $modules[$module] = array('group' => $group_name, 'enabled' => $enabled['enable']);
@@ -812,7 +939,6 @@ function system_modules_submit($form, &$form_state) {
     // the modules out of $form_state.
     $modules = $form_state['storage']['modules'];
   }
-
   // Get a list of all modules, it will be used to find which module requires
   // which.
   $files = module_rebuild_cache();
diff --git modules/system/system.js modules/system/system.js
index 9ff6c08..f19b6dd 100644
--- modules/system/system.js
+++ modules/system/system.js
@@ -134,4 +134,69 @@ Drupal.behaviors.poweredByPreview = {
   }
 };
 
+/**
+ * AHAH success callback for the search button on the modules form.
+ *
+ * If no search fieldset is present, this inserts the search fieldset into
+ * the form and adds a vertical tab for it. If there is already a search fieldset,
+ * it is replaced by the new one.
+ */
+Drupal.ahah.prototype.successCallbacks.moduleFormSearch = function(element, response, status) {
+  new_content = $(response.data);
+
+  // Check if there is already a search tab present, and if so, replace it with
+  // the new one.
+  // We copy over the existing verticalTab data property to reduce flickering.
+  if ($('#system-modules #edit-modules-search-pane').size()) {
+    var tab = $('#edit-modules-search-pane').data('verticalTab')
+    tab.fieldset = $(new_content);
+    $('#system-modules #edit-modules-search-pane').replaceWith(new_content);
+  }
+  else {
+    // Append the search fieldset to the wrapper and add a vertical tab for it.
+    $('#modules-form-wrapper').append(new_content);
+    var tab = new Drupal.verticalTab({ title: $('> legend', new_content).text(), fieldset: $(new_content) });
+    var list = new_content.parents().find('.vertical-tabs-panes').siblings('ul.vertical-tabs-list');
+    list.append(tab.item);
+  }
+  
+  // Add the tab behavior and styling to the new fieldset.
+  $(new_content)
+    .addClass('vertical-tabs-pane')
+    .data('verticalTab', tab)
+    .data('verticalTabCallback', Drupal.moduleFormVerticalTabCallback)
+    .find('input, textarea, select')
+      .change(function() {
+        tab.updateDescription();
+      });
+
+  // Give the search tab the focus and update the description.
+  tab.focus();
+  tab.updateDescription();
+
+  // Attach behaviors to the new content.
+  Drupal.attachBehaviors(new_content);
+}
+
+/**
+ * Assing the vertical tab callback to update the description to all fieldsets
+ * on the modules form.
+ */
+Drupal.behaviors.moduleFormVTab = {
+  attach: function(context) {
+    $('#modules-form-wrapper > fieldset', context).each( function() {
+      $(this).data('verticalTabCallback', Drupal.moduleFormVerticalTabCallback);
+    });
+  }
+};
+
+/**
+ * Vertical tab callback to update the descriptions on the modules form.
+ */
+Drupal.moduleFormVerticalTabCallback = function() {
+  modules = $('input.form-checkbox', this.fieldset).size();
+  enabled = $('input.form-checkbox[checked]', this.fieldset).size();
+  return modules + ' modules, ' + enabled + ' enabled.';
+}
+
 })(jQuery);
\ No newline at end of file
diff --git themes/garland/style.css themes/garland/style.css
index a0ffe44..2627313 100644
--- themes/garland/style.css
+++ themes/garland/style.css
@@ -888,6 +888,13 @@ div.vertical-tabs ul.vertical-tabs-list li.selected a {
 }
 
 /**
+ * Modules form.
+ */
+#system-modules #edit-search {
+  margin-right: 5%;
+}
+
+/**
  * Syndication icons and block
  */
 #block-node-syndicate h2 {
