diff --git a/uc_product/uc_product.admin.inc b/uc_product/uc_product.admin.inc
index fbdfcb8..534c7ea 100644
--- a/uc_product/uc_product.admin.inc
+++ b/uc_product/uc_product.admin.inc
@@ -40,14 +40,14 @@ function uc_product_administration() {
  * Display a list of product classes.
  */
 function uc_product_class_default() {
-  $result = db_query("SELECT * FROM {uc_product_classes}");
+  $classes = uc_product_class_load();
   $header = array(t('Class ID'), t('Name'), t('Description'), t('Operations'));
   $rows = array();
-  while ($class = db_fetch_object($result)) {
-    $ops = array(
-      l(t('edit'), 'admin/store/products/classes/'. $class->pcid .'/edit'),
-      l(t('delete'), 'admin/store/products/classes/'. $class->pcid .'/delete'),
-    );
+  foreach ($classes as $class) {
+    $ops = array(l(t('edit'), 'admin/store/products/classes/'. $class->pcid .'/edit'));
+    if (empty($class->locked)) {
+      $ops[] = l(t('delete'), 'admin/store/products/classes/'. $class->pcid .'/delete');
+    }
     $rows[] = array(
       $class->pcid,
       $class->name,
diff --git a/uc_product/uc_product.features.inc b/uc_product/uc_product.features.inc
new file mode 100644
index 0000000..9b725b9
--- /dev/null
+++ b/uc_product/uc_product.features.inc
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * @file
+ * Features integration for Ubercart product classes.
+ */
+
+/**
+ * Implementation of hook_features_export_options().
+ */
+function uc_product_classes_features_export_options() {
+  $classes = array();
+  foreach (uc_product_node_info() as $type => $info) {
+    $classes[$type] = $info['name'];
+  }
+  return $classes;
+}
+
+/**
+ * Implementation of hook_features_export().
+ */
+function uc_product_classes_features_export($data, &$export, $module_name = '') {
+  $export['dependencies']['uc_product'] = 'uc_product';
+  foreach ($data as $class) {
+    $export['features']['uc_product_classes'][$class] = $class;
+  }
+
+  // Run the node type exporter to grab CCK fields and variables.
+  return array('node' => $data);
+}
+
+/**
+ * Implementation of hook_features_export_render().
+ */
+function uc_product_classes_features_export_render($module, $data, $export = NULL) {
+  $output = node_features_export_render($module, $data, $export);
+  return array('uc_product_default_classes' => $output['node_info']);
+}
+
+/**
+ * Implementation of hook_features_revert().
+ *
+ * @see node_features_revert()
+ */
+function uc_product_classes_features_revert($module) {
+  if ($default_types = features_get_default('uc_product_classes', $module)) {
+    foreach ($default_types as $type_name => $type_info) {
+      // We need to de-activate any missing fields. De-activating allows us to
+      // preserve data. We de-activate by setting the widget_active flag to 0;
+      // widget_active is incorrectly named, and really should be
+      // instance_active
+      if (module_exists('content')) {
+        // Our existing fields ($fields) needs to be the first argument here,
+        // so only fields that don't exist in code can be de-activated.
+        if ($deleted_fields = array_diff(content_features_fields_normal($type_name), content_features_fields_default($type_name))) {
+          foreach($deleted_fields as $field_name) {
+            db_query("UPDATE {". content_instance_tablename() ."} SET widget_active = 0 WHERE field_name = '%s' AND type_name = '%s'", $field_name, $type_name);
+          }
+        }
+      }
+      // Delete node types
+      // We don't use node_type_delete() because we do not actually
+      // want to delete the node type (and invoke hook_node_type()).
+      // This can lead to bad consequences like CCK deleting field
+      // storage in the DB.
+      db_query("DELETE FROM {node_type} WHERE type = '%s'", $type_name);
+      db_query("DELETE FROM {uc_product_classes} WHERE pcid = '%s'", $type_name);
+    }
+    uc_product_node_info(TRUE);
+    node_types_rebuild();
+    menu_rebuild();
+  }
+}
diff --git a/uc_product/uc_product.module b/uc_product/uc_product.module
index 5575c1a..a657ad9 100644
--- a/uc_product/uc_product.module
+++ b/uc_product/uc_product.module
@@ -136,7 +136,8 @@ function uc_product_menu() {
     'file' => 'uc_product.admin.inc',
   );
   $items['admin/store/products/classes/%uc_product_class/delete'] = array(
-    'access arguments' => array('administer product classes'),
+    'access callback' => 'uc_product_class_delete_access',
+    'access arguments' => array(4),
     'page callback' => 'drupal_get_form',
     'page arguments' => array('uc_product_class_delete_confirm', 4),
     'type' => MENU_CALLBACK,
@@ -233,6 +234,13 @@ function uc_product_feature_access($node) {
 }
 
 /**
+ * Menu access callback for 'admin/store/products/classes/%uc_product_class/delete'.
+ */
+function uc_product_class_delete_access($class) {
+  return user_access('administer product classes') && !$class->locked;
+}
+
+/**
  * Implementation of hook_init().
  */
 function uc_product_init() {
@@ -338,7 +346,10 @@ function uc_product_node_info($reset = FALSE) {
 
   if (empty($types) || $reset) {
     $types = array();
-    $types['product'] = array(
+
+    $defaults = module_invoke_all('uc_product_default_classes');
+    $types['product'] = isset($defaults['product']) ? $defaults['product'] : array();
+    $types['product'] += array(
       'name' => t('Product'),
       'module' => 'uc_product',
       'description' => t('This node displays the representation of a product for sale on the website. It includes all the unique information that can be attributed to a specific model number.'),
@@ -346,12 +357,11 @@ function uc_product_node_info($reset = FALSE) {
       'body_label' => $body_label,
     );
 
-    $result = db_query("SELECT pcid, name, description FROM {uc_product_classes}");
-    while ($class = db_fetch_object($result)) {
-      $types[$class->pcid] = array(
-        'name' => $class->name,
-        'module' => 'uc_product',
-        'description' => $class->description,
+    $classes = uc_product_class_load(NULL, $reset);
+    foreach ($classes as $class) {
+      $class = (array) $class;
+      $class['module'] = 'uc_product';
+      $types[$class['pcid']] = $class + array(
         'title_label' => $title_label,
         'body_label' => $body_label,
       );
@@ -1905,18 +1915,43 @@ function uc_product_get_description($product) {
 }
 
 /**
- * Load a product class.
+ * Load a product class, or all classes.
  */
-function uc_product_class_load($class_id) {
-  static $classes = array();
+function uc_product_class_load($class_id = NULL, $reset = FALSE) {
+  static $classes;
+
+  if ($reset || !isset($classes)) {
+    // Load classes from database.
+    $classes = array();
+    $result = db_query("SELECT * FROM {uc_product_classes}");
+    while ($class = db_fetch_object($result)) {
+      $classes[$class->pcid] = $class;
+    }
+
+    // Merge any module-defined classes.
+    foreach (module_invoke_all('uc_product_default_classes') as $pcid => $class) {
+      $class += array(
+        'pcid' => $pcid,
+        'name' => $pcid,
+        'description' => '',
+      );
 
-  if (empty($classes[$class_id])) {
-    $result = db_query("SELECT * FROM {uc_product_classes} WHERE pcid = '%s'", $class_id);
-    $class = db_fetch_object($result);
-    $classes[$class_id] = $class;
+      if (isset($classes[$pcid])) {
+        // Merge defaults with the existing database info.
+        $classes[$pcid] = (object) array_merge($class, (array) $classes[$pcid]);
+      }
+      else {
+        // Ensure the class info is saved in the database.
+        drupal_write_record('uc_product_classes', $class);
+        $classes[$pcid] = (object) $class;
+      }
+
+      // Module-defined classes cannot be deleted.
+      $classes[$pcid]->locked = TRUE;
+    }
   }
 
-  return $classes[$class_id];
+  return is_null($class_id) ? $classes : $classes[$class_id];
 }
 
 /**
@@ -2239,3 +2274,17 @@ function uc_product_views_api() {
     'path' => drupal_get_path('module', 'uc_product') .'/views',
   );
 }
+
+/**
+ * Implementation of hook_features_api().
+ */
+function uc_product_features_api() {
+  return array(
+    'uc_product_classes' => array(
+      'name' => t('Ubercart product classes'),
+      'feature_source' => TRUE,
+      'default_hook' => 'uc_product_default_classes',
+      'file' => drupal_get_path('module', 'uc_product') .'/uc_product.features.inc',
+    ),
+  );
+}
