Open-source project
SimonWaldherr/golang-examples avatar
SimonWaldherr/golang-examples

golang-examples: a graded collection of Go programs, from Hello World to the flight recorder

Go(lang) examples - (explain the basics of #golang)

1,726 stars458 forksGoMIT

At a glance

What is it?
SimonWaldherr/golang-examples is a set of small, focused Go programs for learning the language, arranged from beginner through advanced and expert, with most examples runnable independently. The project is unusually careful about staying current, with a check script, a modern-go CI workflow, and a table mapping each recent Go language feature to the example that demonstrates it.
Who is it for?
golang-examples fits a learner who wants to read working Go rather than a tutorial narrative, and it fits a team that wants a reference of idiomatic patterns to point new starters at. It is the wrong resource for a structured course with exercises and feedback, and the wrong choice if you need working code to put into production, since these are teaching programs rather than a maintained library.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 15 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 6, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • SimonWaldherr/golang-examples1,726 ★ · +2
Star history
Repository2026-10-202026-11-06
SimonWaldherr/golang-examples1.7k1.7k

2 Stars in the last 17 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

A graded ladder rather than a tutorial

The project is described as small, focused programs for learning Go, from `Hello, World!` to concurrency, WebAssembly, runtime tracing, and modern language features, and most examples are standalone programs that can be run independently.

The word standalone is the important one for how you would actually use this. There is no framework here, no build step that couples the examples together, and no narrative that has to be read in order. Each program is a thing you can open, read, and run, and the directory structure tells you how the collection is graded.

The repository map is a table of five directories. `beginner/` holds syntax, types, control flow, files, and small algorithms. `advanced/` holds generics, iterators, concurrency, encoding, tests, and benchmarks. `expert/` holds servers, tracing, assembly, CGO, cryptography, and image generation. `non-std-lib/` holds examples that depend on third-party packages or external services. And `tinygo/` holds TinyGo and microcontroller examples.

The `non-std-lib/` directory is a deliberate separation rather than an inconvenience. An example that needs a third-party package or an external service is a different thing from one that only uses the standard library, because the former will not run for you without setup, and mixing them in one directory would make it unclear which examples are self-contained.

The licence is MIT, there is a DOI badge for the archive, and the repository carries a `CITATION.cff` and a `test.sh` at the root, along with a `scripts/` directory.

The release history is regular: v1.24.2 in September 2024, v1.25.0 in May 2026, and v1.26.0 in July 2026, with the last push on the same day as the v1.26.0 tag. The topics list education, examples, howto, learning, and programming-language, and the project has taken part in Hacktoberfest.

The quick start, and the toolchain version rule

The quick start is three commands, and one of them is not what you would expect.

shell
git clone https://github.com/SimonWaldherr/golang-examples.git
cd golang-examples
go run ./beginner/HelloWorld.go
go run ./advanced/iterators
./scripts/check-modern.sh

The first two are obvious, a file to run and a directory to run. The third is the interesting one, and it is a script in the repository that checks the examples against current Go releases.

The rule that governs the toolchain is stated before the commands. The module version in `go.mod` is the source of truth for the required Go toolchain. The go.mod declares `go 1.26.4`, so that is the version the examples are written against, and the script is how you find out whether they still work on the release you have installed.

That design is what makes the collection worth trusting, and it is the part most example repositories skip. A set of examples written in 2019 still compiles, and it still demonstrates idioms that have since been replaced. The CI workflow named modern-go is the enforcement, and the check script is the local version of the same thing.

The examples are also runnable in the browser. There is an online editor at the site, and a WebAssembly-based Qix game linked from the summary, and the site itself is at simonwaldherr.github.io/golang-examples, which is also the project homepage.

So the workflow for a learner is: clone, check your Go version against go.mod, run the check script, and then work through the directories in order if you want a path, or pick the one you need if you do not.

Every recent Go feature has a program that shows it

The modern Go highlights table is the most unusual thing in the project, because it is a deliberate anti-rot mechanism rather than a feature list.

These examples intentionally use recent stable Go features, and each row pairs a Go version with a feature and the command that runs it.

Go 1.23 brings range-over-function iterators plus the `iter`, `maps`, and `slices` packages, run with `go run ./advanced/iterators`. Go 1.24 brings generic type aliases, run with `go run ./advanced/generic-alias`, and benchmarks with `testing.B.Loop`, run with `go test ./advanced/benchmark-loop -bench .`. Go 1.25 brings `sync.WaitGroup.Go`, run with `go run ./advanced/waitgroup-go`, deterministic concurrent tests with `testing/synctest`, run with `go test ./advanced/synctest`, and the runtime trace flight recorder, run with `go run ./expert/flight-recorder`. Go 1.26 brings initialised pointers with `new(expression)`, run with `go run ./beginner/initialized-pointer`. And Go 1.21 brings structured JSON logging with `log/slog`, run with `go run ./advanced/structured-logging`.

The table is sorted by version rather than by topic, which tells you the intended reading order for someone who already knows Go and wants to catch up with what has changed. And the flight recorder row has a note attached: that example writes `flight.trace`, and you inspect it with `go tool trace flight.trace`.

That last one is the pattern the whole collection follows. A feature is not mentioned, it is demonstrated, and the demonstration comes with the command to run it and, where relevant, the command to inspect the output.

The `testing/synctest` example is worth a second look, because deterministic concurrent tests are one of the harder things to demonstrate convincingly. A concurrency example that produces the same result every run is teaching something a race-condition demo cannot.

nanoGo, and why it is not a smaller TinyGo

The featured project is nanoGo, a minimalist interpreter for a supported subset of Go, and the project summary spends a surprising amount of space on what it is not.

nanoGo evaluates source code dynamically in a CLI, REPL, embedded host, or browser playground, and when used in the browser the interpreter itself is compiled to WebAssembly. That makes it a fit for interactive tutorials, editable documentation, controlled snippets, and browser-based Go experiments.

Then there is a table comparing nanoGo, TinyGo, and GopherJS across five dimensions. The execution model: nanoGo interprets supported Go source at runtime, TinyGo compiles Go programs ahead of time, and GopherJS compiles Go programs ahead of time to JavaScript. The browser artifact: for nanoGo the interpreter runs in WASM and evaluates guest source dynamically, for TinyGo the application itself can be compiled to WASM, and for GopherJS it is pure JavaScript generated from the application.

The best suited to row is the clearest. nanoGo is for playgrounds, REPLs, live examples, controlled embedded scripting, and teaching. TinyGo is for microcontrollers, embedded applications, and deployable WASM programs. GopherJS is for browser front ends and JavaScript-based web integrations.

The Go compatibility row makes the point about the trade: nanoGo has a deliberately supported language and library subset, TinyGo is a compiler with its own documented Go compatibility differences, and GopherJS has broad Go support with documented browser and JavaScript-runtime constraints.

And the host control row is the one that matters most for security thinking. nanoGo has optional capabilities and cooperative resource limits that can restrict guest source. TinyGo's compiled program runs for its selected target, and TinyGo is not an interpreter sandbox. GopherJS's generated program executes with normal browser JavaScript capabilities.

So nanoGo is not a smaller replacement for TinyGo or GopherJS. Choose nanoGo when source must be edited or evaluated at runtime, TinyGo when you want to compile and deploy an application such as to a Raspberry Pi Pico, and GopherJS when compiled JavaScript is the right browser target.

One detail closes the loop. The existing live editor uses its `go2js` integration, which is based on GopherJS, and pressing F5 formats the editor contents, compiles the Go program to JavaScript, and evaluates that JavaScript in the page. It is a compile-and-run workflow, not a nanoGo interpreter session.

The dependency list, and what it costs you to clone

The go.mod is worth reading, because it shows the shape of the collection and the price of running it.

The module is `github.com/SimonWaldherr/golang-examples` and the required Go version is 1.26.4. The direct dependencies include a set of the author's own packages on `simonwaldherr.de/go`, namely golibs, gwv, and micromarkdownGo, which is a small Markdown implementation from 2014 by the timestamp. Alongside them are the standard choices for the domain examples: ebitengine's purego and hideconsole for the CGO and assembly work, gopherjs for the browser target, gonum and gonum's plot for the scientific examples, go-crypto for the cryptography examples, and the x packages for net, crypto, and exp.

The third-party set is what makes the examples in the domain directories possible. `hajimehoshi/ebiten/v2` is the game engine for the Qix game and the minigames, `mattn/go-sqlite3` is for the database examples, `gocv.io/x/gocv` is the computer vision binding, `go-hep.org/x/hep` is the physics toolkit, `senseyeio/spaniel` is the machine learning library, `ulule/limiter` is a rate limiter, `antchfx/xmlquery` and `xpath` are for the XML examples, `robfig/cron` is for the scheduling examples, `smartystreets/goconvey` is the testing framework for the test examples, `ryboe/q` is a queue implementation, and `golang-pkg-pcre` is for the regular expression examples.

Cloning the repository does not itself download Go modules. Dependencies are resolved and downloaded as required by subsequent Go commands, so a standard-library example can have a much smaller practical setup than examples using native or third-party packages.

The indirect list is longer still and includes a LaTeX and PDF toolchain, `codeberg.org/go-latex/latex`, `codeberg.org/go-pdf/fpdf`, and the `codeberg.org/gonuts` binary library, which come from the plotting and document examples rather than from anything central. There is also `github.com/ebitengine/gomobile`, which is how the TinyGo and mobile examples are handled.

The Go version floor of 1.26.4 in the module is worth noticing alongside the modern Go table. This collection does not support old Go versions, and it does not try to.

Where this collection is the wrong resource

The limits are about what a collection of examples is and is not, and they are worth stating before someone plans a curriculum around it.

First, there is no feedback loop. A course has exercises, a grader, and a teacher. This has programs, and reading them teaches you a great deal, but nothing tells you whether your understanding of the iterator example is correct until you write the iterator yourself and it does not work. For a self-learner that is a real gap, and it is why the related projects list includes a small R-like environment, a SQL engine, and a retrieval-augmented generation system, all of which are places to practise.

Second, the examples are teaching programs, not production code. They are small by design, they print things, and they often trade clarity for realism in the direction of clarity. A team that copies a pattern from here into a service is copying a demonstration of a pattern rather than a tested implementation of one.

Third, the dependency footprint is the largest practical surprise. The go.mod pulls in a plotting stack, a LaTeX and PDF toolchain, a computer vision binding that needs native libraries, a game engine, and a Go-to-JavaScript compiler, for a repository whose headline example is Hello World. A single example may need only a subset of these packages; actual resolution and downloads depend on the command and Go module configuration. Check the selected example's native dependencies before running it.

Fourth, the collection is versioned against the newest Go. The go.mod requires 1.26.4 and the modern Go table covers 1.21 through 1.26. That is right for the stated goal and wrong for a team still on an older toolchain, where the newer examples will not compile and the older idioms the examples were written to replace are the ones in use.

Fifth, the domain examples carry a dependency risk that a pure teaching repo would not. gocv needs OpenCV installed, gopherjs needs a specific toolchain, the TinyGo examples need TinyGo, and the SQLite binding needs a C compiler. The `non-std-lib/` directory marks them, but the marker is a directory name rather than a build constraint.

Sixth, and this is a small thing that matters for a collection maintained this way, the modern Go highlights table means the repository is a moving target by design. A version bump in Go adds a row, and a version bump in Go that removes or changes a feature means an example has to change. The check script and the CI workflow are how the project keeps that honest, and they are the reason to trust the examples at all.

Editorial conclusion

golang-examples fits a learner who wants to read working Go rather than a tutorial narrative, and it fits a team that wants a reference of idiomatic patterns to point new starters at. It is the wrong resource for a structured course with exercises and feedback, and the wrong choice if you need working code to put into production, since these are teaching programs rather than a maintained library. Check three things before you work through it: that your Go toolchain matches the version in go.mod, which is the stated source of truth for the required version, that you run the check script, since the collection's value depends on the examples being current, and that the dependency footprint in go.mod does not surprise you, because the module pulls in plotting, database, computer-vision, and WebAssembly libraries for a handful of examples.

Frequently asked questions

How do I run the golang-examples programs?

Clone the repository, change into the directory, and run the examples with `go run`, for example `go run ./beginner/HelloWorld.go` or `go run ./advanced/iterators`. The module version in go.mod is the source of truth for the required Go toolchain, and `./scripts/check-modern.sh` checks the examples against the current Go release.

What is nanoGo and how is it different from TinyGo or GopherJS?

nanoGo is a minimalist interpreter for a supported subset of Go, evaluating source dynamically in a CLI, REPL, embedded host, or browser playground, with the interpreter itself compiled to WebAssembly in the browser. TinyGo and GopherJS both compile ahead of time, the former to WebAssembly and the latter to JavaScript, so nanoGo suits playgrounds and live examples while the others suit deploying an application.

Which recent Go language features do the examples cover?

The table in the project summary maps each to a runnable example: range-over-function iterators with the iter, maps, and slices packages in Go 1.23, generic type aliases and benchmarks with testing.B.Loop in 1.24, sync.WaitGroup.Go, deterministic concurrent tests with testing/synctest, and the runtime trace flight recorder in 1.25, initialised pointers with new(expression) in 1.26, and structured JSON logging with log/slog in 1.21.

How are the golang-examples organised?

Into five directories. `beginner/` has syntax, types, control flow, files, and small algorithms, `advanced/` has generics, iterators, concurrency, encoding, tests, and benchmarks, `expert/` has servers, tracing, assembly, CGO, cryptography, and image generation, `non-std-lib/` has examples that depend on third-party packages or external services, and `tinygo/` has TinyGo and microcontroller examples. Most examples are standalone programs.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. SimonWaldherr/golang-examples on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/simonwaldherr-golang-examples.svg)](https://hysenlabs.com/projects/simonwaldherr-golang-examples)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/simonwaldherr-golang-examples.svg)](https://hysenlabs.com/projects/simonwaldherr-golang-examples)

Was this useful?