The Making of Oso Golf: A Full Stack Deep Dive
How we approached design and architecture to create Oso Golf.
Oso Golf is one of the most fun projects we’ve ever worked on. Oso is an authorization as a service product, and Oso Golf is a Regex-Golf-inspired game that challenges you to fit a set of authorization constraints using a minimum number of roles and attributes.
How It Works
Oso Golf is open source on GitHub so you can take a look yourself. Below is the key points of how Oso Golf works.
Currently hosted on Vercel. Originally hosted on Netlify. We migrated earlier this year because Oso already used Vercel for other JS apps and migrating was easy. More on this later.
Backend is a collection of framework-free functions designed for maximum portability. Functions interact with MongoDB using Mongoose, including logging to a Log collection in MongoDB.
Frontend is in Vue 3 with an entry point as a script tag in index.html. Frontend uses Tailwind for layout, and is bundled with a minimal Webpack config.
On Migrating From Netlify to Vercel
We’ve been saying for a long time that cloud is largely commoditized. Moving Oso Golf from Netlify to Vercel was a relatively small project, made non-trivial by some quirks like Vercel requiring ESM for API handlers.
For backend work, we’re big proponents of “keep all business logic in framework free functions”. When you have framework free functions that take in a params object and return a result, plugging them into any framework you need is fairly trivial. Even ESM vs CommonJS becomes largely a moot point because you can just import your CommonJS logic from an ESM wrapper.

In short, we love Netlify, it is typically our first choice for deploying apps due to their excellent DX and reliable product. But Vercel has its benefits too - if the client wants Vercel, we won’t fight them on it.
On MongoDB For Logging
For years, we avoided piping production logs into MongoDB, holding onto the misguided belief that “MongoDB isn’t well-suited for insert-heavy workloads.” However, in practice, even when sending multiple gigabytes of logs daily to a medium-sized Atlas cluster that also handles production traffic, MongoDB hasn’t faltered in our experience—it doesn’t even break a sweat.
In the case of Oso Golf, the traffic is much lighter, so performance isn’t a concern at all. The real advantage lies in the ability to leverage our deep MongoDB querying expertise to search logs efficiently. While platforms like Netlify and Vercel offer UI tools for browsing logs, their simple text search features pale in comparison to the power of MongoDB’s query language—especially in the hands of a developer with 12+ years of MongoDB experience.

On Tailwind for UI
For Oso Golf, we drew heavily from Tailwind UI for layout elements. At the time, we were still early in our Tailwind journey. If we were to build a similar project today, we’d lean even more on Tailwind UI. We’ve already shared why we love Tailwind, but the short version is this: Tailwind makes layout copy-and-pasteable in ways other CSS frameworks simply can’t, thanks to its approach to cascading.
Copying foundational elements like button layouts or navigation bars saves an incredible amount of time. The brilliance of atomic CSS lies in two key advantages: 1) copying a layout won’t disrupt the rest of your design, and 2) every detail of the layout logic is self-contained in the code you copied. Adjusting minor details—whether it’s changing colors, alignment, or text—is always straightforward and painless.
E2E Testing the Full Stack in Mocha
The killer feature of full stack JavaScript is the ability to test the entire stack in a test runner like Mocha. You can spin up your backend, initialize your frontend, and simulate interactions between the two—all without relying on external processes. In July, we introduced a basic end-to-end test suite for Oso Golf, structured as follows:
Start an Express server with the same route structure as the Next.js app. Remember that the backend functions are framework-free? Yeah, framework-free helps for testing too.
Interact with the Vue app by calling methods and asserting on the app state
This setup isn’t flawless. It doesn’t test at the level of DOM events like “click this button,” and it doesn’t account for re-rendering the app—something we haven’t quite cracked yet. However, it effectively tests about 98% of the stack, all within a single process. That level of integration and simplicity is remarkable.
Takeaways
Oso Golf’s architecture takes advantage of several full stack design principles that we want to highlight:
Framework-free business logic. The business logic of “start a game” or “check the solution” should be easy to run from the Node shell, from a scheduled task runner, in Vercel, in Netlify, or anywhere else.
Leverage your existing skillset. We disagree that you should use the “right tool for every job”, you are better off using a tool you’re familiar with to do the job (if possible) rather than fumbling with unfamiliar software.
Copy existing layout elements where possible, and add what you need. Developers love to joke about “spending the whole day adding 2px margin to every button.” Keep that as a joke, not as real life. Now keep in mind this is for full stack devs - if you’re an excellent designer then do pixel perfect layout work yourself.
With AI, modern deployment tools, Tailwind, cloud db platforms, etc. it is an amazing time to be a full stack developer. It seems like not too long ago where we had to fumble with setting up Kubernetes clusters to deploy Node apps without Claude.ai to debug every error message, and try to glue together horribly broken Bootstrap packages off of Bower before giving up and re-implementing the layout ourselves in vanilla CSS.
The first two principles above, framework-free business logic and leverage your existing skillset, are ones that long-time readers will remember us espousing for years. Copying existing layout is a new principle that we’re working with now because of Tailwind.
Oso Golf’s architecture embodies principles that aren’t just technical—they’re practical. These principles help us ship fast by avoiding wasted time.
The future of full stack web dev is bright—and there’s no better time to be part of it.