diff --git a/cmd/tiller/tiller.go b/cmd/tiller/tiller.go
index 9dbbd31ae86ad61589f32a5d7eac195f8513e5ff..d414524c471742197362b886359f5701aa57fc4f 100644
--- a/cmd/tiller/tiller.go
+++ b/cmd/tiller/tiller.go
@@ -25,9 +25,11 @@ import (
 	"github.com/spf13/cobra"
 	"google.golang.org/grpc"
 
-	"k8s.io/helm/cmd/tiller/environment"
+	"k8s.io/helm/pkg/proto/hapi/services"
 	"k8s.io/helm/pkg/storage"
 	"k8s.io/helm/pkg/storage/driver"
+	"k8s.io/helm/pkg/tiller"
+	"k8s.io/helm/pkg/tiller/environment"
 )
 
 const (
@@ -104,6 +106,8 @@ func start(c *cobra.Command, args []string) {
 	srvErrCh := make(chan error)
 	probeErrCh := make(chan error)
 	go func() {
+		svc := tiller.NewReleaseServer(env)
+		services.RegisterReleaseServiceServer(rootServer, svc)
 		if err := rootServer.Serve(lstn); err != nil {
 			srvErrCh <- err
 		}
diff --git a/cmd/tiller/tiller_test.go b/cmd/tiller/tiller_test.go
index 0618074d1fd8ca21c4b33734ff7c6268205b4510..0698e9d94c1de2d06bcb85e6fe530bee9bfda9bf 100644
--- a/cmd/tiller/tiller_test.go
+++ b/cmd/tiller/tiller_test.go
@@ -19,8 +19,8 @@ package main
 import (
 	"testing"
 
-	"k8s.io/helm/cmd/tiller/environment"
 	"k8s.io/helm/pkg/engine"
+	"k8s.io/helm/pkg/tiller/environment"
 )
 
 // These are canary tests to make sure that the default server actually
diff --git a/cmd/tiller/environment/environment.go b/pkg/tiller/environment/environment.go
similarity index 100%
rename from cmd/tiller/environment/environment.go
rename to pkg/tiller/environment/environment.go
diff --git a/cmd/tiller/environment/environment_test.go b/pkg/tiller/environment/environment_test.go
similarity index 100%
rename from cmd/tiller/environment/environment_test.go
rename to pkg/tiller/environment/environment_test.go
diff --git a/cmd/tiller/hooks.go b/pkg/tiller/hooks.go
similarity index 99%
rename from cmd/tiller/hooks.go
rename to pkg/tiller/hooks.go
index fab90374973de6a2de1c5e4b221767d45e0d46eb..281a234bac2e77b3199bb80462739bc444bbabaa 100644
--- a/cmd/tiller/hooks.go
+++ b/pkg/tiller/hooks.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package main
+package tiller
 
 import (
 	"fmt"
diff --git a/cmd/tiller/hooks_test.go b/pkg/tiller/hooks_test.go
similarity index 99%
rename from cmd/tiller/hooks_test.go
rename to pkg/tiller/hooks_test.go
index af25468ade86ed903aa8bf3470100bb45ccadfe3..f20a1bde6ed0e21a18da2f10c7aeca5eae0e9275 100644
--- a/cmd/tiller/hooks_test.go
+++ b/pkg/tiller/hooks_test.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package main
+package tiller
 
 import (
 	"testing"
diff --git a/cmd/tiller/kind_sorter.go b/pkg/tiller/kind_sorter.go
similarity index 99%
rename from cmd/tiller/kind_sorter.go
rename to pkg/tiller/kind_sorter.go
index 3ee4797fafc4a6aab48eab61fbbb945acc7ee24c..cebae0a52033ebfd828721961e175eb02d587680 100644
--- a/cmd/tiller/kind_sorter.go
+++ b/pkg/tiller/kind_sorter.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package main
+package tiller
 
 import (
 	"sort"
diff --git a/cmd/tiller/kind_sorter_test.go b/pkg/tiller/kind_sorter_test.go
similarity index 99%
rename from cmd/tiller/kind_sorter_test.go
rename to pkg/tiller/kind_sorter_test.go
index 46de376dd7fe0eb860e9615bb390298644a0c2cf..7b7e5f67936364b0a6494a22890b6e9c83a9fbb8 100644
--- a/cmd/tiller/kind_sorter_test.go
+++ b/pkg/tiller/kind_sorter_test.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package main
+package tiller
 
 import (
 	"testing"
diff --git a/cmd/tiller/release_history.go b/pkg/tiller/release_history.go
similarity index 93%
rename from cmd/tiller/release_history.go
rename to pkg/tiller/release_history.go
index 99bb3bb1a0979d3c34eb3f48082cd5134e9706f4..940f3e6eda5febef387d53c4dcc88ae308c811fe 100644
--- a/cmd/tiller/release_history.go
+++ b/pkg/tiller/release_history.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package main
+package tiller
 
 import (
 	"golang.org/x/net/context"
@@ -22,7 +22,7 @@ import (
 	relutil "k8s.io/helm/pkg/releaseutil"
 )
 
-func (s *releaseServer) GetHistory(ctx context.Context, req *tpb.GetHistoryRequest) (*tpb.GetHistoryResponse, error) {
+func (s *ReleaseServer) GetHistory(ctx context.Context, req *tpb.GetHistoryRequest) (*tpb.GetHistoryResponse, error) {
 	if !checkClientVersion(ctx) {
 		return nil, errIncompatibleVersion
 	}
diff --git a/cmd/tiller/release_history_test.go b/pkg/tiller/release_history_test.go
similarity index 99%
rename from cmd/tiller/release_history_test.go
rename to pkg/tiller/release_history_test.go
index 9663c6248eb80cb9b4218ebae0c384915b0036e2..75139c51fb255477e6bce31f26915d3da445753f 100644
--- a/cmd/tiller/release_history_test.go
+++ b/pkg/tiller/release_history_test.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package main
+package tiller
 
 import (
 	"reflect"
diff --git a/cmd/tiller/release_server.go b/pkg/tiller/release_server.go
similarity index 93%
rename from cmd/tiller/release_server.go
rename to pkg/tiller/release_server.go
index 17d42b66f6ea384d014d87547e6e6e14094ca782..c457ab1d7eb4298c3587107a308196b0bd6e4dd6 100644
--- a/cmd/tiller/release_server.go
+++ b/pkg/tiller/release_server.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package main
+package tiller
 
 import (
 	"bytes"
@@ -31,19 +31,17 @@ import (
 	ctx "golang.org/x/net/context"
 	"k8s.io/kubernetes/pkg/api/unversioned"
 
-	"k8s.io/helm/cmd/tiller/environment"
 	"k8s.io/helm/pkg/chartutil"
 	"k8s.io/helm/pkg/proto/hapi/chart"
 	"k8s.io/helm/pkg/proto/hapi/release"
 	"k8s.io/helm/pkg/proto/hapi/services"
 	relutil "k8s.io/helm/pkg/releaseutil"
 	"k8s.io/helm/pkg/storage/driver"
+	"k8s.io/helm/pkg/tiller/environment"
 	"k8s.io/helm/pkg/timeconv"
 	"k8s.io/helm/pkg/version"
 )
 
-var srv *releaseServer
-
 // releaseNameMaxLen is the maximum length of a release name.
 //
 // This is designed to accommodate the usage of release name in the 'name:'
@@ -57,13 +55,6 @@ const releaseNameMaxLen = 14
 // since there can be filepath in front of it.
 const notesFileSuffix = "NOTES.txt"
 
-func init() {
-	srv = &releaseServer{
-		env: env,
-	}
-	services.RegisterReleaseServiceServer(rootServer, srv)
-}
-
 var (
 	// errMissingChart indicates that a chart was not provided.
 	errMissingChart = errors.New("no chart provided")
@@ -78,10 +69,16 @@ var (
 // ListDefaultLimit is the default limit for number of items returned in a list.
 var ListDefaultLimit int64 = 512
 
-type releaseServer struct {
+type ReleaseServer struct {
 	env *environment.Environment
 }
 
+func NewReleaseServer(env *environment.Environment) *ReleaseServer {
+	return &ReleaseServer{
+		env: env,
+	}
+}
+
 func getVersion(c ctx.Context) string {
 	if md, ok := metadata.FromContext(c); ok {
 		if v, ok := md["x-helm-api-client"]; ok {
@@ -91,7 +88,7 @@ func getVersion(c ctx.Context) string {
 	return ""
 }
 
-func (s *releaseServer) ListReleases(req *services.ListReleasesRequest, stream services.ReleaseService_ListReleasesServer) error {
+func (s *ReleaseServer) ListReleases(req *services.ListReleasesRequest, stream services.ReleaseService_ListReleasesServer) error {
 	if !checkClientVersion(stream.Context()) {
 		return errIncompatibleVersion
 	}
@@ -193,7 +190,7 @@ func filterReleases(filter string, rels []*release.Release) ([]*release.Release,
 	return matches, nil
 }
 
-func (s *releaseServer) GetVersion(c ctx.Context, req *services.GetVersionRequest) (*services.GetVersionResponse, error) {
+func (s *ReleaseServer) GetVersion(c ctx.Context, req *services.GetVersionRequest) (*services.GetVersionResponse, error) {
 	v := version.GetVersionProto()
 	return &services.GetVersionResponse{Version: v}, nil
 }
@@ -203,7 +200,7 @@ func checkClientVersion(c ctx.Context) bool {
 	return version.IsCompatible(v, version.Version)
 }
 
-func (s *releaseServer) GetReleaseStatus(c ctx.Context, req *services.GetReleaseStatusRequest) (*services.GetReleaseStatusResponse, error) {
+func (s *ReleaseServer) GetReleaseStatus(c ctx.Context, req *services.GetReleaseStatusRequest) (*services.GetReleaseStatusResponse, error) {
 	if !checkClientVersion(c) {
 		return nil, errIncompatibleVersion
 	}
@@ -258,7 +255,7 @@ func (s *releaseServer) GetReleaseStatus(c ctx.Context, req *services.GetRelease
 	return statusResp, nil
 }
 
-func (s *releaseServer) GetReleaseContent(c ctx.Context, req *services.GetReleaseContentRequest) (*services.GetReleaseContentResponse, error) {
+func (s *ReleaseServer) GetReleaseContent(c ctx.Context, req *services.GetReleaseContentRequest) (*services.GetReleaseContentResponse, error) {
 	if !checkClientVersion(c) {
 		return nil, errIncompatibleVersion
 	}
@@ -275,7 +272,7 @@ func (s *releaseServer) GetReleaseContent(c ctx.Context, req *services.GetReleas
 	return &services.GetReleaseContentResponse{Release: rel}, err
 }
 
-func (s *releaseServer) UpdateRelease(c ctx.Context, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) {
+func (s *ReleaseServer) UpdateRelease(c ctx.Context, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) {
 	if !checkClientVersion(c) {
 		return nil, errIncompatibleVersion
 	}
@@ -299,7 +296,7 @@ func (s *releaseServer) UpdateRelease(c ctx.Context, req *services.UpdateRelease
 	return res, nil
 }
 
-func (s *releaseServer) performUpdate(originalRelease, updatedRelease *release.Release, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) {
+func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.Release, req *services.UpdateReleaseRequest) (*services.UpdateReleaseResponse, error) {
 	res := &services.UpdateReleaseResponse{Release: updatedRelease}
 
 	if req.DryRun {
@@ -341,7 +338,7 @@ func (s *releaseServer) performUpdate(originalRelease, updatedRelease *release.R
 // reuseValues copies values from the current release to a new release if the new release does not have any values.
 //
 // If the request already has values, or if there are no values in the current release, this does nothing.
-func (s *releaseServer) reuseValues(req *services.UpdateReleaseRequest, current *release.Release) {
+func (s *ReleaseServer) reuseValues(req *services.UpdateReleaseRequest, current *release.Release) {
 	if (req.Values == nil || req.Values.Raw == "") && current.Config != nil && current.Config.Raw != "" {
 		log.Printf("Copying values from %s (v%d) to new release.", current.Name, current.Version)
 		req.Values = current.Config
@@ -349,7 +346,7 @@ func (s *releaseServer) reuseValues(req *services.UpdateReleaseRequest, current
 }
 
 // prepareUpdate builds an updated release for an update operation.
-func (s *releaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*release.Release, *release.Release, error) {
+func (s *ReleaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*release.Release, *release.Release, error) {
 	if req.Name == "" {
 		return nil, nil, errMissingRelease
 	}
@@ -406,7 +403,7 @@ func (s *releaseServer) prepareUpdate(req *services.UpdateReleaseRequest) (*rele
 	return currentRelease, updatedRelease, nil
 }
 
-func (s *releaseServer) RollbackRelease(c ctx.Context, req *services.RollbackReleaseRequest) (*services.RollbackReleaseResponse, error) {
+func (s *ReleaseServer) RollbackRelease(c ctx.Context, req *services.RollbackReleaseRequest) (*services.RollbackReleaseResponse, error) {
 	if !checkClientVersion(c) {
 		return nil, errIncompatibleVersion
 	}
@@ -430,7 +427,7 @@ func (s *releaseServer) RollbackRelease(c ctx.Context, req *services.RollbackRel
 	return res, nil
 }
 
-func (s *releaseServer) performRollback(currentRelease, targetRelease *release.Release, req *services.RollbackReleaseRequest) (*services.RollbackReleaseResponse, error) {
+func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.Release, req *services.RollbackReleaseRequest) (*services.RollbackReleaseResponse, error) {
 	res := &services.RollbackReleaseResponse{Release: targetRelease}
 
 	if req.DryRun {
@@ -469,7 +466,7 @@ func (s *releaseServer) performRollback(currentRelease, targetRelease *release.R
 	return res, nil
 }
 
-func (s *releaseServer) performKubeUpdate(currentRelease, targetRelease *release.Release) error {
+func (s *ReleaseServer) performKubeUpdate(currentRelease, targetRelease *release.Release) error {
 	kubeCli := s.env.KubeClient
 	current := bytes.NewBufferString(currentRelease.Manifest)
 	target := bytes.NewBufferString(targetRelease.Manifest)
@@ -478,7 +475,7 @@ func (s *releaseServer) performKubeUpdate(currentRelease, targetRelease *release
 
 // prepareRollback finds the previous release and prepares a new release object with
 //  the previous release's configuration
-func (s *releaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*release.Release, *release.Release, error) {
+func (s *ReleaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*release.Release, *release.Release, error) {
 	switch {
 	case req.Name == "":
 		return nil, nil, errMissingRelease
@@ -532,7 +529,7 @@ func (s *releaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*
 	return crls, target, nil
 }
 
-func (s *releaseServer) uniqName(start string, reuse bool) (string, error) {
+func (s *ReleaseServer) uniqName(start string, reuse bool) (string, error) {
 
 	// If a name is supplied, we check to see if that name is taken. If not, it
 	// is granted. If reuse is true and a deleted release with that name exists,
@@ -577,7 +574,7 @@ func (s *releaseServer) uniqName(start string, reuse bool) (string, error) {
 	return "ERROR", errors.New("no available release name found")
 }
 
-func (s *releaseServer) engine(ch *chart.Chart) environment.Engine {
+func (s *ReleaseServer) engine(ch *chart.Chart) environment.Engine {
 	renderer := s.env.EngineYard.Default()
 	if ch.Metadata.Engine != "" {
 		if r, ok := s.env.EngineYard.Get(ch.Metadata.Engine); ok {
@@ -589,7 +586,7 @@ func (s *releaseServer) engine(ch *chart.Chart) environment.Engine {
 	return renderer
 }
 
-func (s *releaseServer) InstallRelease(c ctx.Context, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
+func (s *ReleaseServer) InstallRelease(c ctx.Context, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
 	if !checkClientVersion(c) {
 		return nil, errIncompatibleVersion
 	}
@@ -608,7 +605,7 @@ func (s *releaseServer) InstallRelease(c ctx.Context, req *services.InstallRelea
 }
 
 // prepareRelease builds a release for an install operation.
-func (s *releaseServer) prepareRelease(req *services.InstallReleaseRequest) (*release.Release, error) {
+func (s *ReleaseServer) prepareRelease(req *services.InstallReleaseRequest) (*release.Release, error) {
 	if req.Chart == nil {
 		return nil, errMissingChart
 	}
@@ -651,7 +648,7 @@ func (s *releaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re
 	return rel, nil
 }
 
-func (s *releaseServer) getVersionSet() (versionSet, error) {
+func (s *ReleaseServer) getVersionSet() (versionSet, error) {
 	defVersions := newVersionSet("v1")
 	cli, err := s.env.KubeClient.APIClient()
 	if err != nil {
@@ -676,7 +673,7 @@ func (s *releaseServer) getVersionSet() (versionSet, error) {
 	return newVersionSet(versions...), nil
 }
 
-func (s *releaseServer) renderResources(ch *chart.Chart, values chartutil.Values) ([]*release.Hook, *bytes.Buffer, string, error) {
+func (s *ReleaseServer) renderResources(ch *chart.Chart, values chartutil.Values) ([]*release.Hook, *bytes.Buffer, string, error) {
 	renderer := s.engine(ch)
 	files, err := renderer.Render(ch, values)
 	if err != nil {
@@ -723,7 +720,7 @@ func (s *releaseServer) renderResources(ch *chart.Chart, values chartutil.Values
 	return hooks, b, notes, nil
 }
 
-func (s *releaseServer) recordRelease(r *release.Release, reuse bool) {
+func (s *ReleaseServer) recordRelease(r *release.Release, reuse bool) {
 	if reuse {
 		if err := s.env.Releases.Update(r); err != nil {
 			log.Printf("warning: Failed to update release %q: %s", r.Name, err)
@@ -734,7 +731,7 @@ func (s *releaseServer) recordRelease(r *release.Release, reuse bool) {
 }
 
 // performRelease runs a release.
-func (s *releaseServer) performRelease(r *release.Release, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
+func (s *ReleaseServer) performRelease(r *release.Release, req *services.InstallReleaseRequest) (*services.InstallReleaseResponse, error) {
 	res := &services.InstallReleaseResponse{Release: r}
 
 	if req.DryRun {
@@ -810,7 +807,7 @@ func (s *releaseServer) performRelease(r *release.Release, req *services.Install
 	return res, nil
 }
 
-func (s *releaseServer) execHook(hs []*release.Hook, name, namespace, hook string) error {
+func (s *ReleaseServer) execHook(hs []*release.Hook, name, namespace, hook string) error {
 	kubeCli := s.env.KubeClient
 	code, ok := events[hook]
 	if !ok {
@@ -848,7 +845,7 @@ func (s *releaseServer) execHook(hs []*release.Hook, name, namespace, hook strin
 	return nil
 }
 
-func (s *releaseServer) purgeReleases(rels ...*release.Release) error {
+func (s *ReleaseServer) purgeReleases(rels ...*release.Release) error {
 	for _, rel := range rels {
 		if _, err := s.env.Releases.Delete(rel.Name, rel.Version); err != nil {
 			return err
@@ -857,7 +854,7 @@ func (s *releaseServer) purgeReleases(rels ...*release.Release) error {
 	return nil
 }
 
-func (s *releaseServer) UninstallRelease(c ctx.Context, req *services.UninstallReleaseRequest) (*services.UninstallReleaseResponse, error) {
+func (s *ReleaseServer) UninstallRelease(c ctx.Context, req *services.UninstallReleaseRequest) (*services.UninstallReleaseResponse, error) {
 	if !checkClientVersion(c) {
 		return nil, errIncompatibleVersion
 	}
diff --git a/cmd/tiller/release_server_test.go b/pkg/tiller/release_server_test.go
similarity index 99%
rename from cmd/tiller/release_server_test.go
rename to pkg/tiller/release_server_test.go
index c4b64f72451d93513b121dd048423226b5255bed..a17638be33dde192bf38c376dfadaf31ae2b8e2e 100644
--- a/cmd/tiller/release_server_test.go
+++ b/pkg/tiller/release_server_test.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package main
+package tiller
 
 import (
 	"errors"
@@ -29,13 +29,13 @@ import (
 	"golang.org/x/net/context"
 	"google.golang.org/grpc/metadata"
 
-	"k8s.io/helm/cmd/tiller/environment"
 	"k8s.io/helm/pkg/helm"
 	"k8s.io/helm/pkg/proto/hapi/chart"
 	"k8s.io/helm/pkg/proto/hapi/release"
 	"k8s.io/helm/pkg/proto/hapi/services"
 	"k8s.io/helm/pkg/storage"
 	"k8s.io/helm/pkg/storage/driver"
+	"k8s.io/helm/pkg/tiller/environment"
 )
 
 const notesText = "my notes here"
@@ -70,8 +70,8 @@ data:
   name: value
 `
 
-func rsFixture() *releaseServer {
-	return &releaseServer{
+func rsFixture() *ReleaseServer {
+	return &ReleaseServer{
 		env: mockEnvironment(),
 	}
 }