diff --git a/cmd/gonew/main.go b/cmd/gonew/main.go
new file mode 100644
index 0000000..920d56a
--- /dev/null
+++ b/cmd/gonew/main.go
@@ -0,0 +1,233 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Gonew starts a new Go module by copying a template module.
+//
+// Usage:
+//
+//	gonew srcmod[@version] [dstmod [dir]]
+//
+// Gonew makes a copy of the srcmod module, changing its module path to dstmod.
+// It writes that new module to a new directory named by dir.
+// If dir already exists, it must be an empty directory.
+// If dir is omitted, gonew uses ./elem where elem is the final path element of dstmod.
+//
+// This command is highly experimental and subject to change.
+//
+// # Example
+//
+// To install gonew:
+//
+//	go install golang.org/x/tools/cmd/gonew@latest
+//
+// To clone the basic command-line program template golang.org/x/example/hello
+// as your.domain/myprog, in the directory ./myprog:
+//
+//	gonew golang.org/x/example/hello your.domain/myprog
+//
+// To clone the latest copy of the rsc.io/quote module, keeping that module path,
+// into ./quote:
+//
+//	gonew rsc.io/quote
+package main
+
+import (
+	"bytes"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"go/parser"
+	"go/token"
+	"io/fs"
+	"log"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"strconv"
+	"strings"
+
+	"golang.org/x/mod/modfile"
+	"golang.org/x/mod/module"
+	"golang.org/x/tools/internal/edit"
+)
+
+func usage() {
+	fmt.Fprintf(os.Stderr, "usage: gonew srcmod[@version] [dstmod [dir]]\n")
+	fmt.Fprintf(os.Stderr, "See https://pkg.go.dev/golang.org/x/tools/cmd/gonew.\n")
+	os.Exit(2)
+}
+
+func main() {
+	log.SetPrefix("gonew: ")
+	log.SetFlags(0)
+	flag.Usage = usage
+	flag.Parse()
+	args := flag.Args()
+
+	if len(args) < 1 || len(args) > 3 {
+		usage()
+	}
+
+	srcMod := args[0]
+	srcModVers := srcMod
+	if !strings.Contains(srcModVers, "@") {
+		srcModVers += "@latest"
+	}
+	srcMod, _, _ = strings.Cut(srcMod, "@")
+	if err := module.CheckPath(srcMod); err != nil {
+		log.Fatalf("invalid source module name: %v", err)
+	}
+
+	dstMod := srcMod
+	if len(args) >= 2 {
+		dstMod = args[1]
+		if err := module.CheckPath(dstMod); err != nil {
+			log.Fatalf("invalid destination module name: %v", err)
+		}
+	}
+
+	var dir string
+	if len(args) == 3 {
+		dir = args[2]
+	} else {
+		dir = "." + string(filepath.Separator) + path.Base(dstMod)
+	}
+
+	// Dir must not exist or must be an empty directory.
+	de, err := os.ReadDir(dir)
+	if err == nil && len(de) > 0 {
+		log.Fatalf("target directory %s exists and is non-empty", dir)
+	}
+	needMkdir := err != nil
+
+	var stdout, stderr bytes.Buffer
+	cmd := exec.Command("go", "mod", "download", "-json", srcModVers)
+	cmd.Stdout = &stdout
+	cmd.Stderr = &stderr
+	if err := cmd.Run(); err != nil {
+		log.Fatalf("go mod download -json %s: %v\n%s%s", srcModVers, err, stderr.Bytes(), stdout.Bytes())
+	}
+
+	var info struct {
+		Dir string
+	}
+	if err := json.Unmarshal(stdout.Bytes(), &info); err != nil {
+		log.Fatalf("go mod download -json %s: invalid JSON output: %v\n%s%s", srcMod, err, stderr.Bytes(), stdout.Bytes())
+	}
+
+	if needMkdir {
+		if err := os.MkdirAll(dir, 0777); err != nil {
+			log.Fatal(err)
+		}
+	}
+
+	// Copy from module cache into new directory, making edits as needed.
+	filepath.WalkDir(info.Dir, func(src string, d fs.DirEntry, err error) error {
+		if err != nil {
+			log.Fatal(err)
+		}
+		rel, err := filepath.Rel(info.Dir, src)
+		if err != nil {
+			log.Fatal(err)
+		}
+		dst := filepath.Join(dir, rel)
+		if d.IsDir() {
+			if err := os.MkdirAll(dst, 0777); err != nil {
+				log.Fatal(err)
+			}
+			return nil
+		}
+
+		data, err := os.ReadFile(src)
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		isRoot := !strings.Contains(rel, string(filepath.Separator))
+		if strings.HasSuffix(rel, ".go") {
+			data = fixGo(data, rel, srcMod, dstMod, isRoot)
+		}
+		if rel == "go.mod" {
+			data = fixGoMod(data, srcMod, dstMod)
+		}
+
+		if err := os.WriteFile(dst, data, 0666); err != nil {
+			log.Fatal(err)
+		}
+		return nil
+	})
+
+	log.Printf("initialized %s in %s", dstMod, dir)
+}
+
+// fixGo rewrites the Go source in data to replace srcMod with dstMod.
+// isRoot indicates whether the file is in the root directory of the module,
+// in which case we also update the package name.
+func fixGo(data []byte, file string, srcMod, dstMod string, isRoot bool) []byte {
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, file, data, parser.ImportsOnly)
+	if err != nil {
+		log.Fatalf("parsing source module:\n%s", err)
+	}
+
+	buf := edit.NewBuffer(data)
+	at := func(p token.Pos) int {
+		return fset.File(p).Offset(p)
+	}
+
+	srcName := path.Base(srcMod)
+	dstName := path.Base(dstMod)
+	if isRoot {
+		if name := f.Name.Name; name == srcName || name == srcName+"_test" {
+			dname := dstName + strings.TrimPrefix(name, srcName)
+			if !token.IsIdentifier(dname) {
+				log.Fatalf("%s: cannot rename package %s to package %s: invalid package name", file, name, dname)
+			}
+			buf.Replace(at(f.Name.Pos()), at(f.Name.End()), dname)
+		}
+	}
+
+	for _, spec := range f.Imports {
+		path, err := strconv.Unquote(spec.Path.Value)
+		if err != nil {
+			continue
+		}
+		if path == srcMod {
+			if srcName != dstName && spec.Name == nil {
+				// Add package rename because source code uses original name.
+				// The renaming looks strange, but template authors are unlikely to
+				// create a template where the root package is imported by packages
+				// in subdirectories, and the renaming at least keeps the code working.
+				// A more sophisticated approach would be to rename the uses of
+				// the package identifier in the file too, but then you have to worry about
+				// name collisions, and given how unlikely this is, it doesn't seem worth
+				// trying to clean up the file that way.
+				buf.Insert(at(spec.Path.Pos()), srcName+" ")
+			}
+			// Change import path to dstMod
+			buf.Replace(at(spec.Path.Pos()), at(spec.Path.End()), strconv.Quote(dstMod))
+		}
+		if strings.HasPrefix(path, srcMod+"/") {
+			// Change import path to begin with dstMod
+			buf.Replace(at(spec.Path.Pos()), at(spec.Path.End()), strconv.Quote(strings.Replace(path, srcMod, dstMod, 1)))
+		}
+	}
+	return buf.Bytes()
+}
+
+// fixGoMod rewrites the go.mod content in data to replace srcMod with dstMod
+// in the module path.
+func fixGoMod(data []byte, srcMod, dstMod string) []byte {
+	f, err := modfile.ParseLax("go.mod", data, nil)
+	if err != nil {
+		log.Fatalf("parsing source module:\n%s", err)
+	}
+	f.AddModuleStmt(dstMod)
+	new, err := f.Format()
+	if err != nil {
+		return data
+	}
+	return new
+}
diff --git a/cmd/gonew/main_test.go b/cmd/gonew/main_test.go
new file mode 100644
index 0000000..590bda0
--- /dev/null
+++ b/cmd/gonew/main_test.go
@@ -0,0 +1,214 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"archive/zip"
+	"bytes"
+	"fmt"
+	"io/fs"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+
+	"golang.org/x/tools/internal/diffp"
+	"golang.org/x/tools/txtar"
+)
+
+func init() {
+	if os.Getenv("TestGonewMain") == "1" {
+		main()
+		os.Exit(0)
+	}
+}
+
+func Test(t *testing.T) {
+	exe, err := os.Executable()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Each file in testdata is a txtar file with the command to run,
+	// the contents of modules to initialize in a fake proxy,
+	// the expected stdout and stderr, and the expected file contents.
+	files, err := filepath.Glob("testdata/*.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(files) == 0 {
+		t.Fatal("no test cases")
+	}
+
+	for _, file := range files {
+		t.Run(filepath.Base(file), func(t *testing.T) {
+			data, err := os.ReadFile(file)
+			if err != nil {
+				t.Fatal(err)
+			}
+			ar := txtar.Parse(data)
+
+			// If the command begins with ! it means it should fail.
+			// After the optional ! the first argument must be 'gonew'
+			// followed by the arguments to gonew.
+			args := strings.Fields(string(ar.Comment))
+			wantFail := false
+			if len(args) > 0 && args[0] == "!" {
+				wantFail = true
+				args = args[1:]
+			}
+			if len(args) == 0 || args[0] != "gonew" {
+				t.Fatalf("invalid command comment")
+			}
+
+			// Collect modules into proxy tree and store in temp directory.
+			dir := t.TempDir()
+			proxyDir := filepath.Join(dir, "proxy")
+			writeProxyFiles(t, proxyDir, ar)
+			extra := ""
+			if runtime.GOOS == "windows" {
+				// Windows absolute paths don't start with / so we need one more.
+				extra = "/"
+			}
+			proxyURL := "file://" + extra + filepath.ToSlash(proxyDir)
+
+			// Run gonew in a fresh 'out' directory.
+			out := filepath.Join(dir, "out")
+			if err := os.Mkdir(out, 0777); err != nil {
+				t.Fatal(err)
+			}
+			cmd := exec.Command(exe, args[1:]...)
+			cmd.Dir = out
+			cmd.Env = append(os.Environ(), "TestGonewMain=1", "GOPROXY="+proxyURL, "GOSUMDB=off")
+			var stdout bytes.Buffer
+			var stderr bytes.Buffer
+			cmd.Stdout = &stdout
+			cmd.Stderr = &stderr
+			if err := cmd.Run(); err == nil && wantFail {
+				t.Errorf("unexpected success exit")
+			} else if err != nil && !wantFail {
+				t.Errorf("unexpected failure exit")
+			}
+
+			// Collect the expected output from the txtar.
+			want := make(map[string]txtar.File)
+			for _, f := range ar.Files {
+				if f.Name == "stdout" || f.Name == "stderr" || strings.HasPrefix(f.Name, "out/") {
+					want[f.Name] = f
+				}
+			}
+
+			// Check stdout and stderr.
+			// Change \ to / so Windows output looks like Unix output.
+			stdoutBuf := bytes.ReplaceAll(stdout.Bytes(), []byte(`\`), []byte("/"))
+			stderrBuf := bytes.ReplaceAll(stderr.Bytes(), []byte(`\`), []byte("/"))
+			// Note that stdout and stderr can be omitted from the archive if empty.
+			if !bytes.Equal(stdoutBuf, want["stdout"].Data) {
+				t.Errorf("wrong stdout: %s", diffp.Diff("want", want["stdout"].Data, "have", stdoutBuf))
+			}
+			if !bytes.Equal(stderrBuf, want["stderr"].Data) {
+				t.Errorf("wrong stderr: %s", diffp.Diff("want", want["stderr"].Data, "have", stderrBuf))
+			}
+			delete(want, "stdout")
+			delete(want, "stderr")
+
+			// Check remaining expected outputs.
+			err = filepath.WalkDir(out, func(name string, info fs.DirEntry, err error) error {
+				if err != nil {
+					return err
+				}
+				if info.IsDir() {
+					return nil
+				}
+				data, err := os.ReadFile(name)
+				if err != nil {
+					return err
+				}
+				short := "out" + filepath.ToSlash(strings.TrimPrefix(name, out))
+				f, ok := want[short]
+				if !ok {
+					t.Errorf("unexpected file %s:\n%s", short, data)
+					return nil
+				}
+				delete(want, short)
+				if !bytes.Equal(data, f.Data) {
+					t.Errorf("wrong %s: %s", short, diffp.Diff("want", f.Data, "have", data))
+				}
+				return nil
+			})
+			if err != nil {
+				t.Fatal(err)
+			}
+			for name := range want {
+				t.Errorf("missing file %s", name)
+			}
+		})
+	}
+}
+
+// A Zip is a zip file being written.
+type Zip struct {
+	buf bytes.Buffer
+	w   *zip.Writer
+}
+
+// writeProxyFiles collects all the module content from ar and writes
+// files in the format of the proxy URL space, so that the 'proxy' directory
+// can be used in a GOPROXY=file:/// URL.
+func writeProxyFiles(t *testing.T, proxy string, ar *txtar.Archive) {
+	zips := make(map[string]*Zip)
+	others := make(map[string]string)
+	for _, f := range ar.Files {
+		i := strings.Index(f.Name, "@")
+		if i < 0 {
+			continue
+		}
+		j := strings.Index(f.Name[i:], "/")
+		if j < 0 {
+			t.Fatalf("unexpected archive file %s", f.Name)
+		}
+		j += i
+		mod, vers, file := f.Name[:i], f.Name[i+1:j], f.Name[j+1:]
+		zipName := mod + "/@v/" + vers + ".zip"
+		z := zips[zipName]
+		if z == nil {
+			others[mod+"/@v/list"] += vers + "\n"
+			others[mod+"/@v/"+vers+".info"] = fmt.Sprintf("{%q: %q}\n", "Version", vers)
+			z = new(Zip)
+			z.w = zip.NewWriter(&z.buf)
+			zips[zipName] = z
+		}
+		if file == "go.mod" {
+			others[mod+"/@v/"+vers+".mod"] = string(f.Data)
+		}
+		w, err := z.w.Create(f.Name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if _, err := w.Write(f.Data); err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	for name, z := range zips {
+		if err := z.w.Close(); err != nil {
+			t.Fatal(err)
+		}
+		if err := os.MkdirAll(filepath.Dir(filepath.Join(proxy, name)), 0777); err != nil {
+			t.Fatal(err)
+		}
+		if err := os.WriteFile(filepath.Join(proxy, name), z.buf.Bytes(), 0666); err != nil {
+			t.Fatal(err)
+		}
+	}
+	for name, data := range others {
+		// zip loop already created directory
+		if err := os.WriteFile(filepath.Join(proxy, name), []byte(data), 0666); err != nil {
+			t.Fatal(err)
+		}
+	}
+}
diff --git a/cmd/gonew/testdata/quote.txt b/cmd/gonew/testdata/quote.txt
new file mode 100644
index 0000000..9f166b5
--- /dev/null
+++ b/cmd/gonew/testdata/quote.txt
@@ -0,0 +1,28 @@
+gonew example.com/quote my.com/test
+
+-- example.com/quote@v1.5.2/go.mod --
+module example.com/quote
+-- example.com/quote@v1.5.2/quote.go --
+package quote
+
+import (
+	"example.com/quote/bar"
+)
+
+func Quote() {}
+-- example.com/quote@v1.5.2/quote/another.go --
+package quote // another package quote!
+-- stderr --
+gonew: initialized my.com/test in ./test
+-- out/test/go.mod --
+module my.com/test
+-- out/test/quote.go --
+package test
+
+import (
+	"my.com/test/bar"
+)
+
+func Quote() {}
+-- out/test/quote/another.go --
+package quote // another package quote!
