Echo server
diff --git a/apps/echo/main.go b/apps/echo/main.go
new file mode 100644
index 0000000..0e96d2c
--- /dev/null
+++ b/apps/echo/main.go
@@ -0,0 +1,58 @@
+// Copyright 2018 Venil Noronha. 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 (
+	"bufio"
+	"flag"
+	"fmt"
+	"io"
+	"net"
+	"os"
+)
+
+var port = flag.Int("port", 3000, "Port to listen on")
+
+// main serves as the program entry point
+func main() {
+	flag.Parse()
+	// create a tcp listener on the given port
+	listener, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
+	if err != nil {
+		fmt.Println("failed to create listener, err:", err)
+		os.Exit(1)
+	}
+	fmt.Printf("listening on %s\n", listener.Addr())
+
+	// listen for new connections
+	for {
+		conn, err := listener.Accept()
+		if err != nil {
+			fmt.Println("failed to accept connection, err:", err)
+			continue
+		}
+
+		// pass an accepted connection to a handler goroutine
+		go handleConnection(conn)
+	}
+}
+
+// handleConnection handles the lifetime of a connection
+func handleConnection(conn net.Conn) {
+	defer conn.Close()
+	reader := bufio.NewReader(conn)
+	for {
+		// read client request data
+		bytes, err := reader.ReadBytes(byte('\n'))
+		if err != nil {
+			if err != io.EOF {
+				fmt.Println("failed to read data, err:", err)
+			}
+			return
+		}
+		fmt.Printf("request: %s", bytes)
+		conn.Write(bytes)
+	}
+}