[Idea] Merge Inertia core into adapters libraries
See original GitHub issueI’ve been thinking about the architecture of Inertia.js recently, and how best to move the library forward. One of the challenges with the current design is the fact that each client-side adapter (Vue, React, Svelte) all use the Inertia core library as a base. While this seemed like a good design decision at the time, practically it’s made the development more challenging for two reasons:
- I now need to manage two repos (core and the adapter) while developing new features, which practically speaking is just annoying. Using
npm link
helps, but even shipping simple features often means deploying updates two multiple libraries. - It makes it very hard to improve one adapter at a time. I personally maintain the Vue.js adapter, @sebastiandedeyne maintains the React adapter, and @pedroborges maintains the Svelte adapter. If changes are required to core that require adapter updates, all three of us have to do that work at roughly the same time. Of course this can be handled using versioning, but practically speaking it’s a pain.
So, recently I’ve been thinking about a different approach: merging Inertia core into each client-side adapter. This allows three things:
- Much easier development since the core and adapter are in the same repo.
- We can develop each adapter independently.
- We can really optimize the core logic for that adapter, in ways that I haven’t been able to do with the shared library. For example, there are some things that we’d do different in core if it was only intended for React. This allows us to do that.
It does mean that the core logic gets duplicated three times, but that seems like a worthwhile tradeoff. And honestly, there really isn’t THAT much core logic. Roughly 350 LoC right now. Further, we’d likely be able to make better use of existing adapter library code in the core logic, allowing us to avoid writing some code entirely.
Any thoughts? 🤔
Issue Analytics
- State:
- Created 3 years ago
- Reactions:10
- Comments:17 (10 by maintainers)
Top GitHub Comments
While striving for API consistency between adapters is nobel goal, it’s not necessarily practical.
I think it’s safe to say that most Inertia users are either using React, OR Svelte, OR Vue, not a combination of them. Inertia adapters should implement patterns based on their host environment, not based on an upstream core package. Side note: the server adapters don’t (and can’t) have a “core library” either, and we’ve seen no issues there.
I came to this conclusion working on the React adapter. Inertia is a global, mutable object, and mutable is the bane of React. This can leads to strange behaviour, where the props passed to the page component (which are immutable, since
inertia-react
acts as a bridge between the mutable and immutable world) don’t match the props on the global Inertia object (which is also accessible to consumers)Vue on the other hand, loves mutable objects and everything works like a charm. If Inertia was built for React first, it’d probably look a lot different.
So, does this mean I’m in favour of dropping the core entirely? Not necessarily. I believe we should redefine the core.
Here are a few things the core takes care of now:
preserveState
andpreserveScroll
based on the request methoda
click should trigger an Inertia visit or notThese are just a few examples. What these examples have in common is that they’re hard to get right, and don’t really depend on the adapters.
On the other hand, which part of the core makes can make it tricky to interop with adapters? State management.
I believe we should rebuild the core to something stateless. We should move the state management to the adapters so they can deal with state in the best way possible. Keep everything server and browser-API related in a core package, because those are hard to keep bug-free and consistent.
Regarding a Lerna monorepo
Based on my experience using Lerna in recent projects, it solves “share tooling across packages” more than it solves “working at multiple packages at once”. It helps a bit, but Lerna still requires some
npm link
voodoo to get things up and running.“Share tooling across packages” isn’t really relevant since React, Svelte, and Vue all have different build requirements.
Jonathan maintains the core and Vue adapter, and it’ll be me and Pedro that do 90% of the work on the React and Svelte adapters. It sounds like a monorepo would only increase the odds of getting in each other’s way.
That said, I’m by no means a Lerna expert, so I’d happily be proven wrong here!
Also, why should we be the happy few to be blessed with monorepo developer experience? I’d rather look into streamlining the DX for everyone, first and third party adapters alike.
Regarding TypeScript
I’ll happily discuss the pros and cons, but let’s keep this issue on topic since there’s already a lot to discuss.
Great question @Juhlinus. The goal would be the same as it is right now—to have feature parity as much as possible between the libraries. However, they already differ slightly, and I think that’s okay in certain situations. I want there to be freedom for adapter maintainers to optimize the adapter as much as possible for their particular language or framework. That goes for both client-side adapters as well as server-side adapters. 👍