Learn Go by building. Each project is self-contained, idiomatic, and dependency-light.
Getting Started Β· Projects Β· Roadmap Β· Contributing
Go Mini Projects is a growing catalog of bite-sized programs written in pure, idiomatic Go. Every folder is an independent project you can read top to bottom in a single sitting, run in one command, and learn one concept from β flags, file I/O, encoding, concurrency, HTTP servers, real-time streaming, and more.
The goal is simple: learn Go by shipping small things that actually work.
- β Self-contained β each project stands on its own, no framework, no boilerplate.
- β Idiomatic β clean code, standard library first, dependencies only when they earn their place.
- β
Runnable in seconds β clone,
cd,go run. That's it. - β Progressive β from a 40-line CLI to a graceful-shutdown HTTP server with SSE.
- Go 1.26+ installed and on your
PATH.
Verify your setup:
go versiongit clone https://github.com/binafy/go-mini-projects.git
cd go-mini-projectsEach project lives in its own numbered folder. cd into one and run it:
cd "1. Text Wrapper"
go run main.go -text="Go is fun to learn by building" -width=15π‘ Projects that pull external packages (like the QR Code Generator) ship their own
go.mod. Justgo runinside the folder β Go resolves the dependencies automatically.
Legend: β Implemented Β· π§ Planned
| # | Project | What it does | Highlights | Status |
|---|---|---|---|---|
| 1 | Text Wrapper | Wraps text to a maximum line width | flag parsing, word-boundary wrapping |
β |
| 2 | QR Code Generator | Turns any URL into a QR image (png/jpg/webp) |
3rd-party lib, random filenames, format validation | β |
| 3 | Web Scraper | Extract data from web pages | β | β |
| 4 | Credit Validator | Validate card numbers via the Luhn algorithm | β | π§ |
| 5 | URL Shortener | Shorten URLs and expand them back | crypto/rand IDs, JSON store, atomic file writes |
β |
| 6 | Empty File Finder | Find zero-byte files in a tree | filepath.WalkDir, resilient error handling |
β |
| 7 | Empty Directory Finder | Find empty directories in a tree | Recursion, transitively-empty detection | β |
| 8 | Password Generator | Generate strong, configurable passwords | crypto/rand, guaranteed character classes |
β |
| 9 | Search String | Grep-like search across files | β | π§ |
| 10 | Watermark Image | Overlay a watermark onto images | β | π§ |
| 11 | Encrypt / Decrypt Text | Symmetric text encryption | β | π§ |
| 12 | CLI Todo App | Manage a todo list from the terminal | β | π§ |
| 13 | XML β JSON | Convert XML documents to JSON | β | π§ |
| 14 | Tic Tac Toe | Terminal two-player game | β | π§ |
| 15 | String Reverse | Reverse text, whole lines or word order | Unicode-aware (combining marks), stdin piping, bufio |
β |
| 16 | SSE Server | Real-time Server-Sent Events over HTTP | embed, context, graceful shutdown, live browser demo |
β |
| 17 | WebSocket | Bidirectional real-time messaging | β | π§ |
1. Text Wrapper β greedy word-wrap in ~40 lines
A tiny CLI that reflows text to a maximum line width without breaking words.
cd "1. Text Wrapper"
go run main.go -text="Im Milwad Khosravi who makes a lot of tools for developers, enjoy it!" -width=10Flags
| Flag | Default | Description |
|---|---|---|
-text |
(required) | The text to wrap |
-width |
5 |
Maximum characters per line |
2. QR Code Generator β URL β scannable image
Generates a QR code from any URL and writes it to disk. Powered by skip2/go-qrcode.
cd "2. QR Code Generator"
go run main.go -url="https://github.com/binafy/go-mini-projects" -filename="repo" -format=png -fileSize=512Flags
| Flag | Default | Description |
|---|---|---|
-url |
(required) | The URL to encode |
-filename |
(random) | Output file name (without extension) |
-format |
png |
Output format: png, jpg, or webp |
-fileSize |
256 |
Image size in pixels |
6. Empty File Finder β zero-byte files across a whole tree
Walks a directory tree and reports every zero-byte file it finds. Sizes come from the directory entry rather than reading each file, so a huge tree never gets pulled through memory, and a directory it cannot open is reported and skipped instead of ending the scan.
cd "6. Empty File Finder"
go run main.go -d testdataThe 'testdata/empty.txt' file is empty!
The 'testdata/milwad/empty2.txt' file is empty!
Found 2 empty file(s) in 'testdata'.
Flags
| Flag | Default | Description |
|---|---|---|
-d |
. |
The directory to search (scanned recursively) |
7. Empty Directory Finder β empty folders, including the ones hiding empties
Walks a tree and reports directories with nothing in them. With -nested it also reports directories that hold nothing but other empty directories β the ones worth pruning even though they are not literally empty. Unreadable directories are reported and skipped, and never counted as empty.
cd "7. Empty Directory Finder"
go run main.go -d testdata
go run main.go -d testdata -nestedGiven outer/middle/inner where only inner is literally empty, the default run reports just inner, while -nested reports inner, middle and outer.
Flags
| Flag | Default | Description |
|---|---|---|
-d |
. |
The directory to search (scanned recursively) |
-nested |
false |
Also report directories holding nothing but empty directories |
β οΈ Git cannot track empty directories, sotestdata/emptyFolderhas to be created locally:mkdir -p "7. Empty Directory Finder/testdata/emptyFolder".
8. Password Generator β random you can actually rely on
Generates passwords from crypto/rand rather than math/rand, so the output is not predictable from previous passwords. Each enabled character class is guaranteed to appear at least once, and the result is shuffled so the class order never leaks into the layout.
cd "8. Password Generator"
go run main.go
go run main.go -count=5 -length=24
go run main.go -length=20 -symbols=falseFlags
| Flag | Default | Description |
|---|---|---|
-length |
16 |
Length of each password |
-count |
1 |
How many passwords to generate |
-lower |
true |
Include lowercase letters |
-upper |
true |
Include uppercase letters |
-digits |
true |
Include digits |
-symbols |
true |
Include symbols |
Disable a class with =false, e.g. -symbols=false. Asking for a length smaller than the number of enabled classes is rejected, since such a password could not contain them all.
15. String Reverse β reversing text without mangling Unicode
Reverses text from a flag, from arguments, or straight from a pipe. Naive []rune reversal detaches accents from their letters, so characters are reversed together with the combining marks that follow them β cafΓ© comes back as Γ©fac, not with a floating accent.
cd "15. String Reverse"
go run main.go -text="Milwad Khosravi"
go run main.go -words -text="one two three"
cat notes.txt | go run main.goInput is read line by line, so piped files keep their line structure β each line is reversed on its own.
Flags
| Flag | Default | Description |
|---|---|---|
-text |
(stdin) | The text to reverse; falls back to arguments, then stdin |
-words |
false |
Reverse the order of the words instead of the characters |
16. SSE Server β real-time streaming done right
A production-shaped HTTP server that pushes a live timestamp to the browser every second using Server-Sent Events. Demonstrates //go:embed, context-based cancellation, http.NewResponseController flushing, and graceful shutdown on SIGINT.
cd "16. SSE"
go run main.go -addr=":8080" -interval=1sThen open http://localhost:8080 in your browser and watch events stream in live.
Flags
| Flag | Default | Description |
|---|---|---|
-addr |
:8080 |
HTTP listen address |
-interval |
1s |
Delay between streamed events |
The long-term vision is a comprehensive Go learning path spanning 100+ projects across every level. A curated slice of what's coming:
|
π’ Beginner
|
π΅ Intermediate / Web
|
π΄ Advanced
|
See the full 100+ project backlog in
todo.txt.
go-mini-projects/
βββ 1. Text Wrapper/ # β
CLI word-wrapper
β βββ main.go
βββ 2. QR Code Generator/ # β
URL β QR image
β βββ main.go
β βββ go.mod
β βββ go.sum
βββ 6. Empty File Finder/ # β
Recursive zero-byte file finder
β βββ main.go
β βββ testdata/
βββ 7. Empty Directory Finder/ # β
Recursive empty-directory finder
β βββ main.go
β βββ testdata/
βββ 8. Password Generator/ # β
crypto/rand password generator
β βββ main.go
βββ 15. String Reverse/ # β
Unicode-aware string reverser
β βββ main.go
βββ 16. SSE/ # β
Real-time SSE server
β βββ main.go
β βββ index.html
βββ ... # π§ Planned projects
βββ todo.txt # Full roadmap
βββ README.md
Contributions are warmly welcome β whether it's a brand-new project, a bug fix, or a docs polish.
- Fork the repository.
- Create a branch:
git checkout -b feat/my-awesome-project. - Add your project in its own numbered folder with a self-contained
main.go. - Keep it idiomatic β
gofmtyour code, prefer the standard library, document your flags. - Open a Pull Request describing what you built and how to run it.
New projects should be runnable with a single
go runand include a short usage example.
Released under the MIT License. See LICENSE for details.
Built with πΉ and β₯ by Milwad Khosravi
If this repo helped you learn Go, consider giving it a β