Matt Mueller: Building Modern Web Applications Faster With Bud

Bud is a brand-new Web framework. It takes the best of Go and JavaScript to help developers focus on solving actual problems without worrying about type safety, performance, or deployment.

Matt Mueller: Building Modern Web Applications Faster With Bud

One thing that strikes people at first is when they hear me talk about Go being an under-appreciated choice for Web application development. Ironically, although most Go developers use the language to build APIs and Web services, there aren’t really many industry-backed solutions for full-stack Web app development.

That is why when I saw Bud get released, I had no choice but to invite its initiator and original creator, Matt Mueller to tell us more about the framework and how he plans to bring some fresh air into the field.

What is Bud?

Bud is a framework for rapid development of Web applications using Go and a popular frontend building framework called Svelte. It was inspired by giants like Ruby on Rails, Next.js, and Laravel and is on a mission to reduce the cost of building, launching, and maintaining rich Web applications. In addition, Bud takes the best of both Go and Svelte to help developers focus on solving actual problems without worrying about type safety, performance, or deployment.

In a familiar Rails-style fashion, Matt kicked it off with a short 15-minute teaser video on how to build a Hacker News clone in 15 min:

It has been a fast-moving journey upward ever since. I thought I’d let numbers talk instead. For only a few weeks since its initial release, Bud has gained almost as half GitHub stars as Buffalo, which has been around for many years. That’s more than impressive!

Bud's rapid growth on GitHub is impressive.

Without further comments on my side, let’s hear Matt’s story and his plans for the future of Web development.

Tell us a bit about yourself. Who is Matt?

I am a full-stack developer currently working as a Product Manager at Prisma.io working on their database clients. I have spent much of my free time and professional career building open source tools for the Node.js ecosystem. Like Go, the Node.js community has developed a preference for the Unix way of building sharp, independent tools rather than massive frameworks.

For quite a while, I kept building lots of these modular tools until I stumbled upon the Laracasts from Jeffrey Way and realized how effective you could be in the Laravel ecosystem.

I have way too many ideas for my limited time. I needed a way to speed up going from concept to production. The advantage of bundling modular tools into a web framework is that you can make additional assumptions about where files are located and what other tools are available. That is how the idea of Bud came along.

How did you come to Go?

To be fair, I've spent most of my professional career writing Node.js. I started in 2011 and was probably among the first 100 developers working with Node.

The transition to Go came much later (2016) when working solo on a conversational Slack bot called Standup Jack. The app featured a RabbitMQ message queue that fed workers to process and respond to Slack messages. However, I kept running into problems of various kinds. The most popular RabbitMQ client for Node at the time was flaky, or when it wasn't the problem, some other part would.

Node.js is a great stack to work with, but the level of many modules at the time wasn't mature for production use cases. It also didn't help much that this was right at the time when everyone decided to come up with their unique flavor of JavaScript.

I stumbled upon Kevin Burke's The Frustration and Loneliness of Server-Side Javascript Development. This post resonated with me because I was feeling the same frustration. I was also casually talking to TJ Holowaychuk, who wrote Farewell Node.js where he gave his reasons for switching to Go. All this got me looking for alternatives. On the last few days of a vacation, I cracked open the Go documentation and started learning Go. I had decided to try and rewrite the message queue in Go and see what happens. The rest was history.

How did Bud come to be?

Interestingly enough, until recently, I did not seriously consider major Web frameworks. I tried Rails back in University, but having all those tools and options in the same bundle made little sense to me then. As I mentioned, I have grown accustomed to building small and modular tools. With time, I realized that when you combine a few of those, you get a framework.

Bud is exactly that - a smart grouping of tools and practices. Like, as having Svelte and React be first-class citizens right from Day One, so one won’t feel limited by a traditional templating language. Those were meant to save me and eventually other people time to work on the things that matter.

Bud started as an experiment in code generation. I had discovered through experimentation and at Prisma, that code generation could give you friendly, type-safe APIs while generating down to potentially low-level operations. With Bud, I wanted to see if I could go beyond just generating models and code-generate an entire Web framework.

Is using a JavaScript UI library instead of Go's template-rendering not bad for SEO?

SEO is crucial to me. I learned this at Authory, where we built a way for journalists to promote their writing from a single place. Their writing needs to be reachable by search engines.

Nowadays, you can have both the smooth developer experience of a UI library like React or Svelte and be 100% search-engine-friendly. Using a clever technique known as server-side-rendering (SSR), modern JavaScript UI libraries allow a large portion of a website or application to be pre-rendered on the server. At the same time, both the developer and the end visitor can enjoy the added interactivity thanks to those libraries.

To avoid asking people to install a separate Node.js server, Bud does that on the fly, using the same Go server that handles the rest of the application. I tried a bunch of experiments to pull this off but ultimately settled on embedding V8 right as part of the Web server. It uses Roger Chapman’s impressive v8go library.

GitHub - rogchap/v8go: Execute JavaScript from Go
Execute JavaScript from Go. Contribute to rogchap/v8go development by creating an account on GitHub.

In your videos on Bud, you talk about extensibility. How do you plan to achieve that?

Indeed, while still a work-in-progress, extensibility is at the core of Bud. Take Bud’s “compiler,” for example. Conceptually, it is simply a filesystem walker that traverses over a virtual filesystem, reading files from that virtual filesystem and writing them to the actual filesystem. The files and directories in this virtual filesystem can point to real files or be backed by generator functions. This allows Bud to be infinitely extended through plugins and generators.

Plugins are conceptually equivalent to those in Ruby on Rails. They allow different Go modules to add files and folders to be used by the Bud compiler as if they were in your application directory. For example, you could install github.com/alice/bud-tailwind into your Bud application that has the file public/preflight.css, and that file would be added to the build as if it were in $APP/public/preflight.css.

On the other hand, Generators allow you to define a trigger function when you try reading from a file or directory. All the core features like controllers and views are generators. We’re still figuring out how to let people bring their own generators. It’s tricky because Go lacks plugin support.

What about database persistence?

Bud will eventually have its own ORM. Luckily, I’ve already built this for PostgreSQL and SQLite, which was why I joined Prisma. It’s conceptually similar to https://github.com/xo/xo but generates many more types of operations. I’ve been using it in all my projects for the last couple of years.

As a fallback for the complex SQL queries, I’d like to integrate sqlc into Bud.

GitHub - xo/xo: Command line tool to generate idiomatic Go code for SQL databases supporting PostgreSQL, MySQL, SQLite, Oracle, and Microsoft SQL Server
Command line tool to generate idiomatic Go code for SQL databases supporting PostgreSQL, MySQL, SQLite, Oracle, and Microsoft SQL Server - GitHub - xo/xo: Command line tool to generate idiomatic Go...
sqlc.dev
Compile SQL to type-safe Go

Is Bud ready to power the next generation of Web applications?

It’ll get there! I anticipate v1.0 coming after we have:

  • Custom layouts and error pages
  • Environments
  • Extensibility
  • Models
  • Migrations
  • Validation
  • Sessions
  • Custom middleware
  • Custom commands
  • Custom transforms
  • Type-safe View props and helpers
  • Basic client-side routing

Many of these features are partially implemented or at least designed. And you will be able to build increasingly sophisticated applications after each new release. I think we’re still about a year away, depending on how much help crops up ;)

Where to go from here?

We’re working on launching the documentation over at livebud.com and improving Bud in the process. This means:

  • Migrating from V8 to Goja
  • Adding custom layouts
  • Creating a tailwind plugin
  • Creating a markdown plugin

More details on this page: https://github.com/livebud/bud/discussions/188

v0.3 Hosted Docs (WIP) · Discussion #188 · livebud/bud
Goals You can effectively build documentation pages using Bud. Deliverable Bud has documentation live on https://livebud.com/ and a demo of the new Bud features that were built to make the document...

Many thanks to Matt, and best of luck on his journey with Bud! Make sure to check out the framework and follow @golivebud on Twitter for the latest updates.