Projects
This is the list of my open source projects. Most are licensed under MPL 2.0, which is my favorite license these days. I've added a short annotation to each project to explain my motivation. Favorite projects are marked with a star.
- go-simpler
- env
- sloglint
- musttag
- goversion
- sloggen
- assert
- errorsx
- queries
- check
- libds
- dotfiles
- porkcron
- Go styleguide
- CI workflows for Go
- Switfbar plugins
- Leetcode solutions
- Personal site
- Personal wiki
go-simpler
Link | Source | Stack: Go, HTML, CSS
A collection of Go packages built with โค๏ธ
This is where most of my Go projects live. It started as a few packages hosted on my personal account, but at some point I thought it would be cool to create an organization. The goal is to eventually make it a community of people who share the same love for minimalist Go packages.
As you probably know, Go requires importing packages with the full URL. Given the direction GitHub has taken, I didn't want to depend on it too much. That's why I decided to use vanity imports, so if I ever need to change hosting, it won't affect my users.
env
Source | Documentation | Stack: Go
๐ Load environment variables into a config struct
This was one of my first open source projects. I wasn't happy with the mainstream config libraries for Go, because I find them bloated with features (looking at you, Viper). Being a fan of the 12factor methodology, I decided to focus on environment variables.
While the implementation is straightforward, working on it helped me to learn a lot about designing a good library API. During development, the API went through multiple iterations, including functional options. In the end, I decided to keep it as close to the standard library as possible, since that is what all Go developers are familiar with. I kept only essential features, while allowing user-defined extensions via Go interfaces.
I may add some convenience helpers in the future, but for now I consider this library mostly complete.
sloglint
Source | Documentation | Stack: Go
๐ชต Ensure consistent code style when using log/slog
I was super excited when structured logging finally made it into the standard library. I was less excited about some of the API choices made, specifically supporting two argument types behind
...any
. I'm actually fine with both styles, but I'd rather have a separate set of functions for each.It's common to fix Go problems with static analysis (see vet checks), so I decided to take the same approach to make using
slog
in production a bit more pleasant. That's howsloglint
was born, and today, with a lot of checks added, I consider it a good supplement toslog
.Since
sloglint
is integrated intogolangci-lint,
which you probably already use (if not, you should), it's super easy to give it a try, especially if you're just getting started withslog
.
musttag
Source | Documentation | Stack: Go
๐ Enforce field tags in (un)marshaled structs
This linter is a bit more opinionated, but I find it useful in almost any project that has some sort of communication. The idea is that when Go struct tags define a contract between parts of the system (e.g.
json
for REST API), they should be written explicitly to avoid accidentally breaking the contract.
goversion
Source | Documentation | Stack: Go
๐ฒ Easily switch between multiple Go versions
I once needed to test a project with multiple Go versions to find a regression bug. Although Go already supported installing multiple
goX.Y
binaries, the project had thego
command hardcoded everywhere, so it was quite inconvenient to test with different versions. The solution I came up with was to temporarily symlinkgo
togoX.Y
, so I quickly wrote a script to do just that.It worked quite well, and based on this script I built
goversion
, a full-featured Go version manager. Unlike analogues, it's cross-platform (yes, I even tested it on Windows) and depends only on Go itself. Although Go 1.21 later introduced a similar feature, I still usegoversion
for explicit version management.
sloggen
Source | Documentation | Stack: Go
๐ชต Generate domain-specific wrappers for log/slog
This project was initially born out of the same complaints about the
slog
API that led to the creation ofsloglint
. The classic answer to any API problem is to wrap it.sloggen
does just that: it generates wrappers from a simple config, so you can easily adjust theslog
API to your specific needs, such as allowing onlyslog.Attr
fields or making all functions accept a context.
sloggen
is useful even if you're happy with the vanillaslog
API: it can be used to generate key constants and custom levels with all the necessary helpers. Also, if multiple services share the same domain, ansloggen
config can be used as a single source of truth.
assert
Source | Documentation | Stack: Go
โ๏ธ Assertions for the standard testing package
I'm not a fan of testify. I find its API clumsy (e.g.
want
beforegot
) and easy to misuse (to the point that testifylint exists). I get that in the Go community it's the assertion library, but for my personal projects I prefer something simpler.I used to carry a few useful assertions with me, but after many projects it became harder to keep them up to date in all places. I combined them into this package, although the code is still small enough to just copy and paste, which I find preferable for libraries (I'm a sucker for empty
go.mod
).
errorsx
Source | Documentation | Stack: Go
๐งจ Extensions for the standard errors package
This is just a bunch of helper functions for error handling that I used to copy between projects. While I wish some of them were in the standard library, I understand why they are not.
queries
Source | Documentation | Stack: Go
๐ท Easily build SQL queries and scan the results
The one thing in software development that I have never understood is ORMs. I mean, as a backend developer you have to work with SQL anyway, so why add another abstraction on top of it? On the other hand, I think query builders are almost always useful. This is yet another one, but unlike most query builders, it is based on string formatting. Think of it as the
fmt
package + special verbs for query arguments. This is probably the closest you can get to writing raw SQL with the benefits of a query builder.As for the query scanner, in my experience, as soon as you need a query builder, you almost always want to conveniently scan query results into structs, so why not include it in the library as well?
check
Source | Documentation | Stack: Go
โ๏ธ Write any validations declaratively
This was a fun little project, sort of a proof of concept. While it helps to save a few lines, it does not necessarily make things more readable, so you should probably not use it.
libds
Source | Stack: C, Make
๐งฑ Data structures implemented in C
While I feel pretty comfortable with programming in general, I have always struggled with two things: low-level stuff and DSA. I also find that the best way to learn a new technology is to build something with it. So I decided to kill two birds with one stone and learn C by implementing fundamental data structures. I started with a hash table because it's probably my favorite one. I had a lot of fun writing this library, and I'd like to dive deeper into low-level programming in the future.
I also really liked the idea of explicitly passing allocators from Zig, so I added support for custom allocators to this library.
dotfiles
Source | Stack: Lua, Python, Shell
๐๏ธ My dotfiles for macOS and Linux
I just love it when I can turn a new machine into my own by running a single script. I think it's totally worth the time spent on all these configs.
The main highlight here is probably my Neovim config, as it took the most effort. It's my primary editor these days and the main reason to learn Lua.
It was such a relief when I finally took the time to organize all this stuff properly. Now my precious dotfiles are safe forever!
porkcron
Source | Stack: Python, Docker, systemd
๐ Automatically renew SSL certificate for your Porkbun domain
porkcron
= Porkbun +cron
. As always, it started as a tiny script, but grew quickly with convenient configuration, installation helpers, and support for Docker and systemd. It now handles certificate renewals for all my websites.
Go styleguide
Link | Stack: Markdown
I have always liked Uber's Go styleguide. With a few exceptions, I agree with all of its points. As I gained more experience, I came up with some preferences of my own. I find them a bit too opinionated to be upstreamed, so I wrote this document instead. It serves as general recommendations for contributors to go-simpler.
CI workflows for Go
Source | Stack: GitHub actions
I find the ability to reuse jobs and maintain them in a single place to be a great feature of GitHub actions. I miss something similar in other CI systems. This collection powers up all my Go projects.
Swiftbar plugins
Source | Stack: Python
I like the idea of putting the output of any script in the menu bar, it's simple yet flexible. It works well for me for things like package manager updates or quick access to Docker containers. Swiftbar is only available for macOS, but as I slowly move everything to Linux, I may port my plugins to a similar app as well.
Leetcode solutions
Source | Stack: Go, Python
There are not many solutions here because I quickly lost interest in solving problems without a clear goal. However, I'm going to get back to it after I spend some time improving my DSA skills.
I prefer to write solutions in my local environment, so I also implemented a problem template generator, which grabs everything needed from the LeetCode API.
Personal site
Link | Stack: HTML, CSS, Go
I have always liked coming across personal websites while browsing the web. It feels cozy to navigate hand-crafted pages compared to the corporate web. I also find it a great way to get to know a person: unlike social media profiles, the whole website is yours, not just the content. I wish more people would create personal websites these days.
Mine is built from scratch with vanilla HTML/CSS and Go for static generation. I didn't want to use any fancy frameworks or pre-built themes, just the good old reliable tools. I'm far from frontend development, so this is probably the best I can do for now in terms of developing websites :)
Personal wiki
Link | Stack: Markdown, Go
Not much to add here, see the wiki page.