diff --git a/README.md b/README.md
index 609677892cf7bdc365ab084a9994356ea674e98e..1f1ca46df32c9d74a401f239f21a0596d7cfac86 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ go get nhooyr.io/websocket
 - First class [context.Context](https://blog.golang.org/context) support
 - Fully passes the WebSocket [autobahn-testsuite](https://github.com/crossbario/autobahn-testsuite)
 - Thorough tests with [90% coverage](https://coveralls.io/github/nhooyr/websocket)
-- [Zero dependencies](https://pkg.go.dev/nhooyr.io/websocket?tab=imports)
+- [Minimal dependencies](https://pkg.go.dev/nhooyr.io/websocket?tab=imports)
 - JSON and protobuf helpers in the [wsjson](https://pkg.go.dev/nhooyr.io/websocket/wsjson) and [wspb](https://pkg.go.dev/nhooyr.io/websocket/wspb) subpackages
 - Zero alloc reads and writes
 - Concurrent writes
diff --git a/accept.go b/accept.go
index a583f232e855e0bf2178150ea6b6f5e63eba7954..47e20b52c373f6757475c86c30b06626f3dfc745 100644
--- a/accept.go
+++ b/accept.go
@@ -134,7 +134,7 @@ func accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (_ *Con
 	b, _ := brw.Reader.Peek(brw.Reader.Buffered())
 	brw.Reader.Reset(io.MultiReader(bytes.NewReader(b), netConn))
 
-	c := newConn(connConfig{
+	return newConn(connConfig{
 		subprotocol:    w.Header().Get("Sec-WebSocket-Protocol"),
 		rwc:            netConn,
 		client:         false,
@@ -143,9 +143,7 @@ func accept(w http.ResponseWriter, r *http.Request, opts *AcceptOptions) (_ *Con
 
 		br: brw.Reader,
 		bw: brw.Writer,
-	})
-
-	return c, nil
+	}), nil
 }
 
 func verifyClientRequest(w http.ResponseWriter, r *http.Request) (errCode int, _ error) {
diff --git a/conn_test.go b/conn_test.go
index 68dc837da96639868314eee78dbfb16d242ea886..451d093a001aa43f294bfccedc513e20ac4e4138 100644
--- a/conn_test.go
+++ b/conn_test.go
@@ -271,7 +271,6 @@ func TestWasm(t *testing.T) {
 		t.Skip("skipping on CI")
 	}
 
-	// TODO grace
 	s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		c, err := websocket.Accept(w, r, &websocket.AcceptOptions{
 			Subprotocols:   []string{"echo"},
diff --git a/examples/chat/chat_test.go b/examples/chat/chat_test.go
index 79523d2a81dabc52782e642d8d67fc3ab1547b0a..eae185807116b9f98912651588b95e0a5f83b329 100644
--- a/examples/chat/chat_test.go
+++ b/examples/chat/chat_test.go
@@ -130,7 +130,6 @@ func setupTest(t *testing.T) (url string, closeFn func()) {
 	cs.subscriberMessageBuffer = 4096
 	cs.publishLimiter.SetLimit(rate.Inf)
 
-	// TODO grace
 	s := httptest.NewServer(cs)
 	return s.URL, func() {
 		s.Close()
diff --git a/examples/chat/main.go b/examples/chat/main.go
index cc2d01e8d37a7e51ea22b45d18e06069957ac06c..7f3cf6f334bd3c97555fc4e49e5d0a061ab608eb 100644
--- a/examples/chat/main.go
+++ b/examples/chat/main.go
@@ -34,8 +34,7 @@ func run() error {
 	log.Printf("listening on http://%v", l.Addr())
 
 	cs := newChatServer()
-	// TODO grace
-	s := http.Server{
+	s := &http.Server{
 		Handler:      cs,
 		ReadTimeout:  time.Second * 10,
 		WriteTimeout: time.Second * 10,
diff --git a/examples/echo/main.go b/examples/echo/main.go
index db2d06c9adfd0741b9e5d378f15a3cf27d13bb6a..f1771752dccf9ac22f34ecc39edba399108f28f5 100644
--- a/examples/echo/main.go
+++ b/examples/echo/main.go
@@ -16,11 +16,6 @@ import (
 	"nhooyr.io/websocket/wsjson"
 )
 
-// TODO IMPROVE CANCELLATION AND SHUTDOWN
-// TODO on context cancel send websocket going away and fix the read timeout error to be dependant on context deadline reached.
-// TODO this way you cancel your context and the right message automatically gets sent. Furthrmore, then u can just use a simple waitgroup to wait for connections.
-// TODO grace is wrong as it doesn't wait for the individual goroutines.
-
 // This example starts a WebSocket echo server,
 // dials the server and then sends 5 different messages
 // and prints out the server's responses.
@@ -34,7 +29,6 @@ func main() {
 	}
 	defer l.Close()
 
-	// TODO grace
 	s := &http.Server{
 		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 			err := echoServer(w, r)