diff --git a/README.md b/README.md
index 822a72878775f98e5501b450bcb0a633ad117e52..9f5c729d5db02cf2b92da906b3911c45068f9894 100644
--- a/README.md
+++ b/README.md
@@ -12,14 +12,15 @@ It is a Dart project scaffolding generator, inspired by tools like Web Starter
 Kit and Yeoman.
 
 ## Things you can create with Stagehand
-
-* package - a starting point for Dart libraries or applications
-* consoleapp - a simple command-line application
-* polymerapp - a web app built using polymer.dart
-* ubersimplewebapp - an absolute bare-bones web app
-* webapp - a mobile-friendly web app with routing, responsive CSS, and (optional) Sass support
-* appengineapp - a simple AppEngine application
-* server-shelf - a web server built using the shelf package
+<!-- template-list -->
+* `appengineapp` - A simple AppEngine application.
+* `consoleapp` - A simple command-line application.
+* `package` - A starting point for Dart libraries or applications.
+* `polymerapp` - A web app built using polymer.dart.
+* `server-shelf` - A web server built using the shelf package.
+* `ubersimplewebapp` - An absolute bare-bones web app.
+* `webapp` - A mobile-friendly web app with routing, responsive CSS, and (optional) Sass support.
+<!-- template-list -->
 
 ## Installation
 
diff --git a/lib/stagehand.dart b/lib/stagehand.dart
index de49c6efb362c0b4a87965184ea3f5617fd66016..4c7955fe8b0a5e3e576bf451d541098e72cd869c 100644
--- a/lib/stagehand.dart
+++ b/lib/stagehand.dart
@@ -43,7 +43,7 @@ final List<Generator> generators = [
   new ShelfGenerator(),
   new WebAppGenerator(),
   new UberSimpleWebAppGenerator()
-];
+]..sort();
 
 Generator getGenerator(String id) {
   return generators.firstWhere((g) => g.id == id, orElse: () => null);
diff --git a/site/index.html b/site/index.html
index c5cead3f9973f4bfeacec90bbb5bfe897d4f8bdd..f6aeef6c2d30aafee30ee0c01c10329441ded465 100644
--- a/site/index.html
+++ b/site/index.html
@@ -90,15 +90,15 @@ $ stagehand webapp
 
       <p>Stagehand contains a highly curated list of templates:</p>
 
-      <ul>
-      <li>appengineapp - <em>a simple AppEngine application</em></li>
-      <li>consoleapp - <em>a simple command-line application</em></li>
-      <li>package - <em>a starting point for Dart libraries or applications</em></li>
-      <li>polymerapp - <em>a web app built using polymer.dart</em></li>
-      <li>server-shelf - <em>a web server built using the shelf package</em></li>
-      <li>ubersimplewebapp - <em>an absolute bare-bones web app</em></li>
-      <li>webapp - <em>a mobile-friendly web app</em></li>
-      </ul>
+<ul id="template-list">
+  <li>appengineapp - <em>A simple AppEngine application.</em></li>
+  <li>consoleapp - <em>A simple command-line application.</em></li>
+  <li>package - <em>A starting point for Dart libraries or applications.</em></li>
+  <li>polymerapp - <em>A web app built using polymer.dart.</em></li>
+  <li>server-shelf - <em>A web server built using the shelf package.</em></li>
+  <li>ubersimplewebapp - <em>An absolute bare-bones web app.</em></li>
+  <li>webapp - <em>A mobile-friendly web app with routing, responsive CSS, and (optional) Sass support.</em></li>
+</ul>
 
     </div> <!-- /container -->
 
diff --git a/tool/grind.dart b/tool/grind.dart
index 05e98895d42edcaf66afee3d8017b11b6b11b40c..6598cb09d5debd0f87a2b2a78abae34fbb6ed1d8 100644
--- a/tool/grind.dart
+++ b/tool/grind.dart
@@ -45,6 +45,34 @@ void buildTemplates(GrinderContext context) {
         getDir('templates/${generator.id}'),
         getFile('lib/generators/${generator.id.replaceAll('-', '_')}_data.dart'));
   });
+
+  // Update the readme.md file.
+  File f = getFile('README.md');
+  String source = f.readAsStringSync();
+  String fragment = stagehand.generators.map((g) {
+    return '* `${g.id}` - ${g.description}';
+  }).join('\n');
+  String newSource = _replaceInString(
+      context,
+      source,
+      '<!-- template-list -->',
+      '<!-- template-list -->',
+      fragment);
+  f.writeAsStringSync(newSource);
+
+  // Update the site/index.html file.
+  f = getFile('site/index.html');
+  source = f.readAsStringSync();
+  fragment = stagehand.generators.map((g) {
+    return '  <li>${g.id} - <em>${g.description}</em></li>';
+  }).join('\n');
+  newSource = _replaceInString(
+      context,
+      source,
+      '<ul id="template-list">',
+      '</ul>',
+      fragment);
+  f.writeAsStringSync(newSource);
 }
 
 /**
@@ -190,3 +218,20 @@ List<FileSystemEntity> _listSync(Directory dir,
   results.sort((entity1, entity2) => entity1.path.compareTo(entity2.path));
   return results;
 }
+
+/// Look for [start] and [end] in [source]; replace the current contents with
+/// [replacement], and return the result.
+String _replaceInString(GrinderContext context, String source, String start,
+    String end, String replacement) {
+  int startIndex = source.indexOf(start);
+  int endIndex = source.indexOf(end, startIndex + 1);
+
+  if (startIndex == -1 || endIndex == -1) {
+    context.fail('Could not find text to replace');
+  }
+
+  return source.substring(0, startIndex + start.length + 1) +
+      replacement +
+      '\n' +
+      source.substring(endIndex);
+}