I built an alternative and named it S2 (Simple Storage).
https://github.com/mojatter/s2
More details below, but here's a quick look β it works almost like MinIO via docker compose:
services:
s2:
image: mojatter/s2-server
ports:
- "9000:9000"
environment:
S2_SERVER_USER: myuser
S2_SERVER_PASSWORD: mypassword
S2_SERVER_BUCKETS: assets,uploads
volumes:
- s2-data:/var/lib/s2
volumes:
s2-data:
Why I Built It
I've been using MinIO across several projects, but it went into code freeze and I wasn't comfortable staying pinned to a specific version indefinitely.
What I Learned Pairing with AI
I know most of you are already getting the most out of AI/LLMs β I'm a late starter here.
I kicked things off casually using Google Antigravity (an agent-first IDE powered by Gemini 3.1 Pro) with no paid plan. I wrote the initial codebase myself, and leaned on it heavily for English documentation since that's not my strong suit.
I pushed through to the first commit with Antigravity, but hit the free tier limits pretty quickly. I'd paid for Gemini once before and blew through $200 in two days, so I switched to Claude Code to keep going.
I fully intended to write all the Go code myself β but Claude Code is remarkably capable. Give it a direction and the code comes back almost exactly as you envisioned.
At first I let it handle git commit. Then before I knew it, I was handing off git push and PR creation too. By that point, I'd basically stopped writing code myself.
As I kept delegating, it suggested creating a docs/api-audit.md. I had no idea what that was β apparently it's standard practice in the OSS world. That kind of discovery kept happening, and then it started proposing API redesigns. When I dug into the reasoning, every point made sense. It felt like a new hire who was honestly more capable than me had just joined the team.
Eventually my workflow became: describe what I want at a high level, skim the PR, click merge.
I'd figured it would take a month of working in spare moments to get something functional. Instead, something better than I'd planned was done in a matter of days.
I used to picture myself writing code well into old age. Turns out that may not be how things go. π
About S2
Let me get to the actual pitch.
S2 offers both a MinIO-like server and a general-purpose storage client interface.
MinIO-like S2 Server
It covers the essentials: multipart upload, SigV4 authentication, presigned URLs. Advanced features like ACL and versioning aren't supported, but for "I just want to use an S3 client as-is in local dev and staging" use cases, it holds up well.
Swapping out production S3 or MinIO is just an endpoint URL change.
If you have Docker, one line gets you a running server with a web console at localhost:9000:
docker run --rm -p 9000:9000 mojatter/s2-server
General-Purpose Storage Client: s2env
Backends are swappable via config, giving you something close to Laravel's Storage facade. Switch between S3 in production and osfs locally without touching your code.
// s2.json
{
"assets": { "type": "osfs", "root": "/var/data" },
"prod": { "type": "s3", "root": "my-bucket" }
}
// Same interface regardless of backend
storages, _ := s2env.Load(ctx, "s2.json")
assets := storages["assets"]
assets.Put(ctx, s2.NewObjectBytes("hello.txt", []byte("hello")))
For testing, swap in memfs and you can test object storage code without spinning up Docker at all.
strg, _ := s2.NewStorage(ctx, s2.Config{Type: s2.TypeMemfs})
// Same code as production β no Docker needed
Wrap-up
I became a MinIO refugee and built a replacement with AI. Here's what I found:
- The speed and accuracy were remarkable β I ended up handing almost everything over.
- It gave me new insights along the way and I genuinely learned things.
- The end result was better than what I originally had in mind.
It's a fascinating time to be building software. Give S2 a try!
Credits
The header image was generated with Google Gemini. It includes the Go Gopher mascot, originally designed by RenΓ©e French and licensed under CC BY 3.0.

Top comments (0)