Back to Writing

Learning from Failure: MonsterUI

By Isaac Flath·January 26, 2026
Learning from Failure: MonsterUI

Learning from Failure: MonsterUI

I spent months building MonsterUI. Now, when people ask if they should use it, I hesitate. I often get questions like: "Why aren't you using FastHTML and MonsterUI?", "You could do that quickly with MonsterUI.", and "Should I use MonsterUI?"

MonsterUI changed me. It redefined what I love to build, yet I couldn't explain why I stopped using it.

Now I know why: I felt uncomfortable admitting that I failed. Not a catastrophic failure, I learned a great deal while building it, but it failed to become the tool I actually wanted to use.

Original Goals: I wanted to build great-looking UI in Python with no verbosity or boilerplate or repetitive inline class strings, without a separate templating language like Jinja. I also wanted to test owning a project with notebook-based development (nbdev) on a team setting and explore building web applications in notebooks.

I've explored all three paths, and my views have stabilized (though I'd welcome seeing something that de-stabilizes them). This post will focus on the library aspect.

MonsterUI Development

I started MonsterUI as a newcomer to web development, having never built a UI. But the project taught me to love the work. I built applications, cards, blogs, and demos with surprising speed. I was optimistic and completely committed.

But hacks piled up as commercial work outgrew demos and learning projects.

People call MonsterUI a wrapper for FrankenUI. It was, at first. Now it is more, but the architecture is so confusing that most can't understand the difference. As the creator and architect, that's my fault. I renamed it from fh-frankenui to MonsterUI to communicate this, but changing the library name is not a real fix.

I piled dependency on dependency. I built a Markdown rendering capability with dictionary styling and hand-coded Tailwind navbars. I added custom JavaScript for scroll-spy and pulled in Daisy UI for toasts and spinners. To make example UIs easier, I integrated DiceBear and Picsum external APIs for placeholders. I blended FrankenUI with Tailwind to fix typography, then we bolted on HighlightJS and KaTeX for math and code.

Every new feature solved a specific problem and felt important at the time. I believed combining them would create something powerfully convenient. But the result was a mess: a user now had no easy path extend or customize their UI with MonsterUI.

To extend a component, you need to know its origin. Is it Tailwind? FrankenUI? UIkit? Daisy UI? Custom? Then you check that library’s documentation to see if that option exists. If an option in a library wasn't exposed in MonsterUI, you could often pass it as kwargs. I deliberately limited arguments to keep things simple and rely on kwargs for customization: 80% of what you need, fast.

In practice, users couldn't know what was available without digging through source code and dependent library documentation. And it was hard to form a mental model of the library, since its guiding principle was too loose.

The library was theoretically flexible but practically rigid. For quick demos or simple projects, it still works. But as applications grow, specific UI needs emerge, and MonsterUI becomes a burden that's hard to remove.

Today, MonsterUI runs on outdated versions of Tailwind, DaisyUI, and FrankenUI. Migrating would take enormous time. If I were to do it, I'd use Tailwind alone without higher-level component libraries. I would decouple for better separation of concerns in different libraries (or plugins).

I won't pursue that, though I did do some exploration of what the next version might look like for air. You can read about the architecture, or explore the prototype library in that same repo.

For my own projects, I now use Jinja. I used to hate it (my hatred for it partly inspired MonsterUI): why learn a templating language when Python has functions and composition? But Jinja's tooling and ergonomics pay off as complexity grows.

What I learned

This project changed my approach to building software. While the final product had flaws, the process of creating it provided a fundamental education in three areas.

Web Development

I started this project never having built for the web. By building MonsterUI I had to learn HTMX, javascript, css, tailwind, and theming. I’ve been a product manager, a dance teacher, and a data scientist. I’ve worked in manufacturing. Now I can also build for the web. And I now love building for the web.

Documentation Creation

Writing good documentation is difficult. I learned that developers value minimal, concrete examples over only dense API references.

I rebuilt the documentation several times. I initially used nbdev, but it presented three distinct problems:

  • Collaboration: The structure confused people, which discouraged collaboration. If a user or contributor wanted to fix a small bug, they first had to learn a complex tool-chain and new IDE. Most didn't bother. This is a general problem with nbdev.
  • Rigidity: The framework made it difficult to include the dynamic examples the UI library requires, because nbdev serves static sites. Static sites are fine for most documentation pages, but not as good of a fit for a web dev library with server side capabilities IMO.
  • Technical Friction: The tools fought each other. Because I was building a UI library inside a notebook, the styles often clashed. I spent a lot of time fighting UI rendering inside of notebook environments. These may not be big deals for many libraries, but for a UI library faithful rendering of the UI is critical!

API Design + Separation of Concerns

I never understood why tools relied on "clunky" plugin ecosystems or groups of libraries that work well together. I thought I could build common features directly in the main library and do it right. I was wrong.

MonsterUI's was meant to be a (mostly) all-in-one solution. But every convenient feature I added made the library harder to understand. I tried to untangle the mess with separate modules (franken and daisy), but it wasn't enough.

I began studying how successful projects like FastAPI, HTMX, Mantine, React, and NextJS stay out of the user's way. This diversification gave me a more complete understanding of web development, which I may not have done without experiencing the friction myself.

The MonsterUI project kick-started my interest in web development. I've now built SaaS apps and consulted on web development, and it's part of the work I enjoy most.