GoLazy Blog
Hello World, GoLazy
Why GoLazy exists, why the site is still marked as AI-generated, and why the framework is not trying to be neutral.
At some point, after building enough web applications, you start recognizing the same invoice.
New product, new repo, new domain. Then the same questions arrive, wearing a different hat. Where do routes live? Where do controllers live? Are we rendering on the server or smuggling an application into the browser and calling it a page? How do assets work? Where do background jobs start? Where does configuration go? What does local development mean? How do we upgrade this thing six months from now, when everyone has forgotten why the weird bit exists?
Every project answers those questions. Many projects pretend they are not answering them. That is how you get "lightweight" systems made of twelve libraries, three build tools, a README full of rituals, and one engineer everyone is afraid to lose because they remember where the bodies are buried.
GoLazy exists because I am tired of paying that tax.
It has been around since 2022. We have used it internally on several projects, usually because we needed a small web application around something else we were building: an admin, an operational tool, a web interface for a service that did not need an entire frontend-and-backend production. For most of that time, it was useful but unfinished.
Over the last two months, we finally had enough time to polish it into something that could be shared. “Could be shared” is doing some work in that sentence. This is the first public hello, not a declaration that every corner is finished.
This first post is here to explain what GoLazy is, why I am building it, and why the website currently has a warning that the content is mostly generated by AI and has not had deep review by a human.
That warning is not decorative. It means what it says.
GoLazy is heavily in development. The framework is still in the v0.1 line, and my main focus is not polished documentation, launch copy, or convincing people to use it in production. My focus is closing the API surface and making the framework comfortable to work with every day.
That means routing, controllers, views, assets, services, release cycles, upgrade paths, and the local development loop. The boring parts. The parts that decide whether a framework becomes a useful tool or just a clever pile of packages with a logo.
Why I am building this
I am Guillermo Alvarez. I have been building software for more than 20 years, and writing Go for more than 10. I also write about engineering leadership, teams, and shipping software at cientifico.net, where I keep discovering that most software problems eventually become responsibility problems. Annoying, but convenient for recurring themes.
Before Go, a lot of my thinking about web development came from Ruby on Rails.
Rails changed how many of us thought about building web applications. It showed that development can be fast when a framework gives you a strong application shape, common conventions, and tooling that removes repeated decisions. I still believe that lesson is correct.
I do not believe Rails is the only way to build quickly.
Go has a different character. It is explicit, boring in useful ways, easy to deploy, and good at staying understandable as systems age. I like those properties. They are not glamorous. They also do not page you at 3 a.m. because the toolchain wanted to express itself.
But I never found a Go web framework that felt like Rails while still feeling like Go. Many frameworks were perfectly capable, but they came with a different structure, a different set of conventions, or a different idea of how a Go application ought to be written. I kept wanting something that used the standard library and standard Go ideas where possible, while still giving an application a coherent shape.
The Go ecosystem often leaves every application to assemble its own framework from many small pieces. That can be powerful. It can also mean every team has to rediscover the same answers, then document those answers, then enforce them, then repair them after the next refactor, then rediscover them again because apparently we enjoy seasonal suffering.
GoLazy is my attempt to put the tools I have used over the last two decades into one coherent Go application workflow.
The model
The model is simple: server first, Go underneath, conventions where repeated decisions add nothing.
GoLazy is not trying to be neutral. It has a shape.
It is for backend-rendered applications, simple mental models, strong conventions, and less frontend ceremony. It ships without choosing a database or an ORM. Business behavior belongs in services. Controllers translate HTTP. Views render the result. I think of it as service-view-controller rather than model-view-controller, and that choice deserves its own post.
Around that boundary, GoLazy provides an opinionated path for routing, controllers, views, embedded and fingerprinted assets, Tailwind, Turbo, SEO, caching, jobs, service lifecycle, development, deployment, and upgrades. Not every application needs every part. The point is that the parts share one application model instead of arriving as a bag of unrelated decisions.
Backend rendering is not a nostalgic regression. It is a reasonable next step after years of overcorrecting into single-page apps, hydration problems, client-side state synchronization, build pipelines, and frontend frameworks eating everything that was not nailed down.
Some of that complexity is real. Some of it can fuck off.
This does not mean every application should be built with GoLazy. Some products need a heavy client. Some teams need separate frontend and backend systems. Some organizations are large enough that the ceremony is not accidental; it is load-bearing.
But a lot of web work is smaller than that. You may already have a service and need a small admin. You may need to expose a useful web interface for something you have built. You may want to ship a product without first creating two applications, two deployment paths, two sets of conventions, and a peace treaty between them.
Fine. Use the tool that matches the problem.
But if you are building a product where most pages are still pages, where the backend owns the domain model, where deployment simplicity matters, and where you would rather ship the feature than build a tiny distributed systems symposium around a settings screen, GoLazy is the direction I care about.
The framework is also not optimized to win synthetic request benchmarks. Go is already fast enough for the applications I care about. I care more about the time between an idea and a production application, and whether that application is still understandable when I have to change it six months later.
That does not mean runtime behavior disappears behind developer-friendly magic. The development tools can inspect routes, services and their dependencies, jobs, assets, cache behavior, requests, logs, traces, memory, and allocations using the Go runtime's own machinery. The boring path should be visible, or it eventually stops being boring.
A project that took time
I started working on GoLazy in 2022. For a long time it was a project I kept returning to, but never had enough focused time to polish into something genuinely useful.
That has changed because of AI, but not in the way people sometimes mean it. GoLazy is not a framework generated from a prompt. A lot of code in the current version is AI-assisted, and some of it is generated, but it is based on an architecture and a set of opinions that existed before this wave of AI coding tools.
What AI has changed is throughput. Right now, a large part of my day is reviewing prompts, reading generated code, rejecting things, accepting things, and making architectural decisions. This is less glamorous than the demos make it look. It is mostly judgment, editing, and saying "no" to code that was technically valid and still a bad idea.
The challenge of building web applications in Go has not disappeared because AI can write code. If anything, the question is sharper now: what is the smallest useful shape for the application you actually need? AI can produce another frontend, another API layer, another build pipeline, and another pile of glue very quickly. It does not make those things necessary.
Some of those decisions will be good. Some will probably be bad. That is what v0.1 is for. If every decision were already obviously correct, I would be suspicious. Or lying. Probably both.
So yes, it took time. The work started in 2022, and the first useful public version is only arriving in 2026. But now it is here.
Shipping solutions, not tech
As engineers, we are responsible for shipping solutions, not technology.
That sentence is one of the main reasons GoLazy exists. The point is not to create a framework because frameworks are interesting. The point is to make it easier to turn an idea into a working product without spending the first weeks wiring the same infrastructure again.
I want GoLazy to provide the boring path: create an app, add routes, render pages, work with assets, run background jobs, test the result, deploy it, and upgrade it later. The framework should make those things feel connected without hiding the Go code underneath.
This also means GoLazy is not designed by committee. Serious contributions, critique, and disagreement are welcome. But disagreement is not the same thing as a veto. The project has a center of gravity. It will say no to some abstractions, patterns, dependencies, and architectural fashions. Not because I enjoy saying no, although it has its moments, but because a framework without taste becomes a box of spare parts.
Some technical decisions behind GoLazy need their own posts. There will be later series about why the framework is shaped this way, how the API boundaries are chosen, why some conventions exist, and where I think Go web development can be simpler.
This post is only the starting point.
Why the guides are not fully reviewed yet
The current guides are useful, but they should be read with care. They are part of the development process, not the final promise.
Right now, I am using AI heavily to help document the moving target while I work on the framework itself. That is practical, but it has a cost: generated documentation can be incomplete, too confident, or slightly behind the code. Documentation that sounds confident while being subtly wrong is one of software's more annoying little gifts.
Until the API surface settles, repeatedly doing a deep human review of every guide would take time away from the work that makes the guides true. Reviewing a guide for an API I might change next week is not discipline. It is theater.
The plan is to treat v0.2 as the point where that changes. Once GoLazy reaches that milestone, the guides should be human reviewed, the core workflow should be stable enough to test seriously, and the framework should be ready for more people to try with clearer expectations.
Until then, the warning stays.
If you are reading the site today, treat it as a public workbench. The project is real. The code is moving. The ideas are being tested in the open.
The promise is not that everything is finished. The promise is that GoLazy is being shaped toward a practical way to build and ship Go web applications without carrying more machinery than the product needs.