
Show HN: Microfronts – Front-end solution for running multiple frameworks as one - eavichay
https://github.com/eavichay/microfronts
======
coldcode
Right, and ensure you never can fix anything and hire generations of people
who slave over the old crappola until they give up. Meanwhile you wind up with
legacy code from multiple languages/language versions all mixed up like a
junkyard sculpture.

I worked at a major travel company (you know the brand) that ignored its
legacy web+backend for almost 10 years until our parent company basically gave
us away to our biggest competitor (the tech was all abandoned as unusable) who
made us just a marketing brand (also 100% of people laid off in the process).
We couldn't keep up with our competitors as everything was impossible to fix
any more. On the other hand the mobile team I worked with replaced everything
and we were extremely agile in competing (other than being limited by the
crappy back end).

It's not always a good idea to replace everything, but it's also not a good
idea to live with shit either.

~~~
hn_throwaway_99
My thoughts (as someone who worked at a brand of the same parent travel
company as you): It is definitely NOT a good idea to live with shit as it will
kill your velocity long term, so the question is how to replace it? _Every_
single "big bang" replacement I've done, while not exactly a total failure,
was _extremely_ painful. If a tool like this made it easier to piecemeal
replace your legacy code, while showing business value more incrementally, I'd
be all for it.

I agree leaving your house in this "junkyard sculpture" state indefinitely
(love that analogy) will eventually kill your business.

~~~
hinkley
I think the problem here is that we often ask the questions too late. Things
went wrong a very long time ago. A rewrite is declaring bankruptcy, but often
the same actors barely change their behavior and you end up in the exact same
spot again.

I’m starting to fear that the right response, especially considering the Big
Picture, is to let it die. Let some other competitor with fresh ideas eat your
lunch. I suspect these problems are symptoms of a deeper, terminal illness and
palliative care is the best you can do.

------
joncfoo
Micro-frontends are indeed a solution looking for a problem as others have
noted. They remind me of the ball of mud that was Java portlets.

No team(s) _wants to maintain_ a SPA written in multiple frameworks. If you
truly must, embed a component written in framework X into a component in
framework Y.

The embedding of components is a good way to _re-factor your way out_ of
having multiple frameworks and migrating towards a single framework. We've
been doing this successfully at work where we're incrementally migrating our
AngularJS + React SPA to Vue one component at a time.

------
asutekku
This feels like as a solution to the problem that does not exist. This just
increases the complexity and makes the interface horribly fragmented and hard
to develop for after a while.

~~~
regularfry
The problem this solves is having different teams in the same company
perfectly happily developing away on their own stacks when a random business
requirement needs that they get their components in the same browser window
such that neither team is tied to the other's deployment cadence.

~~~
JMTQp8lwXL
Having worked at multiple engineering organizations, I could see how some
people might question the value of this. For example, A big N company I worked
at went all in on React. Top down, no ifs-ands-or-buts about it. I'm biased
and like React, so I didn't mind the decision. Today, I'm in an engineering
organization where we have teams using React, Vue, and Angular, with no
foreseeable convergence on one. Each team feels most productive in its
preferred stack. A solution like this allows us to at least ship our code
together, instead of having everyone maintain CI/CD on top of their
application code. It buys us additional developer productivity. We don't need
to be duplicating deployment pipelines.

------
btbuildem
I've been prototyping this approach recently -- I think you can go simpler /
leaner yet.

The iframe angle is probably the most universal, and easiest way to include
legacy apps / sites. It does present challenges with authentication, as
cookies cannot be persisted by a framed context. Local storage still works,
but that requires some changes in the legacy apps.

As far as the "orchestrator" goes, I don't see the point of using a nearly-
legacy framework (yes, a jab at Angular) when this can be done in plain
vanilla JS with postMessage. Some balk at using events, but in this context
messaging between clients could be a light, elegant solution to the
communication / synchronization problem.

Finally -- this is bound to fail in actual real-world applications, because
legacy apps are very likely to include everything and the kitchen sink, and
simply wrapping them in frames doesn't solve the problem of a bloated do-
everything spaghetti monster.

As an architectural approach for developing new, modular front-end solutions,
this is promising. Multiple small teams responsible for small, single-purpose
apps, stack-agnostic in aggregate -- this way of handling scale could reduce
the overall complexity, making development and maintenance a little easier.

------
JMTQp8lwXL
For those who may not know, here's a similar library:
[https://github.com/CanopyTax/single-spa](https://github.com/CanopyTax/single-
spa)

I'm glad to see two solutions out there, because there's a lot of variety in
how this problem can be solved. For example, single-spa recommends (but does
not mandate) using import maps [0] using SystemJS (to get better cross-browser
support) The idea is, each application says they want 'react-dom' or
'@angular/core', and it is resolved to a URL.

However, if applications are built expecting, say, different versions of
dependencies, a naive approach to import maps won't work (e.g., the import
'react-dom' is requested-- how do we know which version to serve?).

At my employer, we take each frontend application and transpile to ES Modules
and then combine via webpack. It's not what's recommended in Single SPA, but
it greatly simplifies the deployment architecture for us.

We don't have to worry about hosting a CDN that can resolve import maps,
everything's just in the bundle.

~~~
FlorianRappl
I think there are multiple solutions out there.

Our solution is called Piral,
[https://github.com/smapiot/piral](https://github.com/smapiot/piral), however,
we do not believe that mixing technologies should be a solution - it's rather
a workaround (which we also support). The real deal from our point of view is
in independent development, deployment, and modular, decoupled thinking.

------
throwGuardian
Much needed! For those questioning the use case: there are unique components
(say rich text editor like draftjs) that are better in one framework (React)
than in others. If your app is built in Vue, but you really want to use
DraftJs because it's the best rich text editor, and the proper tool for the
job regardless of it's backing framework, this project becomes invaluable.

~~~
soneca
There is another use case, that happened in my last job: migrate from one
framework to another.

We were using EmberJS, which is a framework that I liked a lot, but it was
just almost impossible to hire frontend developers to work with Ember. It is
such a niche framework that it is basically asking developers to compromise
their future career prospects to work on it at this point.

We used Single SPA to make an organized and gradual transition from Ember to
React.

So having a solution to run different frontend frameworks is a way to avoid
lock-in on a single framework (which can go out of favor in the future for
whatever reason).

------
Sirikon
Be pretty sure about needing this when you do it, because it might be your
biggest mistake ever if you're not sure about the implications.

------
rhapsodyv
We've using iframe to extend legacy apps for at least 10 years. And I don't
think this approach that needs rewrite the of the base router really brings a
benefit. Very often is really problematic to change the base router.

------
jacquesm
This is a good solution, but _only_ for transitions, you should strive to get
rid of the older one as soon as you can develop. But at least you have an
incremental path rather than a big bang at the moment you need to switch and
that can be a huge advantage. Another HN'er here did a port like that on a
pretty big website and nobody was the wiser change was happening until it was
all done.

~~~
soneca
Exactly that. We used Single SPA to go from Ember to React incrementally,
makes total sense and it helps a lot.

------
robbyt
There are two types of engineering. Additive and subtractive. All software
problems can be solved with either:

1\. Some abstraction. 2\. Replacing the existing "thing" with a new one that
had more functionality.

Building layers of abstraction is typically safer and easier, but the
abstractions aren't free. There's a really performance and completely tax to
using the additive approach. Just take a look at the Win32 API. So many calls
are slow AF and just reading a file off the disk in Windows requires 1000s of
syscalls and confext switches- because of too much "safe" abstractions built
over the years.

Compare this to Apple's engineering strategy, where they often deprecate and
replace an APIs. This is obviously more abusive to the developers, and the
users, but arguably better for the long term stability and performance of the
system.

~~~
temac
> Just take a look at the Win32 API. So many calls are slow AF and just
> reading a file off the disk in Windows requires 1000s of syscalls and
> confext switches- because of too much "safe" abstractions built over the
> years.

Windows, like any big system, has problems, but not this one. Its FS is slow,
but not for this reason.

~~~
cliffdover
What's the reason? Genuinely curious.

~~~
popotamonga
sometimes i wonder why does explorer listing 100k files in a path can take
minutes.

And searching the whole disk for a partial filename? tens of minutes.

I can do both in a database on the same machine in seconds...

~~~
wongarsu
You might like Voidtools Everything, a free tool that does partial filename
searches in milliseconds. It's incredibly useful for finding files.

[https://www.voidtools.com/](https://www.voidtools.com/)

------
gatherhunterer
I have a code question.

On line 24 in this file an object is sealed, but it has a type assigned. What
does sealing this object change? Is there a concern that other running code
will try to assign or delete properties on this object?

[https://github.com/eavichay/microfronts/blob/master/src/rout...](https://github.com/eavichay/microfronts/blob/master/src/router.ts)

------
FlorianRappl
For those who are interested in microfrontends / their patterns I've written a
small blog post: [https://blog.bitsrc.io/6-patterns-for-
microfrontends-347ae00...](https://blog.bitsrc.io/6-patterns-for-
microfrontends-347ae0017ec0)

------
sb8244
Why does the example use different domains in the base URLs? Does the app do
hard navigation between those?

~~~
asjfkdlf
It looks like the code is running in iframes, so yes it would do hard
navigation, but it would not change the domain the user sees.

------
mariopt
Using iframes, for most apps, usually brings more pain than benefits.

If an app is partially build with React, Angular and/or other lib/frameworks,
that is in itself a red flag. You might be dealing with legacy code while
moving to a newer stack. Using the same lib/framework brings you less mental
overhead and quicker development speed, developer onboard, etc. Unfortunately
I worked in some places where this was a sad reality and it was never easy to
fix simple bugs due to the lack of structure, architecture, code conventions,
etc . A refactor is your best friend but good luck convincing the product
owner that you need X amount of time to bring 0 new features to the business.

Downsides of Iframes:

1\. For each iframe you use, you'll use more memory, more CPU, bandwidth,
increased TTI, etc.

2\. You'll have to deal with subdomains authentication

3\. Data over fetching, each iframe fetch its own data without sharing with
another iframe. Trying to cache this is a sure way to chaos.

3\. Breaking an app into tiny packages might be overkill when compared to
having a proper folder structure, specially for UI.

4\. Now you have a Content Security Policy to maintain, it gets trickier over
time.

5\. You’ve N CI pipelines, some repos will be “forgotten“ -> older
React/Angular versions, packages that never got updated because you don’t work
in that repo/“microfront”.

6\. More DevOps overhead

7\. Forget about good UX and be welcome to the world of redirects -> a
“microfront” that takes you to another “microfront”

In my experience, breaking the _business logic_ into packages is great since
the logic is self-contained with unit testing, etc but placing the UI
components there will bring you the problem of not having atomic UI
components. Now if you want to change a UI component in just 1 package, good
luck trying to figure out which pages could be broken.

You’ve to be very careful on how you break your app into packages, it only
takes 1 bad design decision to make the whole thing a nightmare to work on.
Not to mention when you’ve packages that depend on other packages, you haven’t
written anything about versioning which is critical.

It is much easier to look at page built with React/Angular where you can see
the exact definition of the UI versus jumping between several packages to try
to figure out where do things come from. Put the UI components and pages in a
single folder/package. If you something like StoryBook and create your package
for UI components, even that brings some work to get right and maintain, you
split these components into more than 1 package and you’ll be running in hell
for simple changes.

Reduced mental overhead is a precious luxury I strongly value.

edit: formatting

------
hatch_q
In most cases this doesn't work at all - flash, ActiveX, ...

~~~
dahauns
Silverlight with WCF RIA services...

------
RobLach
I don't ever want whatever problem this is solving .

