The micro misunderstanding
I still remember the first time someone pitched microfrontends in a planning meeting. It sounded like magic. Modular! Scalable! Independent teams! But the reality turned into a mess of dependencies and inconsistent user experiences.
Whenever new technology patterns start to gain traction, a familiar tension emerges: Are we doing this because it genuinely solves a problem we have? Or are we doing it because it looks good on our architecture diagram? Or even worse, it's just someone's pet project.
All motivations can be valid. But as with most things in engineering, context is everything.
Today, I want to talk about a pattern that often gets applied for the wrong reasons: back-end for frontend (BFF), especially when mixed with micro-frontends.
A pattern born from need
BFF isn’t some shiny new thing. It gained attention after Sam Newman described it in 2015 in his book Building Microservices. He talked about shaping APIs to match what each frontend actually needs, a web app, a mobile app, or even a smartwatch interface. Instead of one generic backend for all, you build adapters specific to each UI.
Before it had a name, people were already doing this with Node.js or proxy servers. But once the term caught on, tools and practices followed.
Eventually, BFFs became easier to build and some tools made BFFs much more accessible:
- Express.js: Lightweight and flexible, perfect for custom endpoints.
- GraphQL / Apollo Server: Great for shaping APIs per client, especially useful for mobile apps.
- Next.js API routes, Remix loaders, React Router v7: Modern frameworks that mix frontend and data loading naturally.
- tRPC: Full-stack type safety, great for monorepos where frontend and backend live together.
You no longer need big backend infrastructure to get started with a BFF.
Why BFF matters for scaling teams
BFFs help teams move faster. Instead of building generic APIs, you shape them around the frontend needs. If your backend evolves more slowly than your UI, the BFF acts as a helpful buffer.
But here's a lesson I learned the hard way: too many tiny BFFs can create their own problems. Duplicated logic. Confusion. More maintenance. A better way is to share and modularize where you can.
When frontend teams can shape their data, iterate, and deploy independently, the feedback loop shrinks. Dev frustration drops. Shipping gets easier. That’s the dream.
But then comes the big question: if you have microservices, do you also need microfrontends?
The micro misunderstanding
Microservices and microfrontends get bundled together in conversations, but they solve different problems.
- Microservices: Break backend responsibilities into small services. Helps with scale and parallel work.
- Microfrontends: Split UI into parts owned and deployed by different teams.
One is about APIs. The other is about visuals and user flows.
And here’s the catch: they don’t have to go together. In fact, unless you’re operating at the scale of Spotify or Amazon, microfrontends might be overkill.
Frontend teams rarely work in total silos. Shared design systems, components, and user flows create natural overlaps. Trying to isolate too much just makes life harder.
So no, you’re not running multiple startups in parallel just because you have microservices. There still needs to be orchestration and shared thinking at the UI layer.
What about monorepos?
Enter monorepos. They offer a structured middle ground. A single codebase with multiple apps and shared packages. You can slice it by feature, domain, or team. Tools like Turborepo, Nx, and pnpm workspaces make it manageable.
You get modularity without runtime stitching. It’s a nice blend of speed and structure.
Takeaways
Tech loves patterns. We see what big companies do and want to emulate it. But here’s the hard truth: what works for them might not work for you.
Architecture isn’t about cool diagrams. It’s about how teams work together. Microservices, microfrontends, monorepos, BFFs, these are just tools to solve specific problems.
What I’ve learned is this:
The best architecture matches your team, not your ambition.
Before you adopt something new, ask:
"Is this solving a real bottleneck for us?"
"Or are we just following a trend?"
Patterns are helpful. But context is what makes them work.
What architectural choice did you regret, or absolutely love, because it truly fit your context?
Get posts in your inbox
Subscribe to my Substack newsletter for the latest posts and updates.
Subscribe on Substack