# go-echarts: building ECharts HTML from Go structs

> go-echarts is a Go library that emits Apache ECharts HTML rather than drawing pixels itself. It suits Go services that need to hand a browser a chart, and it is the wrong tool when you need a PNG on the server.

**go-echarts/go-echarts** — 🎨 The adorable charts library for Golang.

- Repository: https://github.com/go-echarts/go-echarts
- Website: https://go-echarts.github.io/go-echarts/
- Stars: 7,645 · Forks: 591
- Language: Go
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/go-echarts-go-echarts

## What go-echarts solves, and for whom

Go has few data visualization options, and the README says so directly: the project exists because the ecosystem lacks a data visualization library comparable to what other languages offer. go-echarts does not draw anything itself. It generates HTML that loads Apache ECharts, the JavaScript charting library, and the README credits pyecharts as a model the project learned from and evolved from. The audience is therefore a specific one: Go developers who already have data in a Go process and want a chart in a browser. That includes internal dashboards, report generators that write an .html file, and HTTP handlers that stream a chart to a client. The README lists 25+ chart types and 400+ maps as the feature surface, plus a handbook, a separate examples repository and GoDocs as the entry points. If your output target is a browser tab, the fit is direct. If your output target is an image file on disk, the library is aimed at a different problem.

## How it works: Go structs in, ECharts HTML out

The architecture is a code generator, not a renderer. You build a chart object from the charts package, for example charts.NewBar() or charts.NewLine(). You attach global options through SetGlobalOptions with functional options such as charts.WithTitleOpts(opts.Title{...}) and charts.WithInitializationOpts(opts.Initialization{Theme: types.ThemeWesteros}). You attach data with SetXAxis and AddSeries. Then you call Render, passing an io.Writer. The README's first example passes an *os.File created from bar.html; the second passes an http.ResponseWriter. The repository layout matches this split: opts/ holds the option structs, charts/ holds the chart constructors, components/ and datasets/ hold supporting pieces, render/ and templates/ hold the output generation, and types/ holds shared values such as theme names. The consequence is that the Go side never rasterizes. The browser executes the ECharts JavaScript and paints the chart. That is why Render accepts any writer: the artifact is text, so it can go to a file, an HTTP response, or a buffer. The dependency footprint is small, which the go.mod confirms: the module requires only github.com/stretchr/testify directly, with go-spew, kr/pretty, go-difflib, check.v1 and yaml.v3 as indirect dependencies. The module declares go 1.18.

## Installing go-echarts and rendering a first bar chart

The README gives two installation paths. The module-aware path is the one to use. Run go get against the v2 path, or add the require line to go.mod. The README warns that using v2 without modules is not a good choice and shows a manual workaround that moves charts, components, datasets, opts, render, templates and types into a v2 directory; treat that as a fallback, not the normal route.

```bash
go get -u github.com/go-echarts/go-echarts/v2/...
```

Alternatively, the README shows the go.mod form directly:

```
require github.com/go-echarts/go-echarts/v2
```

The first real use is the bar chart from the README. It creates a chart, sets a title, attaches two series over a fixed X axis, and writes the result to bar.html. The imports come from the v2 paths for charts and opts.

```go
package main

import (
	"math/rand"
	"os"

	"github.com/go-echarts/go-echarts/v2/charts"
	"github.com/go-echarts/go-echarts/v2/opts"
)

func generateBarItems() []opts.BarData {
	items := make([]opts.BarData, 0)
	for i := 0; i < 7; i++ {
		items = append(items, opts.BarData{Value: rand.Intn(300)})
	}
	return items
}

func main() {
	bar := charts.NewBar()
	bar.SetGlobalOptions(charts.WithTitleOpts(opts.Title{
		Title:    "My first bar chart generated by go-echarts",
		Subtitle: "It's extremely easy to use, right?",
	}))
	bar.SetXAxis([]string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}).
		AddSeries("Category A", generateBarItems()).
		AddSeries("Category B", generateBarItems())
	f, _ := os.Create("bar.html")
	bar.Render(f)
}
```

What you should see after running it is a bar.html file that opens in a browser and draws two bar series. The README also shows the same pattern served over HTTP: the handler builds a line chart with a theme, sets series options through charts.WithLineChartOpts(opts.LineChart{Smooth: opts.Bool(true)}), and calls line.Render(w) against the response writer. The example registers the handler on / and listens on :8081. Note the error handling in the README snippets: os.Create and Render return errors that the example discards. In a real service you would not.

## Where go-echarts stops: no server-side image, no v1 upgrade path

The most consequential limitation follows from the mechanism. Because the Go code emits HTML and the browser draws the chart, there is no server-side rasterization in the documented workflow. If you need a PNG attached to an email, embedded in a PDF, or returned from a JSON API, the README does not describe a path for that, and the repository layout gives no rendering backend for it. People search for "go echarts png" for exactly this reason; no such output is documented, so treat it as unconfirmed rather than supported.

The second limitation is versioning. The README states plainly that v1 and v2 are incompatible and that you cannot upgrade from v1 to v2 smoothly. There is no documented migration guide, only the author's opinion that the new version is worth trying. The README also notes that release candidates are published before standard releases when changes are minor, and that upgrading across rc versions may require small adjustments. A team pinned to v1 faces a rewrite of chart construction code, not a dependency bump.

The third is the dependency on a browser and on the ECharts JavaScript version the generated HTML expects. The README's badge records echarts v5.4.3. Nothing in the README describes offline rendering, a headless browser harness, or a fallback when JavaScript is unavailable.

## How go-echarts differs from Go-native chart renderers

The alternative approach in the Go ecosystem is a library that computes geometry in Go and writes an image directly. That is a different architecture with different trade-offs, and the related searches surface two such projects by name: wcharczuk/go-chart and vicanso/go-charts. Neither is described in this repository's README, so the comparison has to stay at the level of approach rather than features. A Go-native renderer produces a file or byte stream with no browser involved, which suits cron jobs, PDF pipelines and email attachments. It gives up the interactive layer: tooltips, legends toggling series, zoom and the 400+ map set come from ECharts, and a static renderer would have to reimplement any of that it wanted. go-echarts takes the opposite bet. It accepts a browser as a prerequisite in exchange for the full ECharts feature set and a small Go dependency tree. The choice is not about which library is better; it is about whether a browser is in your delivery path. If it is, go-echarts is the shorter route. If it is not, a renderer that draws in Go is the only route, and you should evaluate those projects on their own documentation.

## Maintenance, releases and the MIT licence

The repository is not archived, and the last push was on 2026-09-13. Releases are frequent and versioned: v2.7.0 on 2026-02-23, v2.7.1 on 2026-03-14, and v2.7.2 on 2026-04-11. The README adds a wrinkle worth planning for: release candidates are published before standard releases when changes are minor, so a team tracking the project closely may land on an rc. Pin a released tag in go.mod if you want to avoid that.

The upgrade cost is concentrated at major versions. Within v2, the release cadence suggests small changes, and the README frames rc adjustments as minor. Across v1 to v2, the README says the upgrade cannot be done smoothly, so budget for rewriting chart construction and option structs rather than adapting them.

The licence is MIT, per the repository's LICENSE file and the badge in the README. MIT is permissive and imposes no copyleft obligation on your code. It does require that the copyright notice and permission notice be preserved in copies or substantial portions of the software. Note the split in what you are shipping: your binary contains Go code under MIT, but the generated HTML loads Apache ECharts, which is a separate project with its own licensing. The README links to echarts.apache.org but does not state ECharts' licence terms, so check that separately if the distinction matters to your distribution.

## Conclusion

Adopt go-echarts when a Go process already produces data and a browser is available to draw it: the v2 module installs with go get -u github.com/go-echarts/go-echarts/v2/... and Render takes any io.Writer, so net/http handlers work. Do not adopt it if you need server-side PNG output, a stable API across major versions, or rendering without a browser. Before committing, verify that the charts you need exist in charts/ and that the option structs in opts/ cover the fields you rely on, since the README documents no rollback or migration path between v1 and v2.

## FAQ

### How do I install go-echarts for a Go module project?

Run go get -u github.com/go-echarts/go-echarts/v2/... or add require github.com/go-echarts/go-echarts/v2 to go.mod. The README advises against using v2 without Go modules and presents the manual directory-moving workaround only as a fallback.

### What is the basic go-echarts usage pattern for a chart?

Create a chart with charts.NewBar() or charts.NewLine(), set options such as charts.WithTitleOpts(opts.Title{...}), attach data with SetXAxis and AddSeries, then call Render with an io.Writer. The README writes the result to an *os.File or to an http.ResponseWriter.

### Can go-echarts produce a PNG file on the server?

The documented workflow emits HTML that a browser renders with Apache ECharts, and the README shows no server-side image output. The repository layout contains no rasterization backend, so PNG generation is not something the README confirms.

### Can I upgrade a go-echarts v1 project to v2?

The README states that v1 and v2 are incompatible and that you cannot upgrade smoothly from v1 to v2. No migration guide appears in the README, so the change amounts to rewriting chart construction code.

### What licence does go-echarts use?

go-echarts is MIT licensed. The generated HTML loads Apache ECharts, a separate project with its own terms, which the README links to but does not describe.

## Sources

- [go-echarts/go-echarts on GitHub](https://github.com/go-echarts/go-echarts)
- [License: MIT](https://github.com/go-echarts/go-echarts/blob/master/LICENSE)
- [Project website](https://go-echarts.github.io/go-echarts/)
- [README](https://github.com/go-echarts/go-echarts/blob/master/README.md)
- [Releases](https://github.com/go-echarts/go-echarts/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/go-echarts-go-echarts
