diff --git a/cmd/helm/install.go b/cmd/helm/install.go
index ec16146921db4c327cae7d509b0f322a00f3d8b5..3f7d701f1d966140d7b156b0c11d4cfdeeb01711 100644
--- a/cmd/helm/install.go
+++ b/cmd/helm/install.go
@@ -54,12 +54,13 @@ func runInstall(cmd *cobra.Command, args []string) error {
 // 		   Might be friendly to wrap our proto model with pretty-printers.
 //
 func printRelease(rel *release.Release) {
+	if rel == nil {
+		return
+	}
+	fmt.Printf("release.name:   %s\n", rel.Name)
 	if verbose {
-		if rel != nil {
-			fmt.Printf("release.name:   %s\n", rel.Name)
-			fmt.Printf("release.info:   %s\n", rel.GetInfo())
-			fmt.Printf("release.chart:  %s\n", rel.GetChart())
-		}
+		fmt.Printf("release.info:   %s\n", rel.GetInfo())
+		fmt.Printf("release.chart:  %s\n", rel.GetChart())
 	}
 }
 
diff --git a/cmd/helm/list.go b/cmd/helm/list.go
new file mode 100644
index 0000000000000000000000000000000000000000..19e9f6c9e46a897716c01fd091e211d068c06b26
--- /dev/null
+++ b/cmd/helm/list.go
@@ -0,0 +1,111 @@
+package main
+
+import (
+	"fmt"
+	"sort"
+	"time"
+
+	"github.com/gosuri/uitable"
+	"github.com/kubernetes/helm/pkg/helm"
+	"github.com/kubernetes/helm/pkg/proto/hapi/release"
+	"github.com/kubernetes/helm/pkg/timeconv"
+	"github.com/spf13/cobra"
+)
+
+var listHelp = `
+This command lists all of the currently deployed releases.
+
+By default, items are sorted alphabetically. Sorting is done client-side, so if
+the number of releases is less than the setting in '--max', some values will
+be omitted, and in no particular lexicographic order.
+`
+
+var listCommand = &cobra.Command{
+	Use:     "list [flags]",
+	Short:   "List releases",
+	Long:    listHelp,
+	RunE:    listCmd,
+	Aliases: []string{"ls"},
+}
+
+var listLong bool
+var listMax int
+var listOffset int
+var listByDate bool
+
+func init() {
+	listCommand.Flags().BoolVarP(&listLong, "long", "l", false, "output long listing format")
+	listCommand.Flags().BoolVarP(&listByDate, "date", "d", false, "sort by release date")
+	listCommand.Flags().IntVarP(&listMax, "max", "m", 256, "maximum number of releases to fetch")
+	listCommand.Flags().IntVarP(&listOffset, "offset", "o", 0, "offset from start value (zero-indexed)")
+	RootCommand.AddCommand(listCommand)
+}
+
+func listCmd(cmd *cobra.Command, args []string) error {
+	if len(args) > 0 {
+		fmt.Println("TODO: Implement filter.")
+	}
+
+	res, err := helm.ListReleases(listMax, listOffset)
+	if err != nil {
+		return err
+	}
+
+	rels := res.Releases
+	if res.Count+res.Offset < res.Total {
+		fmt.Println("Not all values were fetched.")
+	}
+
+	if listByDate {
+		sort.Sort(byDate(rels))
+	} else {
+		sort.Sort(byName(rels))
+	}
+
+	// Purty output, ya'll
+	if listLong {
+		return formatList(rels)
+	}
+	for _, r := range rels {
+		fmt.Println(r.Name)
+	}
+
+	return nil
+}
+
+func formatList(rels []*release.Release) error {
+	table := uitable.New()
+	table.MaxColWidth = 30
+	table.AddRow("NAME", "UPDATED", "CHART")
+	for _, r := range rels {
+		c := fmt.Sprintf("%s-%s", r.Chart.Metadata.Name, r.Chart.Metadata.Version)
+		t := timeconv.Format(r.Info.LastDeployed, time.ANSIC)
+		table.AddRow(r.Name, t, c)
+	}
+	fmt.Println(table)
+
+	return nil
+}
+
+// byName implements the sort.Interface for []*release.Release.
+type byName []*release.Release
+
+func (r byName) Len() int {
+	return len(r)
+}
+func (r byName) Swap(p, q int) {
+	r[p], r[q] = r[q], r[p]
+}
+func (r byName) Less(i, j int) bool {
+	return r[i].Name < r[j].Name
+}
+
+type byDate []*release.Release
+
+func (r byDate) Len() int { return len(r) }
+func (r byDate) Swap(p, q int) {
+	r[p], r[q] = r[q], r[p]
+}
+func (r byDate) Less(p, q int) bool {
+	return r[p].Info.LastDeployed.Seconds < r[q].Info.LastDeployed.Seconds
+}
diff --git a/cmd/tiller/release_server.go b/cmd/tiller/release_server.go
index 68f37daf481d4fb20dccea0336cd3de26f23ff03..2333b3c2b57cfcc7214af7c3cca62e632b53d3fc 100644
--- a/cmd/tiller/release_server.go
+++ b/cmd/tiller/release_server.go
@@ -3,6 +3,7 @@ package main
 import (
 	"bytes"
 	"errors"
+	"fmt"
 	"log"
 
 	"github.com/kubernetes/helm/cmd/tiller/environment"
@@ -33,8 +34,43 @@ var (
 	errMissingRelease = errors.New("no release provided")
 )
 
+// ListDefaultLimit is the default limit for number of items returned in a list.
+var ListDefaultLimit int64 = 512
+
 func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream services.ReleaseService_ListReleasesServer) error {
-	return errNotImplemented
+	rels, err := s.env.Releases.List()
+	if err != nil {
+		return err
+	}
+
+	total := int64(len(rels))
+
+	l := int64(len(rels))
+	if req.Offset > 0 {
+		if req.Offset >= l {
+			return fmt.Errorf("offset %d is outside of range %d", req.Offset, l)
+		}
+		rels = rels[req.Offset:]
+		l = int64(len(rels))
+	}
+
+	if req.Limit == 0 {
+		req.Limit = ListDefaultLimit
+	}
+
+	if l > req.Limit {
+		rels = rels[0:req.Limit]
+		l = int64(len(rels))
+	}
+
+	res := &services.ListReleasesResponse{
+		Offset:   0,
+		Count:    l,
+		Total:    total,
+		Releases: rels,
+	}
+	stream.Send(res)
+	return nil
 }
 
 func (s *releaseServer) GetReleaseStatus(c ctx.Context, req *services.GetReleaseStatusRequest) (*services.GetReleaseStatusResponse, error) {
diff --git a/cmd/tiller/release_server_test.go b/cmd/tiller/release_server_test.go
index 53d51c505b8e57a9cf9815a805c255a5938959c5..f76e3d91ecc0e9ed5cb6ffe20b8897f37433b228 100644
--- a/cmd/tiller/release_server_test.go
+++ b/cmd/tiller/release_server_test.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"fmt"
 	"strings"
 	"testing"
 
@@ -12,6 +13,7 @@ import (
 	"github.com/kubernetes/helm/pkg/storage"
 	"github.com/kubernetes/helm/pkg/timeconv"
 	"golang.org/x/net/context"
+	"google.golang.org/grpc/metadata"
 )
 
 func rsFixture() *releaseServer {
@@ -193,8 +195,44 @@ func TestGetReleaseStatus(t *testing.T) {
 	}
 }
 
+func TestListReleases(t *testing.T) {
+	rs := rsFixture()
+	num := 7
+	for i := 0; i < num; i++ {
+		rel := releaseMock()
+		rel.Name = fmt.Sprintf("rel-%d", i)
+		if err := rs.env.Releases.Create(rel); err != nil {
+			t.Fatalf("Could not store mock release: %s", err)
+		}
+	}
+
+	mrs := &mockListServer{}
+	if err := rs.ListReleases(&services.ListReleasesRequest{Offset: 0, Limit: 64}, mrs); err != nil {
+		t.Fatalf("Failed listing: %s", err)
+	}
+
+	if len(mrs.val.Releases) != num {
+		t.Errorf("Expected %d releases, got %d", num, len(mrs.val.Releases))
+	}
+}
+
 func mockEnvironment() *environment.Environment {
 	e := environment.New()
 	e.Releases = storage.NewMemory()
 	return e
 }
+
+type mockListServer struct {
+	val *services.ListReleasesResponse
+}
+
+func (l *mockListServer) Send(res *services.ListReleasesResponse) error {
+	l.val = res
+	return nil
+}
+
+func (l *mockListServer) Context() context.Context       { return context.TODO() }
+func (l *mockListServer) SendMsg(v interface{}) error    { return nil }
+func (l *mockListServer) RecvMsg(v interface{}) error    { return nil }
+func (l *mockListServer) SendHeader(m metadata.MD) error { return nil }
+func (l *mockListServer) SetTrailer(m metadata.MD)       {}
diff --git a/docs/examples/alpine/Chart.yaml b/docs/examples/alpine/Chart.yaml
index 0e86771b38ad35a147dcdb09e0d92082f3b5507a..cab858d0a2ecd178ea3a190f08dcb128378e9a6e 100644
--- a/docs/examples/alpine/Chart.yaml
+++ b/docs/examples/alpine/Chart.yaml
@@ -1,4 +1,4 @@
 name: alpine
 description: Deploy a basic Alpine Linux pod
 version: 0.1.0
-home: "https://github.com/kubernetes/helm"
+home: https://github.com/kubernetes/helm
diff --git a/pkg/helm/helm.go b/pkg/helm/helm.go
index 8a5913bb24954d1a67a14da4660eeeec9e1610bd..4b366e85f0a7ba28e2e2d99c41dbe382431d82b4 100644
--- a/pkg/helm/helm.go
+++ b/pkg/helm/helm.go
@@ -13,8 +13,23 @@ var Config = &config{
 }
 
 // ListReleases lists the current releases.
-func ListReleases(limit, offset int) (<-chan *services.ListReleasesResponse, error) {
-	return nil, ErrNotImplemented
+func ListReleases(limit, offset int) (*services.ListReleasesResponse, error) {
+	c := Config.client()
+	if err := c.dial(); err != nil {
+		return nil, err
+	}
+	defer c.Close()
+
+	req := &services.ListReleasesRequest{
+		Limit:  int64(limit),
+		Offset: int64(offset),
+	}
+	cli, err := c.impl.ListReleases(context.TODO(), req, c.cfg.CallOpts()...)
+	if err != nil {
+		return nil, err
+	}
+
+	return cli.Recv()
 }
 
 // GetReleaseStatus returns the given release's status.