VOOZH about

URL: https://dev.to/mojatter/i-became-a-minio-refugee-so-i-built-a-replacement-with-ai-3ig

⇱ S2 – My MinIO Alternative Built with AI in a Few Days - DEV Community


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

👁 Web Console

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.