Jellyfin-web: Migrate to a new framework

Created on 6 Mar 2020  路  126Comments  路  Source: jellyfin/jellyfin-web

We plan on modernizing the code here, which involves choosing a new framework. The only hard requirement is supporting incremental migrations, since we don't plan on migrating the entire codebase at once.

If you have a suggestion, add a comment below containing only the name of the library. An upvote means you would enjoy moving to that framework and a downvote means you would hate the framework. If you have no opinion don't add anything, and please avoid any other reactions on the suggestions themselves. Comments about your opinions are welcome!

enhancement

Most helpful comment

Vue

All 126 comments

Vue

React

Angular

Backbone

Ember

Polymer

My argument for React is still it's much closer to standard html (in jsx) and js. Where as Vue even has it's own custom file type and uses custom syntax for data binding and logic that is useless outside of Vue. Meaning if you don't know Vue, you will be constantly looking up docs for trivial changes. And the time you invest in that will be useless once Vue inevitably dies (as will all current js frameworks in a few years).

Potential resources for the migration to either of the current front-runners:

React

https://xebia.com/blog/migrating-to-react-step-by-step/
https://babeljs.io/docs/en/babel-plugin-transform-react-jsx

Vue

https://medium.com/@bluntjackson/adding-vue-js-to-an-existing-project-ed2d040f870b

Angular 9

(Please research if you Angular 9(!) and don't confuse it with angularjs, that's a totally different framework)

I just fixed the Angular comment so it would indicate the newer versions.

Meh people probably googled for angularjs or remembered it (or it being talked about), can't imagine that anyone just hates a modern framework, I heard many people being against it before they have even seen it or because they have used it "some time ago" it moved really fast.

Pro angular 9 is just the ease of development, everything can just be triggers with CLI

I would argue that React is not any closer to standard HTML and JS than Vue. I also disagree that Vue having a custom filename makes it less similar to HTML, because the SFC for Vue looks extremely standard to me. Airbnb is one company that goes so far as to require files including JSX get a different file extension because they don't consider them to be compatible.

One of the best reasons to switch to React in my opinion would be React Native. When we started thinking about moving to a framework we considered React specifically for this reason, but if we aren't moving in that direction I don't see a reason to use React over any other framework. It seemed like a pain at the time though, because lots of the libraries people were trying to add didn't support React Native and we had to limit our options.

Vue has amazing documentation which is helpful when learning a framework. They also have a framework comparison page here if anyone wants to see what Vue thinks about other frameworks.

I think the same about react and I agree with the vue page that angular is really nice for large applications (which is what we are talking about) and recent efforts of optimizing it where really good

Using react native in the web app would hold it back severely from my experience

Honestly, I think nobody would read Angular" anything and think Angular 1.0 nowadays.

We never really considered Angular internally, because no one in the web team is really familiar with it as much as with Vue or React, and it's heavy, which could prove to be an issue on Smart TV where memory is severely limited (And we're hitting a bottleneck already due to images, currently).

To me, the clear choice is between React and Vue. I'll need to see which is easier to integrate early in our build system so we don't have to wait for the ES6 migration to be done.

Well you won't have anyone knowing angular, when you don't try it and I personally think it's really easy to learn, we didn't have anyone on the team knowing angular at that time, but every one was positively surprised, how easy it is to manage and develop.
Just try something new it'll be a good choice I promise.

If the plan is to gradually move the codebase to a new framework, it seems Vue is more suitable to a migration than React. Moreover, I'd argue Vue has an easier learning curve than React and using the latter could see a reduced number of contributions than with Vue.

+1 for react, but knowing my reputation i don't doubt this immediately disqualifies react 馃檭

Weren't there some talks about new clients in React? There's even a repo: https://github.com/jellyfin/jellyfin-react-client

I think the question should be "how and why is Vue better than React". Let's not pick what's hippest, but pick what best suits our needs and plans. Next year there will be another hip new framework for JS; would we discard all the Vue work for that?

Well why always only vue and react? As you said don't always just pick the hottest framework. It sounds like you're discarding angular before you've tried or even looked at it.
Yeah sure many people use react and vue, but if you build a huge application they're just not that suitable for it.

@joshuaboniface the question should really be which is better, not why is React the best. We have exactly nothing written in any framework for the current web client and the question you posed seems to suggest a bias. It's also important to note React was started in 2013 and Vue in 2014, only one year later, so I wouldn't consider either one a "hip new framework" since both have been around and widely used for nearly the same amount of time. Angular has actually been around for even longer, so all three should be considered established at this point.

I mean out of the clear choices available to us based on developer experience. 8 downvotes and no upvotes for Angular seems to indicate that we have no one able to work on it.

I don't personally care, I know exactly zero of them. But I am concerned that this might turn into a bunch of pointless bikeshedding about which framework to use, when we should just pick the best one for our needs and stick with it.

Well the 8 downvotes are for angularjs (it was edited) I downvoted it too

We're still probably at least a month away from writing anything for this, so there's no rush.

Keeping with the doocracy, IMO the guys who are consistently shipping are the ones who's opinions matter most. Wherever the active contributors land is probably the winner....

One of the best reasons to switch to React in my opinion would be React Native.

https://github.com/necolas/react-native-web this might be useful to create components that can be used in both web and mobile environments.

There's also nativescript, which is kind of framework independent.

Are there any wrappers like Electron or Cordova that cover more platforms? We have been doing that and so far it has worked well in my opinion.

Are there any wrappers like Electron or Cordova that cover more platforms? We have been doing that and so far it has worked well in my opinion.

I believe react native has pretty great coverage. Only problem is I don't think we can do a gradual transition with that as you're only allowed to use their custom "html" tags AFAIK

Are there any wrappers like Electron or Cordova that cover more platforms? We have been doing that and so far it has worked well in my opinion.

I believe react native has pretty great coverage. Only problem is I don't think we can do a gradual transition with that as you're only allowed to use their custom "html" tags AFAIK

Agree the approach has been successful and that it seems to have made the barrier to contributing pretty low. Web + Electron + Cordova/Capacitor seem to hit almost all relevant platforms - which others did you have in mind?

My biggest worry about React Native is it's not "web-first" which feels like would be more difficult to target oddball browsers like we see with TV clients and media boxes (but I have no practical experience there)...

Alternative Web Frameworks with cross-platform (Web, iOS, Android, Linux, Windows) packaging tools - the strengths here are high reusability/compatibility, pre-built UI components, existing web skillsets.

My biggest worry about React Native is it's not "web-first" which feels like would be more difficult to target oddball browsers like we see with TV clients and media boxes

I share that worry

Yeah Ionic is quite ok

I don't personally care, I know exactly zero of them. But I am concerned that this might turn into a bunch of pointless bikeshedding about which framework to use, when we should just pick the best one for our needs and stick with it.

Wherever the active contributors land is probably the winner....

I second this and this.

My primary thoughts and considerations for picking would be:

  • Choosing what fits the best for building the kind of UI this app provides
  • Being able to easily land Electron/native as a build target in order to eliminate the need for separate desktop apps
  • Being able to incrementally move over the codebase as stated in the original issue

Ultimately I think the choice should fall on the most active project members & contributors, as they'll be the ones having to end up dealing with the framework the most.

Also I'd like to ask about jellyfin-react-client (even though it's not really anything right now).

Also any thoughts or opinions on moving code to ES6/Babel as part of the modernization/transition?

Already being covered (see #868).

Also any thoughts or opinions on moving code to ES6/Babel as part of the modernization/transition?

I think this is already planned/started

The incremental switch is likely the hardest part. It sadly eliminates many "automation options" like create react app (at least if it works like I think it does), angular cli and I guess other equivalents.
So I don't know if it's particularly desirable to take that burden and also continue shipping parts of that legacy code.

Would building a parallel web client like jellyfin-react-client be a better solution altogether? On one hand it's hard to incrementally transition the codebase to a new framework, on the other it's bad to either abandon the currently shipped client codebase or otherwise fragment developer resources to keep up feature parity between two totally different clients for an extended period of time.

Also any thoughts or opinions on moving code to ES6/Babel as part of the modernization/transition?

Take a look at #869 and #868

Also I'd like to ask about jellyfin-react-client

It's kind of abandoned, unfortunately. Most of the contributors prefer to work on this and to fix it up.

My personal opinion is that we have a client that works and I'd rather fix it up. Plus I have issues with React Native on web browsers. It's not "web first", despite the web client being the front of Jellyfin and what most users would be seeing. I've also seen that most web targets for it are limited and/or barely supported...

So I don't know if it's particularly desirable to take that burden and also continue shipping parts of that legacy code.

Whatever we do, this client has to be fixed up and maintained until we have something that can replicate 100% of the features available in this.
The fact is that the React Native client has seen very little activity in the 14 months since its initial commit.
To me, there's more value in fixing jellyfin-web, even if we have to redesign entire parts of it while porting it to something else. But, of course, anybody is free to work on the React Native client or lauch a React/Angular/Vue/other web client in parallel to this one. That's the beauty of open source :)

I have started an angular client, but wanted to wait for swagger and the API redesign (if it ever comes) before resuming it

I believe that React DOM and React Native code can live in the same project, so they share the same base code with only the component rendering being different. By using different file extensions (.js vs .native.js or .android.js) you can make a certain build use only certain files.

In this way (if we choose React), the initial focus can be writing for React DOM. Once everything is ported over, then work can begin to add React Native component rendering to the existing project. This allows for cross-platform development with only two sets of rendering - web and everything else. This also avoids the fact that, like MrTimscampi mentioned, react-native isn't "web-first" by handling its rendering separately where needed.

How good is Polymer and what does it excel at the most? Considering the entire YouTube frontend uses it might be a good fit.

Polymer ist mostly build around custom elements, it's kind of interesting, but I personally don't think it really suited for a large app.

And I don't know if we can get it to work on old tv browsers.

Polymer seems like a good option if you're looking for something lightweight, but if the goal is to make jellyfin-web the "one app that works everywhere" then you'll want a framework with some type of native app option.

Well polymer would still work with Cordova... But it's just less of a framework and more focused on components

Here's a nice comparison of the crossplatform frameworks, but it's in German and I don't know how well translator works on it: https://m.heise.de/developer/artikel/Flutter-React-Native-und-NativeScript-Kopf-an-Kopf-im-Cross-Plattform-Rennen-4502497.html

How about Riot.js?

https://riot.js.org/

I did a comparison of the stats for every framework that has been talked about here (Except platform stuff like Cordova, Ionic, Electron, etc): https://www.npmtrends.com/react-vs-vue-vs-@angular/core-vs-riot-vs-polymer

Here's a graph of the downloads in the last year:
image

And here are some stats for each project:
image

Honestly, one of the big things we need is community support for the framework. We need that thing to be staying alive for years, to be stable and to not implement breaking changes every six months. I'm pretty sure I'm not the only one who doesn't want to be doing another migration in a year because the framework we chose was abandoned or introduced breaking changes.

To me, that alone sort of eliminates everything but Vue, React and Angular (And I know this won't be popular).

Another big requirement we have is that we need to migrate everything in-place. I spent about 20 minutes searching Google for this for each of the three frameworks. I couldn't find anything about what that process would look like for Angular. All I can find are posts talking about moving from AngularJS to Angular, moving to TypeScript or upgrading your Angular version, but nothing about how to handle moving from straight JavaScript to Angular.
For both React and Vue, I quickly found the links I posted earlier in this thread, as well as dozens of other articles.

If anyone has good articles about migrating Angular in-place, feel free to send them, I'm interested.

Overall, I also notice in the stats that the Angular package is less used on NPM, has fewer stars, fewer forks and yet more open issues than React or Vue. This suggests bad issue triage, lower support, more problems, etc (I emphasize "suggests", because there's no real way to know for sure, but such a large difference is concerning).

Plus I don't think any contributor aside from Cromefire knows Angular, which kind of defeats the purpose.

As for React, I have a few issues with it:

  • It seems like you can't split HTML out of the JSX files. I'd very much prefer to separate as much of the HTML markup as possible from the JavaScript.
  • React has higher numbers on NPM, but around the same community participation as Vue, which means a lot less of the user are contributing back to the framework
  • React is lead by one company, with its roadmap and needs, which may not be ours in the future. By contrast, Vue is financed via donations and Open Collective, pretty much like Jellyfin. I feel like not depending on one corporation for all our UI framework would be a better choice.
  • React is constantly changing and evolving, changing the best practices often. Vue keeps its major versions running much longer and limits the amount of breaking changes. Change can be a great thing, but keep in mind we're migrating a fairly big codebase here and we'll be at it for a while. As said earlier, I'd rather not have to refactor already migrated parts of the client because some new version changed what the best way to do something is.

With this, I can pretty confidently say my vote goes fully towards adopting Vue, as it seems to be the best option for our needs.

Another big requirement we have is that we need to migrate everything in-place. I spent about 20 minutes searching Google for this for each of the three frameworks. I couldn't find anything about what that process would look like for Angular. All I can find are posts talking about moving from AngularJS to Angular, moving to TypeScript or upgrading your Angular version, but nothing about how to handle moving from straight JavaScript to Angular.

If anyone has good articles about migrating Angular in-place, feel free to send them, I'm interested.

It's rather hard, because of all the shell angular gives you. It defines pretty clear structures and best practices, which makes it pretty hard to migrate in place, because so may components are working hand-in-hand with other components. A point that could work would be the angular custom elements integration (that works both ways, so you can include custom elements and also provide it as a custom element).

Overall, I also notice in the stats that the Angular package is less used on NPM, has fewer stars, fewer forks and yet more open issues than React or Vue. This suggests bad issue triage, lower support, more problems, etc (I emphasize "suggests", because there's no real way to know for sure, but such a large difference is concerning).

The angular repo is a monorepo with a bunch of more components than just @angular/core. As far as I've experienced it they're quite fast at resolving issues. (It provides framework, compiler, router, testing, ...)

Angular is more of a "do it once, do it right" (batteries included), than a kind of patchwork like react or vue.

Angular is more of a "do it once, do it right" (batteries included), than a kind of patchwork like react or vue.

But then that's another issue, in my opinion. Because what if "the Angular way" isn't what we want? Then we don't have the option of switching that part to something else.

Angular being monolithic makes me want to use it less, honestly.

Well you can always do things differently as with almost any framework, but there's often just an easy solution included

What about Blazor client-side? Could benefit from code reuse as it uses C#, and you can serve it as static files (server not required to change).

@frogcrush I'm not too sure about the existence of any client relevant code in C#. Moreover, modern frameworks support distributing files without any server needed. Lastly, I'd argue that those working on the web client aren't the same as those on the server, thus not having the same knowledge of C# as JS & co (but that's just my naive opinion).

@frogcrush I'm not too sure about the existence of any client relevant code in C#. Moreover, modern frameworks support distributing files without any server needed. Lastly, I'd argue that those working on the web client aren't the same as those on the server, thus not having the same knowledge of C# as JS & co (but that's just my naive opinion).

Ohoho, there is indeed. For client-side Blazor, no server is required. You serve it as static files like any other PWA. You could (and people do) run it on Github Pages.

Alternatively, you can use server-side Blazor. This is what people use for things like Electron where you're already running a stack. The nice thing is you can do both without and code changes. Since they're both running a version of the dotnet standard.

Also, I don't really view the syntax as very different than something like React; I would argue that to write Blazor you don't have to know C#. You can still interop back and forth with JavaScript, but you have the power of full dotnet available as well.

Seems like it either requires a C# server or WebAssembly, which is a no go since we require support for some old and crusty browsers (Afaik, we support back to Chrome 27, due to Smart TVs).

Plus I'd rather refrain from making this spaghetti mess even more complex by adding yet another piece to the puzzle.

Not to mention that most of the contributors to this repository are JS devs first and foremost. We have a lack of C# devs for the server, compared to here and it feels like changing the language of the web client would drive a lot of contributors away.

@frogcrush Again, Vue, Angular, React and others do support PWA and are way more popular than Blazor.

@frogcrush Again, Vue, Angular, React and others do support PWA and are way more popular than Blazor.

Windows is more popular than Linux. Does that mean that everyone should just use Windows, since obviously Linux has no use cases where it could make sense?

@frogcrush Again, Vue, Angular, React and others do support PWA and are way more popular than Blazor.

And are way more appealing for JS devs

I think we should consider to use https://www.nativescript.org/ to build iOS and Android from the same code that we will use for new web (maybe angular 9 or react)

@frogcrush Again, Vue, Angular, React and others do support PWA and are way more popular than Blazor.

Windows is more popular than Linux. Does that mean that everyone should just use Windows, since obviously Linux has no use cases where it could make sense?

Comparing web frameworks to operating systems is quite far-fetched. From a development point of view, the popularity of a tool among developers defines what type of support we can have, how many libraries we could use and how many knowledgeable contributors we could get.

Finally, I don't dismiss the fact that your framework has its qualities but I was just skeptical about the arguments you've made. You've said we could reuse C# code, and frankly I don't know that much about the project's structure, but if you could point me to where there is C# client code, I'd be appreciative. Also, you're free to clarify why is Blazor a more suitable framework (notably due to its PWA capabilities) and why would Jellyfin use PWA client applications.

@frogcrush Again, Vue, Angular, React and others do support PWA and are way more popular than Blazor.

Windows is more popular than Linux. Does that mean that everyone should just use Windows, since obviously Linux has no use cases where it could make sense?

Comparing web frameworks to operating systems is quite far-fetched. From a development point of view, the popularity of a tool among developers defines what type of support we can have, how many libraries we could use and how many knowledgeable contributors we could get.

Finally, I don't dismiss the fact that your framework has its qualities but I was just skeptical about the arguments you've made. You've said we could reuse C# code, and frankly I don't know that much about the project's structure, but if you could point me to where there is C# client code, I'd be appreciative. Also, you're free to clarify why is Blazor a more suitable framework (notably due to its PWA capabilities) and why would Jellyfin use PWA client applications.

Well on the PWA part I'm on board, but as that also supported by all other frameworks, that not quite a selling point

If I correctly understand PWA, it should let us easily make a cross compatible app for web / iOS / Android / etc. ? And also I've seen it can help caching stuff on the device, maybe offline use of Jellyfin?

Yes all of it, but it's of course more constrained than a native app. Also iOS support is really bad (although I heard I got improved in the latest update)

And the caching part is relatively separate from the PWA, although some browsers require it to install the PWA. (It's called service workers)

Do you mean iOS support of PWA or simply local storage? In any case it's another thing to take into account when choosing between PWA, SPA or SSR (is there anything else by the way?).

iOS just supports the PWA part poorly. I don't understand your second sentence, you're just throwing unrelated terms around.

Not sure if this was mentioned before, but looks promising if targeting web and mobile: https://flutter.dev/

I think it's not mentioned here yet, but the problem with it is, it's not really a webframework, it renders the app frame by frame and paints it on a canvas. That not a really good web experience I think

iOS just supports the PWA part poorly. I don't understand your second sentence, you're just throwing unrelated terms around.

I'm not too knowledgeable about these, but I thought making an SPA application wasn't the same as a PWA? And SSR means Server Side Rendering, isn't it the opposite of a SPA?

Not sure if this was mentioned before, but looks promising if targeting web and mobile: https://flutter.dev/

Flutter is still pretty young and I've had problems using it on both mobile platforms due to its modules being sometimes not cross-compatible.

I'm not too knowledgeable about these, but I thought making an SPA application wasn't the same as a PWA? And SSR means Server Side Rendering, isn't it the opposite of a SPA?

Server-side rendering just means that the server renders the HTML and then sends it to the UI. The UI will then "hydrate" the server-rendered HTML with click-events and stuff. So it can be used in a single page app or other app with multiple HTML docs.

Ok then we can have SSR / SPA apps or SSR / no SPA apps. Thanks!

Ok then we can have SSR / SPA apps or SSR / no SPA apps. Thanks!

I think SSR could be something that is added later as an optimization.

SSR is of relatively complex, but for our use case not really needed.
SPA are all of these frameworks, even the current UI. I thinks it's an absolute must have.
PWA is often not related with the code, but frameworks can provide integrations.

Being able to statically serve the entire application is really important to me. SSR seems unnecessarily complex and inefficient for what this app is trying to do.

Well you can usually still serve ssr apps statically, but it can be really complex because of js running on the server

Still using SSR you can cache the entire app in the browser

SSR and caching is totally unrelated

Nope. First request will return the app, but new requests will return http status code 304

Not projecting any preference but want to speak from my own experience choosing between Angular and React at work.

I see mention of a want/need for flexibility. After using React full-time for 2.5yrs I can say that it definitely provides the flexibility. That being said, I recommend setting up the coding guidelines as well as guidelines for state-storage so the number of competing implementation patterns is minimized. Also be careful about reading articles that came out before React Hooks API.

Use hooks API (vs Class components and this.setState) since this is the standard way to write React components. It is very good and I've found that it actually makes it hard to write bugs if you learn and use it properly: https://reactjs.org/docs/hooks-intro.html.

There is also Concurrent Mode that is a huge deal since it adds non-blocking rendering. This can make an APP a lot faster. For the most part it should just require reading the docs and following best-practices to enable it: https://reactjs.org/docs/concurrent-mode-intro.html

Side-note: with any framework, but specifically with React, be careful about articles or suggestions from others to use things without a good reason. The most popular one is "Use redux because it's good", when in reality you can do everything it does with React out of the box (context API, since hooks came out. Also redux uses this under the hood). These articles are still useful to learn design patterns (especially with the intro of the useReducer hook in React).

Agree with @cromefire , SPA is the only way to go if writing a web-app.

You should only use service workers anyway also SSR is still totally unrelated to any response code those are controller by the webserver and not by the technique you are using

By statically served I mean dump some bundled app assets into the web root of an nginx and call it a day.

Yes that's possible, that's just not prerendered then, at least that's my experience with angular and (p)react

You usually have 2 builds one for the server one for the client

Fine, since this is going crazy I vote for wasm but not Blazor. Fuck Blazor, fuck Microsoft, fuck C#.

I vote for Rust+wasm. Rust has the most widespread wasm support of any language and phenomenal tooling for regular and wasm development.

No GC, minimal runtime, insane performance, massive safety guarantees, more mature wasm landscape and tooling. Rust is def the way to go with wasm.

I think this has veered a bit off-topic.

While we appreciate the lively discussion this topic has generated, keep in mind that this is a discussion about the framework for the web client, which is in Javascript and plans to move to TypeScript at some point in the future, and it's not about replacing Cordova or adding an Electron layer in this repository (If you want to work on a desktop version of this client, we have a repository exactly for that, which needs some love: https://github.com/jellyfin/jellyfin-theater-electron)

After some internal discussion and tally of the vote results (focusing on the regular contributors of this repository), it seems like Vue is the direction we are going in.

The next step will be finding a small, ideally self-contained, part of the client that we can rewrite as a proof of concept and a way to get the Vue pipeline in.

For small and self contained component I vote once again for volume controls.

There are 3 copies of it in the code, 2 perfectly identical 1 nearly identical (its just one layer closer to the manipulated vars). It's small, yet more functional than a drop down list or the like, and it gets used a lot without being a game breaker if borked thanks to external volume control options.

It's really perfect, since it covers all the major sticking points we will come across when turning the UI slowly into components (reducing duplicate code, small, functional in more than 1 way, has options if we break it, etc). Especially the almost identical part... Emby loved to copy/paste code rather than make it into a component after all.

Fine, since this is going crazy I vote for wasm but not Blazor. Fuck Blazor, fuck Microsoft, fuck C#.

I vote for Rust+wasm. Rust has the most widespread wasm support of any language and phenomenal tooling for regular and wasm development.

No GC, minimal runtime, insane performance, massive safety guarantees, more mature wasm landscape and tooling. Rust is def the way to go with wasm.

Rust + WASM is awesome, but it has to has it's purpose of course. For UI and communication JS it better.

For small and self contained component I vote once again for volume controls.

There are 3 copies of it in the code, 2 perfectly identical 1 nearly identical (its just one layer closer to the manipulated vars). It's small, yet more functional than a drop down list or the like, _and_ it gets used a lot without being a game breaker if borked thanks to external volume control options.

It's really perfect, since it covers all the major sticking points we will come across when turning the UI slowly into components (reducing duplicate code, small, functional in more than 1 way, has options if we break it, etc). Especially the almost identical part... Emby loved to copy/paste code rather than make it into a component after all.

Thinking a bit about it, wouldn't that depend on other components? (At least a slider component)

I was thinking that some kind of indicator might be best, as these don't really use anything else and are simply plopped onto the cards.

I agree we got off-topic for the PWA. Only reason I mentioned it was because of an above comment; I don't think Jellyfin should be a PWA. Just not a great experience.

I still say Blazor is a good choice because you can have SSR if you want it and CSR if you don't with absolutely no change to the code. Plus, it would allow creating a cross-platform single library and set of models that can be used everywhere. Then, only UI layers would have to change between platforms (think Windows, UWP/Xbox/RPi, Xamarin for Android and iOS, Electron.NET on Macos/Linux or for most of the platforms listed before).

Having to maintain all these different code bases in different languages is annoying for developers that want to come in and fix some bugs or add some new features.

Time permitting I might put together a demo of how this would work.

inb4 "but muh JavaScript is the best thing ever"

Well aren't enough C# devs

We definitely have more than enough help on the frontend right now :) so no need to worry about that.

Well aren't enough C# devs

Maybe due to the hostility towards C#?

However, my position is one of agreeing with the person above; those who are most actively contributing should be the ones making the final decision. I don't see any need to turn this into a flame war; but I think just asking the community for opinions on a JavaScript framework will always descend into one if we're being honest.

In the end, I wish you all luck :) Maybe I'll go make a (working) theatre client for Windows...

Maybe due to the hostility towards C#?

I am absolutely in love with C# on the backend so I'm not sure what hostility you're referencing, it's one of my favorite languages.

In the end, I wish you all luck :) Maybe I'll go make a (working) theatre client for Windows...

There's a UWP client that is being worked on. If you want to help look here:
https://matrix.to/#/!YOoxJKhsHoXZiIHyBG:matrix.org/$3FghUG6VDKT8gH4hbG37LSmojJrZZ-cTS07zNOZyB-g
The green ones are C# and those with red boxes are projects that definitely need more developers. (The others are also fine to work on though)

SPA is amazing, but overcomplicated in code.
SSR is great and fast but a more PIA to host vs dumb static webserver SPAs enjoy and less "embeddable"

If you decide to use Vue, there is a framework called Nuxt that take a lot of the "burden" out and automate a lot of things.

I've been playing with Vue in the current codebase for the past hour or so. Here are my findings for now:

We'll need the ES6 move to be done for it to be manageable. Mainly this is to avoid making our build system even more of a mess than it already is.

By playing a bit, I arrived essentially at this, after loading Vue via the CDN by inserting a script tag in index.html:

site.js

// We need to ignore our current custom elements, as they'll trip up Vue
Vue.config.ignoredElements = ['emby-linkbutton', 'paper-icon-button-light', 'emby-tabs', 'emby-button'];

// To avoid messing with AMD modules for now, I'm registering the component as a global object inside window
window.helloVue = Vue.component('hello-vue', {
    template: '<p>Hello, Vue!</p>'
});

// Since we're already pretty much a SPA, loading Vue globally for the whole client works.
window.app = new Vue({
    el: '#vue-wrap',
    data: {
        message: 'Hello Vue!'
    }
});

hometab.js

// Right now, components have to be instancied, mounted and inserted into DOM manually.
var ComponentClass = Vue.extend(window.helloVue);
var instance = new ComponentClass();
instance.$mount();
view.appendChild(instance.$el);

image

I managed to insert that simple hello-vue component into the home page pretty easily. There's unfortunately some annoying code due to our current structure (the manual instantiation and DOM insertion bit), but as we move more and more to Vue, this should be gradually removed.

I think we can pretty much start on this as soon as all the ES6 migration is done (which should be during the 10.7 cycle I think, unless we release early.

So with time, is the plan to insert Vue by a script tag in every page or using something like Vue CLI ?

I think there really only is a single html file, it's already a spa

@MrTimscampi I'm happy to lend a hand with the Vue side of things. Been following JF for a few months and would love to help out with this endeavor. I've been using Vue since 2017 (and have enjoyed every minute of it).

So with time, is the plan to insert Vue by a script tag in every page or using something like Vue CLI ?

As @cromefire, we only have one page, all the rest is already loaded in dynamically through a router and a view container.

As such, inserting Vue can be done once and we're good to go.

Vue CLI would be mostly for making an entirely new project. Unfortunately, given the nature of our beast, we'll be rolling on our own for all the build stuff. Likely a combination of Webpack + vue-loader + ts-loader. I'm not yet sure if we'll keep Gulp or not (I'd rather have something simple in the end).

@MrTimscampi I'm happy to lend a hand with the Vue side of things. Been following JF for a few months and would love to help out with this endeavor. I've been using Vue since 2017 (and have enjoyed every minute of it).

Awesome ! We're always looking for more people to help :) We're not quite ready to start on the move to Vue yet, but if you want to lend a hand to get us there faster, working on the ES6 migration would be a huge help. You can look at #868 for a list of what still needs to be done and how to do it :) Also feel free to reference the PRs labeled es6.

If you want an easier way to ask questions or get help, the team hangs out on Matrix, mainly on this channel.

@mattstrayer I have confidence we can get ES6 relatively quickly so it shouldn't be too long before we can start. The original plan was to start with the existing custom elements in the codebase, since that will have the largest impact on the site itself, but that might be cumbersome with the method outlined above.

@MrTimscampi one question we should consider before starting on Vue is whether we want to use some kind of component or CSS framework or "roll our own" so to speak. If we do end up picking some kind of framework we need to be more careful about the design, because I'd much rather have incremental changes with the looks than a complete overhaul.

@MrTimscampi one question we should consider before starting on Vue is whether we want to use some kind of component or CSS framework or "roll our own" so to speak. If we do end up picking some kind of framework we need to be more careful about the design, because I'd much rather have incremental changes with the looks than a complete overhaul.

There is a material implementation for Vue, which we can leverage and with that at least keep the basis which we can easily extend. I think we talked a bit about that already in the past where the consensus mostly was: Material is cool, but we want a bit of our own design language in it (which should be really easy).

Vue CLI would be mostly for making an entirely new project. Unfortunately, given the nature of our beast, we'll be rolling on our own for all the build stuff. Likely a combination of Webpack + vue-loader + ts-loader. I'm not yet sure if we'll keep Gulp or not (I'd rather have something simple in the end).

I'd think it'll be pretty straight forward to use once the whole code base is migrated. If it's somewhere as useful as the Angular CLI, it's definitely something we want I'd say.

@cromefire out of curiosity, what's the implemention of Material in Vue you're thinking of? And I do agree, once the code is migrated, it'll be more a matter of refactoring than anything else.

I think this is kinda the "default" impl: https://vuematerial.io/

Thanks for the link! There's also https://vuetifyjs.com if you want to have a glance. I've only tried this one as posts on Reddit (back in 2018) said it was better (more complete and faster) than VueMaterial. Although Vuetify has 26K stars against 9K for VueMaterial and has way more regular work (I don't know if it's a good or bad thing).

My own experience (edit: with Vuetify) is that it's really easy to pull a nice clean unoriginal Material feel. Even though I think it is customizable, I think we'll have to check at least both those two frameworks (if we ever use a design framework) for performance issues and customisation capabilities to reach the design vision of the team.

I've never really used Vue so IDK

Yeah, Vuetify is definitely the more default/standard Material Design implementation. It also supports SASS/SCSS variables, internationalization and RTL support with a lot of its components, and treeshaking functionality with the vuetify-loader plugin for webpack.

Shouldn't tree shanking be working anyway? (Via webpack)

Since Vuetify (and other plugins) use the Vue.use method to load themselves as a global package object of some kind, it appears that the helper webpack plugin allows for better integration and tree-shaking functionality when including components. I haven't used that functionality myself, but they provide some documentation that tries to explain it better than I can:

https://vuetifyjs.com/en/customization/a-la-carte/

Also, Vue 3's rewrite just made a lot more of the codebase tree-shakeable than in the previous version, so this somewhat shows that treeshaking in general can refer to (1) the webpack functionality, (2) the level of modularization in a codebase allowing for that functionality, and (3) any helper functionality needed in special circumstances provided by a library/codebase.

@MrTimscampi one question we should consider before starting on Vue is whether we want to use some kind of component or CSS framework or "roll our own" so to speak. If we do end up picking some kind of framework we need to be more careful about the design, because I'd much rather have incremental changes with the looks than a complete overhaul.

I was edging towards Vuetify + custom components, as I don't think we really want to reinvent the wheel and re-implement buttons, tables, navigation drawers and so on, but we need some custom stuff like cards and such.

Although I'd like to note there's Vue 3 coming, with some breaking changes and new features. It is already in RC and they are planning to officially release it in august.

Maybe we can start under Vue 2 and migrate to Vue 3 as soon as it is deemed stable enough and depending on how the needed dependencies update / behave under it.

My $0.02... In my experience Vuetify, while very bulky, is a good solution until you need to customize it. In recent projects I've used tachyons which gives you a toolkit of common styling practices. Using that with flexbox has been a sensible middle ground between a true css/component framework and writing it all from scratch.

edit: Again, I'm new here, so catching up... has there been a design style that's been accepted or is it all up in the air?

It'll probably something material (like), like it is now. I mean custom css ist really easy.

Maybe we can start under Vue 2 and migrate to Vue 3 as soon as it is deemed stable enough and depending on how the needed dependencies update / behave under it.

The plan is to start on Vue 2, since much of the extended ecosystem of Vue won't be out for a bit. My current time frame estimate is around late 2020/early 2021 for a move to Vue 3, once larger libraries, components and so on have moved to it and it has had some time to stabilize a bit.

My $0.02... In my experience Vuetify, while very bulky, is a good solution until you need to customize it. In recent projects I've used tachyons which gives you a toolkit of common styling practices. Using that with flexbox has been a sensible middle ground between a true css/component framework and writing it all from scratch.

The current goal is only to use Vuetify for "standard" controls: stuff like buttons, form elements, navigation drawer and so on.

The idea is basically to reduce the amount of custom crap to only what is necessary to us. A button stays a button and doesn't really have a lot of non-button-like features that one would use. We'd be using Vuetify "a-la-carte" to avoid bundling the entire package if we end up not using stuff.

Again, I'm new here, so catching up... has there been a design style that's been accepted or is it all up in the air?

The current one is based on an old Emby-made fork of Material Design Lite. So it has some Material Design visual language, but doesn't stick to it fully.

Our goal is not to make the client full Material Design, but something "Material-like", with our own spin and identity on it, so as to not be yet-another-generic-looking-material-app.

Edit: By "material-like", I mean similar to what we have currently: we take some visual cues from it, but Jellyfin very much looks like Jellyfin and not like Random Material App 53.


I've been throwing around ideas for how to start this, since ES6 is really close to be done (We're 9 PRs away from completion of the modules, then a final PR to remove RequireJS completely).

I expect multiple PRs to cover the initial work:

  • Remove RequireJS + move the current build to Webpack without "new stuff" (i.e. we'd have Babel, PostCSS and that's pretty much it).
  • Rework the new build pipeline to add support for Vue and TypeScript (more on this below)
  • Add Vue to the project and migrate a small thing as a test (I'm currently leaning towards the episode count indicator in the cards, since it's very simple, it's visible everywhere and we'll see very easily if it's messed up in some way).

1 will happen after a few PRs (one of which is already opened, #1789) to clean site.js in order to make it a better entry point (and easier to work with, since a lot of cleanup is needed for it to be RequireJS-less).

For 2, I need some input. Due to our requirements (Smart TVs), we pretty much require core-js. As far as I know, TypeScript doesn't provide it and I'd really like to avoid having to manually import them, so we'll need to keep Babel in addition to TypeScript.

Now, here's where the question comes in. I see two ways of doing this:

  • tsc -> Babel (Compile TypeScript, then feed the result through Babel)
    Con: potentially slow, since we do two build steps
  • Babel with TypeScript profile
    Con: Some features can't be used, like const enums. Imo it's not a big deal, but it's worth it to note.

Note: This impacts only building the client. In-editor debugging will still be handled by whatever your editor uses.

I'm leaning towards Babel w/ TS profile, for simplicity. I'd appreciate any comments or arguments for the first method, or even more options if I missed something.


Concerning the order in which Vue will be tackled, some things need to be taken into account.

We want to avoid future refactoring as much as possible. With that and the fact that we plan to use vue-router in mind, a few features like Data Fetching could be useful to simplify our code a lot from the get-go.

However, an issue arises, as we are already using page.js as a dumb router, with custom a view container and such.

The proposed approach to solve this, without any guarantee that it'll actually work, is as follows:

  • Add vue-router to the project, near the start of the move. The * route will point to the current router and a navigation guard to make a link between vue-router and page.js (Passing or converting URL parameters, and so on)
  • When an exiting route is fully converted (So all its components are migrated and it can be rebuilt as a Vue route), we define a new route that takes priority over *.
  • Links are changed by using the $route object to control vue-router from inside the legacy route.

If anyone has experience with this process, examples or references, that would be very useful.


Concerning Vuex, the current plans are to go without it at the start, and gauge how useful it could be as we go along, then add it in if we deem it necessary.

I expect it to make its way into the client fairly rapidly, but we're taking a cautious approach here, by trying not to add everything under the sun in one go.

Here are some preliminary matches for components between Jellyfin and Vuetify:

Vuetify Components Matching For Jellyfin

User icon, avatar, user selection cards => v-avatar (https://vuetifyjs.com/en/components/avatars/)
Episode/Watched indicators => v-badge (https://vuetifyjs.com/en/components/badges/)
skinHeader => v-app-bar (https://vuetifyjs.com/en/components/app-bars/)
appFooter => v-footer (https://vuetifyjs.com/en/components/footer/)
emby-button => v-btn (https://vuetifyjs.com/en/components/buttons/)
emby-checkbox => v-checkbox (https://vuetifyjs.com/en/components/selection-controls/)
emby-collapse => v-expansion-panels (https://vuetifyjs.com/en/components/expansion-panels/)
emby-input => v-text-field (https://vuetifyjs.com/en/components/text-fields/)
emby-itemrefreshindicator => v-progress-circular (https://vuetifyjs.com/en/components/progress-circular/)
emby-playstatebutton => v-btn-toggle (https://vuetifyjs.com/en/components/buttons/)
emby-progressbar => v-progress-linear (https://vuetifyjs.com/en/components/progress-linear/)
emby-radio => v-radio/v-radio-group (https://vuetifyjs.com/en/components/selection-controls/)
emby-ratingbutton => v-btn-toggle (https://vuetifyjs.com/en/components/buttons/)
emby-select => v-select (https://vuetifyjs.com/en/components/selects/)
emby-slider => v-slider (https://vuetifyjs.com/en/components/sliders/)
emby-tabs => v-tabs (https://vuetifyjs.com/en/components/tabs/)
emby-textarea => v-textarea (https://vuetifyjs.com/en/components/textarea/)
emby-toggle => v-switch (https://vuetifyjs.com/en/components/selection-controls/)
itemsContainer => v-virtual-scroller (https://vuetifyjs.com/en/components/virtual-scrollers/)
listItem => v-list-item-group (https://vuetifyjs.com/en/components/list-item-groups/)
navigationDrawer => v-navigation-drawer (https://vuetifyjs.com/en/components/navigation-drawers/)
toast => v-snackbar (https://vuetifyjs.com/en/components/snackbars/)
paprt-icon-button-light => v-btn + v-icon (https://vuetifyjs.com/en/components/icons/)
dialog => v-dialog (https://vuetifyjs.com/en/components/dialogs/)
actionSheet => v-menu (https://vuetifyjs.com/en/components/menus/)

doing this:

  • tsc -> Babel (Compile TypeScript, then feed the result through Babel)
    Con: potentially slow, since we do two build steps
  • Babel with TypeScript profile
    Con: Some features can't be used, like const enums. Imo it's not a big deal, but it's worth it to note.

We are using webpack, right? In that case ts-loader and babel-loader is kinda the "standard" way.

We are using webpack, right? In that case ts-loader and babel-loader is kinda the "standard" way.

That's what I mean with "tsc -> babel-loader" :p

I can help with it if you want, have done it like a million times. The good thing is, you can share the Babel config between js and ts.

Really excited to get this going. Great write ups, analysis, and planning @MrTimscampi 馃憤

FYI Vuetify rolled out a new docs website for anyone doing some research / prep for the Vue migration.

https://next.vuetifyjs.com/en/getting-started/installation/#vue-ui-install

Thanks for the heads up @mattstrayer

I feel like this can be closed now, you can follow progress on the new repository.

Was this page helpful?
0 / 5 - 0 ratings