2025 was my first year as a developer. And as I mentioned here, it wasn’t an easy year. Without going into too much detail, I went through several management changes throughout the year—which, unsurprisingly, disrupted continuity and made it harder to keep our roadmap moving forward.
Still, near the end of the year, we managed to deliver an internal AI project. I can’t share the repository because it isn’t open source and was built exclusively for the company. Even so, I think it’s worth writing about, because I learned a lot from the process.
Project scope
The initial scope was to build an application where users could:
- Interact with multiple AI models
- Create and use custom agents based on those models
- Have administrators manage access profiles, create user groups, add users, and register external AI models using API keys
We had a little under a month and a half to deliver a pilot that would be presented to headquarters in Spain. So I immediately met with my manager to share a few ideas.
Architecture and approach
I suggested we build a full-stack interface and a backend. The client would communicate through a proxy layer and connect to a RESTful API on the server. That API would then interact with local models via Ollama and persist data in a PostgreSQL database.
I was responsible for the interface, and I chose Nuxt—a meta-framework for Vue.js that I hadn’t used professionally before, but already knew about. And honestly: working with Nuxt and its ecosystem ended up being one of the best decisions for this kind of application.
Prototyping and UI development
As soon as we aligned on the direction in a closed-room session, I started thinking about screen prototypes. I’m not a web designer, and my design knowledge is limited, but a couple of tools helped a lot: v0 and Figma Make. They can generate complete interfaces—from design to code—but I didn’t plan to reuse their code directly. I used them mainly as guidance and inspiration.
For the actual development, I started from an official dashboard template from NuxtUI. Then I customized it, taking inspiration from the UI outputs generated by the tools above. One of the great things about Nuxt is that it uses file-based routing by default—so as you create pages, routes are automatically created as well.
And of course, I used AI throughout the process to speed up implementation. With that support, I finished the static UI in five days. After that, I began turning the interface into a dynamic application by integrating it with local data and real APIs. I implemented composables to manage state across components and pages.
A clean integration pattern
As my manager delivered the backend APIs, my job was mostly to wire the Nuxt proxy into the composables using a consistent pattern:
Component → Page → Composable → Proxy / BFF
This approach kept maintenance simple: each module had a single responsibility, and it became much harder to accidentally break the client.
Rendering AI output safely
Another interesting challenge was formatting model outputs. Most responses came back as Markdown—but the raw output looked “unstyled,” almost like plain text. So I decided to render Markdown as HTML for a better reading experience.
That introduced its own challenges: beyond improving visuals, I needed a sanitizer to prevent any malicious HTML from being injected into the UI.
Writing a Markdown renderer from scratch would be exhausting and time-consuming, so I looked for existing solutions—and, unsurprisingly, the Nuxt ecosystem already had a strong option: Nuxt MDC. It gave me everything I needed, and the moment I rendered the first response properly, I was reminded how mature the ecosystem is.
I even started rendering LaTeX as mathematical equations and Mermaid as diagrams, since MDC supports plugins that make this kind of extension straightforward.
Final result and takeaways
So what did we end up with? Not just a prototype to present, but a tool that was already minimally functional. We didn’t implement every final feature—but we didn’t need to for the pilot. It was enough to demonstrate value clearly.
This experience also reinforced something I strongly believe: the idea that AI will “steal developer jobs” doesn’t match reality—at least not in the way people claim. What worked best for us was treating AI as a copilot: I guided it, reviewed decisions, and took control whenever needed.
Even if we get to a future with extremely powerful AI, someone will still need to steer it, apply judgment, and make trade-offs—whether the task is small or large.
My main takeaway from this project is simple: don’t be afraid to use the right tools for the job. Learn them, leverage them, and use them to your advantage.