Vue.js + Go with Echo v5, part 1: environment and first API

Mascote LinuxPro programando numa estação com o logo do Vue na tela e o gopher do Go na mesa, com o cachorro caramelo cyborg deitado ao lado

Vue.js + Go with Echo v5 series: Part 1: environment and first API · Part 2: Vue frontend with Vite · Part 3: tasks REST API · Part 4: login with session and cookie · Part 5: embed, single binary and Docker

Complete code: all files from the series are in the gist vue-go-echo-v5, with a README that shows which folder each one goes in.

A frontend in Vue.js and a backend in Go make a very practical pair for internal tools, dashboards and small SaaS apps. Vue handles the reactive interface, and Go delivers a fast API that, in the end, turns into a single binary with the site inside. In this five-part series we'll build, from scratch, a task application with login using Go, Echo v5, and Vue 3. All code was tested with the versions mentioned. In this first part: what each piece is, how to prepare the environment, and how to bring up the first API route.

What we'll build

At the end of the series, you'll have:

  • a JSON API in Go with the framework Echo v5: login, logout, current user, and a CRUD for tasks;
  • a frontend in Vue 3 with Vite and Vue Router, with a login screen and task list;
  • session in a cookie HttpOnly, without storing the token in the localStorage;
  • the compiled frontend embedded in the Go binary with go:embed;
  • a Dockerfile that compiles everything without you needing to install Go or Node on the machine, and generates an image of about 10 MB.

The series roadmap:

  1. Environment and first API (this article);
  2. Vue frontend with Vite, with proxy to the API in development;
  3. Task REST API: routes, JSON, validation and errors in Echo v5;
  4. Session and cookie login, authentication middleware and protected routes in Vue Router;
  5. Embed, single binary and Docker: production build, systemd and Nginx.

Why Echo v5

Echo is a minimalist web framework for Go: a fast router, route groups, ready-made middlewares (log, recover, CORS, static files, rate limit) and helpers for JSON. The version 5 it is a compatibility break compared to v4. The changes you see most often in day-to-day work are:

  • echo.Context became a struct: the handler now receives *echo.Context (pointer), not the interface anymore echo.Context;
  • logging with log/slog: the v4's own logger is gone, and Echo uses the standard library's structured logger;
  • new import: github.com/labstack/echo/v5;
  • route methods return RouteInfo, and the server gained the echo.StartConfig with graceful shutdown via context.

A lot of tutorials online still show v4 code, with func(c echo.Context) error. With v5 that code doesn't compile. The full list of changes is in the document API_CHANGES_V5.md of the project. In this series we use Echo v5.3.1, released in July 2026.

Versions used in the series

Checked on 22 September 2026:

  • Go 1.27.1;
  • Node.js 24 (LTS), which brings npm;
  • Echo v5.3.1;
  • Vue 3.5.43, Vue Router 4.6.4 and Vite 8.3.0.

Newer versions within the same release line should work. If something fails to compile, first compare the Echo version: it's the piece with the most changes between major versions.

Install Go and Node.js

For Go, use the official tarball from go.dev/dl. The distribution package is usually behind, and Echo v5 requires a recent Go. We have a longer guide at Installing Golang on Linux; the summary for amd64:

curl -LO https://go.dev/dl/go1.27.1.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.27.1.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.bashrc
source ~/.bashrc
go version

For Node.js, follow the official download page and choose the 24 LTS line, using whichever installer you prefer (tarball, version manager, or distribution repository). Then check:

node -v    # v24.x
npm -v

In part 5 we show how to build everything using only Docker. If you'd rather not install Go and Node, you can follow the series by reading the code and leave the build to the container.

Project structure

The backend and the frontend live in the same repository. Go is the main project, and Vue lives in the web/:

vueapp/
├── go.mod
├── main.go              # servidor Echo
├── internal/api/        # rotas, login e tarefas (partes 3 e 4)
└── web/                 # projeto Vue criado pelo Vite (parte 2)
    ├── embed.go         # go:embed do build (parte 5)
    ├── src/
    └── dist/            # gerado pelo npm run build

Create the folder and the Go module. The module path is the name used in the imports; replace it with your repository address:

mkdir vueapp && cd vueapp
go mod init github.com/exemplo/vueapp
go get github.com/labstack/echo/v5@v5.3.1

The first route with Echo v5

Create the main.go with a health route in /api/health. All API routes will start with /api: isso deixa o resto dos caminhos livre para o Vue, o que vai importar nas partes 2 e 5.

package main

import (
	"log/slog"
	"net/http"

	"github.com/labstack/echo/v5"
	"github.com/labstack/echo/v5/middleware"
)

func main() {
	e := echo.New()
	e.Use(middleware.RequestLogger())
	e.Use(middleware.Recover())

	e.GET("/api/health", func(c *echo.Context) error {
		return c.JSON(http.StatusOK, map[string]string{"status": "ok"})
	})

	if err := e.Start("127.0.0.1:8080"); err != nil {
		slog.Error("servidor", "error", err)
	}
}

What each part does:

  • echo.New() creates the application;
  • middleware.RequestLogger() logs each request as JSON via slog;
  • middleware.Recover() turns a panic into an error 500, instead of crashing the process;
  • the handler receives *echo.Context, with a pointer, which is the v5 signature;
  • c.JSON serializes the map and sets the Content-Type.

Run and test in another terminal:

go mod tidy
go run .
curl -i http://127.0.0.1:8080/api/health
HTTP/1.1 200 OK
Content-Type: application/json
...
{"status":"ok"}

In the server terminal you'll see the Echo banner and one log line per request, already in JSON:

{"level":"INFO","msg":"Echo (v5.3.1). High performance, minimalist Go web framework https://echo.labstack.com","version":"5.3.1"}
{"level":"INFO","msg":"http(s) server started","address":"127.0.0.1:8080"}
{"level":"INFO","msg":"REQUEST","method":"GET","uri":"/api/health","status":200,...}

We start the server in 127.0.0.1 for purpose: during development, the API is not exposed on the network. In part 5 the port and address start coming from environment variables.

Files for this part in the gist

Each file opens directly in the gist of the series. The gist brings the final version of the project: main.go and routes.go they also get login in part 4 and the embedded frontend in part 5.

Next step

With Go serving JSON, the part 2 creates the Vue frontend with Vite inside web/ and configures the proxy that makes the npm run dev talk to this API without any CORS issues. If you want to see this same architecture applied to a larger project, also read the series phpVirtualBox in Go.

Vue.js + Go with Echo v5 series: Part 1: environment and first API · Part 2: Vue frontend with Vite · Part 3: tasks REST API · Part 4: login with session and cookie · Part 5: embed, single binary and Docker