VueJS Amsterdam 2026

Jakob Schröter, Helian Rivera - From Desktop to Web Rebuilding our Data Science Platform with Vue &

30:25 · 12 Mar 2026 – 13 Mar 2026 · YouTube

About this talk

In this talk, Jacob Schütter and Elian Rivera share their experience of migrating the KNIME desktop application to a modern web platform. They describe the initial challenges faced with the traditional Java desktop application and highlight the need for a web-based solution that offers better usability and manageability for users. The speakers discuss the choice of technologies, opting for Vue.js and Nuxt, which simplified development and allowed for incremental updates. Their journey also involved solving performance issues related to rendering with SVG and transitioning to WebGL using PixiJS for improved performance. Throughout the migration, they emphasized the importance of user feedback and incremental adoption while ensuring backward compatibility with existing features.

Full transcript

Okay, all yours. Good. Thank you. So, everybody still awake? Yeah, woo! Yeah, that's the energy. Okay. Yeah, hi hi everyone. We're really excited to be here today because 3 years ago, like Elian and myself, we were here in the audience and we thought, "Wow, like one day we want to stand here on the stage." And yeah, here we are. It's really cool. And we want to show

you our our story about how we migrated desktop application to the web. And yeah, let's get started. But before, who are we? Well, clicker? Yep. My name is Jacob Schütter and funnily enough, my initials JS fit to what I'm doing since nearly three decades because I'm yeah, started building websites when I was 11. And honestly, like with all these innovations happening every year, I still really enjoy

doing it. And my name is Elian Rivera and no, I have not been working in human resources since I was 11. I've been a developer. I like it a lot. My passion is in web development and I've been doing it for the past 10 to 12 years. And together with Jacob, we work at a company called KNIME. So, what is KNIME? KNIME is an open source data

science platform. It's got released in 2004. And over the time, it grew to over 300,000 users worldwide. But beside the open source part, we also have commercial offerings which are used by more than 150 well-known enterprises. Yeah, to me this sounds pretty interesting and when I joined KNIME, um 8 years ago, my like front end friends asked me, "Hey Jacob, what are you working on? Like can

you send me a link? I want to see something." >> [sighs] >> I I didn't want to send them the link. Because back then, KNIME was an 800 megabyte download looking like this. Oof. >> [laughter] >> It's a Java desktop application based on Eclipse. Um but yeah, you get the idea here. Like KNIME is a visual data science tool tool allowing anyone to work with data. Basically,

by building workflows, by connecting nodes, and configuring them without coding. But you can code a bit if you want. It's very powerful and established and uh because because it's open source, like has a lot of integrations and third-party integrations extensions. Um but it's potential is a bit limited as you can guess, right? Um Um because it's like the desktop application. And also our commercial customers, they ask

us, "Hey, it would be much easier for us to manage this um running in-house, right? Um if it would be a web application." So, this is why we and some more developers got hired for to transform this into a modern web experience. Um here you can see uh one idea of like the early designs where we wanted to go in the direction. And these of course are

like just a couple of examples, but you can maybe sort of guess the complexity that the tool has because uh the the KNIME product is not just about building workflows. You can do a lot with it. You can execute them in the background. It can run through a lot of data. You can create visualizations, reports, uh dashboards, interactive data apps. It's It's software that's been around for

a long time. Uh so, we had a lot of work ahead of us. But I mean, we maybe we can back code it. Sure, it should be easy. Um so, we started the journey to build a new workflow editor and of course, we first wanted to assess what framework to use and spoiler alert, we chose Vue cuz otherwise, we wouldn't be here. And yeah. And like I

think one thing we liked a lot about Vue is the great DX and Dragon was showing it earlier this morning that there's this like special thing about Vue and once we started using it, it was like really really nice. And especially, it's it provides like an easy onboarding for developers that don't have a lot of experience with front end development and because we come from a like

there were a lot of developers with Java background, this like made it a bit easier for adoption. But of course, the most important criteria for deciding this was that the logos really fit well together. And this was like, we go for it. But of course, when we were getting ready to start the development of it, uh something else happened and we had to Yeah, priorities shifted a

bit in the because we realized that actually we had a lot of interesting content which was only available in the desktop application. So, content like example workflows showing use cases how to use KNIME to solve this and that, right? to improve the visibility on the market, we wanted to put this content online and also make it indexable by search engine engines. And that's why the idea of

building a content platform first um came up. we started looking into frameworks that could help us with that. And yeah, we knew we needed server-side rendering for the static content, right? For search engines. But also client-side rendering because we knew also that this like likely [snorts] we will add more features to this. Like it's not only about like a static website. And further, the framework should be

flexible for all the future upcoming things. But also be a bit of struc- structured, right? Um so that when it grows, um it it has a bit of structure. So, since Vue was settled already, we of course looked into Nuxt. And it was in a very early stage. I think we started with uh Nuxt version like a beta version of Nuxt 2. And um yeah, we liked

the direction it was going. It looked really promising. And of course of course, we did our check. Final sanity check. The logos also fitted really nicely together back then. Like now the Nuxt logo looks a bit more rounded. >> It's still a triangle, so I think it works. Yeah, um so and Nuxt turned out to be a great choice. Um over time, this platform grew to like

the main entry point for many of our users. And let me quickly show you how it looks today. So, basically, you can imagine it like GitHub for data science. It's actually called KNIME Hub. And so, you can search for workflows. You can collaborate in teams. Um but also, we have enterprise features um in this application. Um like for example, being able to deploy workflows you have created

as a data app is what we called like some interactive um app um for business users for example, but also deploy those workflows as web services for example. We have many more features in there, but uh we cannot show them all. But we want to highlight some of the challenges we faced doing the development. So, yeah, it started small, but now it's big like enterprise front end

with over 200,000 lines of code. Um it's deployed to multiple environments, software as a service, uh on premise. And with this like there comes like a high dynamic feature set, right? Uh we have feature flags, uh permissions, licenses that you can apply. on the back end side, we have like many microservices that we need to handle all um with one like big front end. Luckily, with Nuxt

3, uh Nitro came in and that helped a lot to um improve on on this side and also um to build a back end of a front end layer um that we're using here. With all of this and nowadays multiple teams working on the same code base, ownership and architecture gets a bit tricky. And this is what we're currently like facing and uh trying to improve with

with like a feature slice design inspired architecture. But after hearing Jacob's nice talk yesterday, um and also speaking to Daniel, I think we we will look into uh Nuxt modules and also Nuxt layers um again again. Yep. But now now we have the content platform, we can take a step back and we go back to the UI. And we want to finish the user journey. So, we

have this workflow. Wouldn't it be great if we have like some way to edit the workflow? And that's when we came back to the workflow editor, which was the original thing we wanted to start with. But before we do so, we wanted to set for ourselves a few guiding metrics. Um for example, we know that we want to go to the web, but of course, we still

have to support the desktop application. So, we want one single code base. We don't want to write everything twice. Second, we want to go for incremental adoption because the tool has been around for a long time. It has a lot of features and so, it's very impractical to migrate everything all at once. We have to figure out a way that people can start using it while still

being able to use the features in the legacy Um of course, we also wanted to focus not on feature parity, but rather value parity. What this means is like we wanted to assess what are the features that already exist and like individually like take them one by one and say, "Okay, this is more aligned with the feature like with the future of the product." And bring those

first rather than just like yeah, let's just do everything. importantly, we also must not break any existing workflows because the tool like a lot of people are using it in their companies, they're running a lot of data through it. Uh so, we have to make sure that everything that used to work before still works in the new application. It has to be completely backwards compatible. And of

course, last but not least, we can innovate because this is a good opportunity. We're doing a lot of things anew, so we can revise the UX, uh bring new features like new quality of life improvements. So, why not do that? Um but still, I mean, with that said, we still have this Java application that we need to bridge uh to the web. And how do we do

that? And of course, we need a browser to do Uh in the beginning, what we did was like we experimented with SWT web view. This is provided by Java. And what this does is just it spin up spins up a native operating system browser. Uh but under the hood, because it's using the native OS browser, and the majority of our users are in Windows, that meant Internet

Explorer 11. And this is This is not a good commitment to make. So, of course, we looked into something else. Uh in this case, the Chromium Embedded Framework, alias CEF. And for those who might not know, CEF is what's used uh under the hood by Electron apps. But we cannot do an Electron app because Electron apps have a node backend. We have a Java backend. Um so,

this doesn't work. Uh and luckily, we found this company from Argentina called Echo. And they provide such a wrapper. They provide something called Echo Chromium, and this wraps around CEF and interfaces very well with Java, specifically in our case with an Eclipse an Eclipse IDE environment. And it also provides the communications that you can get to to the UI. So, what we did, uh we added this

little button here. This is the classic interface. And what we added was essentially something we call the perspective switch. And when you click this button, what you see here it's a browser being spin up with a basic variable hello world application. But this is now HTML you're like using JavaScript, so now the world is your oyster, essentially. And uh so, next we can look a bit into

rendering. So, here uh these are the main primitives that we have in our application. They're called nodes, KNIME nodes. And maybe from the get-go you can imagine that HTML won't really work for this. So, we went for the next best thing, which is SVG. And SVG had a big advantage for us. Uh a lot of these nodes were already written in some form or another as components

as view components for the content platform which was developed before. So, we could reuse some of that code. And um yeah, using SVG in view, it's pretty easy. It's like just like HTML, you can pretty much do everything that you can do uh in HTML. However, for us, this presented a challenge uh because set index is three in SVG, essentially because there is no set index. Everything

is based on the DOM order. And luckily, View has this very nice feature called teleport, which we use heavily on the SVG canvas implementation uh to essentially retain a good component structure while still rendering the things in the order that we want it. Um of course, after many iterations, this is kind of like how it looked like a bit in the future. Uh here in the background,

we can see the web UI. This is still the desktop application. Uh you can see in the background the web UI being powered by CEF. And in the foreground, you can see that it integrates with the regular the legacy features that already existed. This is a Java application. So, we we got to the state of mix and match, which was really good because it left lets us

like still develop things and yeah, continuously improve. However, this is just a summary of the implementation of the workflow editor. There's still a few interesting challenges that we run into along the way, and we want to share with you some of those. One of those challenges are our forms. Because in fact, we have many forms in the application. For example, if we look at the screenshot again

here, um to configure those nodes, um we have a form. And we have over 3,000 nodes. Most of the nodes are written in Java and some in Python. So, we needed to find a way how to transform those forms into like this new like web um web form. And um most importantly, the extension developers of KNIME, they should not need any front-end knowledge to do that. So,

we did some research and find a nice library called JSON forms. And with JSON forms, basically, you define like a JSON forms schema describing the form that you want to build. And then there's a JSON forms renderer that can plug into your view components. And then you can render like your own components based on this scheme. Then again, like we created like a like a little SDK

for Java and for Python, which allows developers to just annotate their Java and Python code, and the SDK then transforms this into a JSON form schema. And in the end, um it will turn out into a nice web-based UI. And you can see the UI like the forms can be quite complex with some conditional logic and so on in there. Thanks to the mix and match alien

explained before, we are now able to ship those modernized forms already within the like classic desktop application. Right? You see in the back, this is like still Java, but in the front there's a modern dialogue. But also, we could combine it with the new workflow editor that we have built, right? So, that we have the workflow editor, the new one, and also the new forms. Nice. Yeah,

this is pretty cool. Uh unfortunately, this there's still another problem. Uh this window that you can see in the foreground is still running a separate browser instance. And because we know we want to go to the web, we still had another problem to solve, which was how to embed them at runtime because we need to make them that they're all in the same window. And the reason

why we have to do this is because as we said before, we have a lot of extensions that we do not know at build time what the extensions are. Only the user can decide what extensions they install. So, a lot of these are generated at runtime, and we can we have to fetch them. Um This is kind of like what our initial approach looked like. Uh so,

we had the main application. It's like the application shell that is running the main view uh application. And what it would do is it would fetch uh what we call internally a UI extension build. This would be a bit library build. And it would be fetched at runtime and would be registered dynamically in the main application. And this worked for a bit, but slowly we started to

notice some issues. Uh for example, we started having like a lot of CSS scoping conflicts because the reason is like uh both the main application and all of these UI extensions use a shared UI kit that we built in-house. And sometimes there were like code being written that would override some of those styles uh from the shared components. And because we're embedding everything into the same instance,

the scoping conflicts would arise. And they were very tricky to debug and very tricky to predict when they would happen. So, you would have like the UI loading something, and then all of a sudden a button starts to look a bit funky. another problem we had was uh View version incompatibilities. Uh the team that works uh my my team that we we work on the like the

main editor, but the teams that work on the UI extensions, they're separate teams. And they often have like different update cycles for their dependencies. So, there were come times, for example, where we are using View 3.8, but they're still using 3.5 on their like extension. And when we pull that in, there's maybe like a bit of an incompatibility there. And another problem was that in order to

make this work, we had to expose the application like the View instance into the global window, which did not provide like technical difficulties, but it's still a a potential security issue, right? Because it's just exposing the window object. So, we had to like take a different approach to solve this Yeah, so we again wrote a little SDK. This time we called it KNIME UI extension SDK. And

um this handles the embedding and the communication between the main application and those standalone um UIs. It supports two modes. One is the iframe mode. And this of course has best isolation, best sandboxing, and also from a security perspective is the best. So, especially for third-party extensions, this is um the way we wanted to to go. But it has one issue, and this is your that you're

tied to this visual frame, right? You you cannot escape it, which is a good thing on the one hand. Um but we had use cases where we, for example, wanted to show like a popover or a modal dialogue um from out of those standalone applications, which should overlay the main application. And that's why we also implemented this shadow DOM mode, which basically renders a View application into

shadow DOM. Um it also has some um JavaScript and CSS isolation, so it works pretty well. And we use this for our in-house um UIs that we built. Also, the nice thing with this is um like with both actually, but uh more mostly with the iframe is that we are not tied to View, right? We can load any kind of application in there. And that's what we

use for our visualizations, where we um used the Apache ECharts um framework. All right. So, with all of this that we described so far, we reached a very important milestone And I think this milestone deserves a little drum roll. you heard before that I played the drums, but unfortunately I couldn't bring my drums here. Um so I need all of you now to do a little drum

roll with your feet, right? Can we do it? Let's start. Yeah. Yeah, yeah, a bit louder, a bit louder. A bit louder. Yeah, and stop. Cool. Yeah. Thank you. Thank you. Really cool. I wanted to use the web audio API for something more or less useful one day. >> All right, but back to our milestone. Um with all of this we finally had the whole application for

the first time working in the browser. In a usable state, right? You see we dropped an Excel file here. Then we um you like you can see like you can expect inspect the data. You see the configuration like our forms. You also see the visualizations. So, the whole thing really is working. Yeah, and we also have some AI features by the way. Like it integrates with all

the models. It does some stuff for you, but I think we had enough of AI, so we're not going to show any of that. >> All right. Um at this point we also want to point out that I really like um Ilian and I we we did not develop this ourselves, right? It was like many developers at KNIME um who are likely watching us here on the

live stream. >> of us. They were all helping and it took a huge effort to migrate um this application not only on the front end side, but also on the back end side infrastructure um UX, the product side, and so on. So, yeah. Because it's running on the browser now >> Yeah. I can No, no, wait. No, no, don't No, no, wait. What are you doing? No,

no, don't do it. No, no. Why not? You're going to send your friends? No, no, no, no. I think there might be still problems. You have to make sure things because you know things can go wrong. Oh, yeah. Performance, yes. Actually, this is one of my favorite topics and we indeed had some performance issues. Also, KNIME provides uh like a way how to wrap like complex or

split complex workflows into tiny pieces. They're called KNIME components. Guess what some users do. They built huge workflows. >> And you might remember that we're using SVG for this rendering, right? And with SVG, yeah, every element is rendered in the DOM. So, the more elements you have, the slower it gets. And yeah, you can see here that the performance with big workflows was not acceptable at all.

Luckily, Ilian had a few ideas. Yes. Um so, we set ourselves to replace uh this approach. And of course, we first looked into a canvas implementation. And at this point we did not want to rewrite everything, so we wanted to look for some tools that lets us retain the same architecture that we had inside, but kind of like map from A to B. And we looked into

for example some tools like Konva JS, which integrates great with Vue. Uh but unfortunately, we did not have any meaningful performance wins in the POCs that we made. So, we had to keep looking. And then we thought, okay, what about WebGL? And we found this framework called PixiJS. And for those who don't know, PixiJS is like a 2D rendering engine for game development in the web. It's

pretty cool, very well maintained, and like great performance. Uh but it lacks a first-party integration with Vue. But the POC that we made with this uh we had to raw target with vanilla Pixi, but it was really good. The performance was great. And we said, okay, what do we do now? Uh but thankfully, Vue has this thing, the custom render API. And like I know there's some

guys from TresJS here at the conference, so they they know about this cuz Tres is like using this to So, we had to say, okay, maybe we have to write one ourselves for Vue Pixi uh for Pixi in this case. Uh but the Vue community also is great and this already exists. It's called Vue3 Pixi. And with this we were able to get uh working. So, we're

back here. Um So, let me show you how that looks. Here on the left side we have uh the SVG implementation. This is a very simplified example. On the right side we have a WebGL snippet using Vue3 Pixi in And like most of the magic happens here. Like here in SVG, normally what you would do is you would bind your paths. But in the case of uh

WebGL, everything happens on the render function, which is powered by watch effect. So, normally you have to draw all the things, but you can have your reactive dependencies in there. And whatever it changes, it will just schedule uh to the render uh batches that Pixi would like redraw on its next pass and it would just get synchronized with the scene graph of And of course, again, this

is a very simplified example. There's many things that we had to do from scratch. For there was no CSS that we could reuse. So, we had to style a lot of things. For some cases where performance was more critical, we had to like go a a bit around and use directly Pixi. But overall, um I think the results were Uh this is the same workflow that Jack

was showing before. Uh same amount of nodes, but in this case the the interaction for dragging is like very, very smooth. And like not only this was like a nice effort, but uh it also opened the door for future more performance optimizations because we are now in full control of the render output. So, this is really good. Yeah, thanks. >> [applause] >> Thank you. Yeah, to recap

our journey here like a very rough timeline of our milestones that we had. Um in reality, did partly also partly also happen in parallel, right? The development of those milestones. But yeah, um and now this year we are really looking forward to finally launch the in-browser editing officially. That is the next uh big thing we're going to to release. Yeah, and uh of course, you know, like

not everything that we did is user-facing. Like there was a lot of work that was happening behind the scenes. Uh you're all developers, so you know like the story. We had to do a lot of like Vue2 to Vue3. This was really smooth. The API was very stable. The guide was like really easy to do. Nuxt 2 to Nuxt 3 was a bit of a anecdote, but

I think we also had like a a few other things. >> Oh, yes. Oh, yes. Yeah. >> And we still need to go to Nuxt 4. Yeah. Yeah, but I I think in general all these things are worth it. Like performance improved, the productivity improved. All these tools are moving in the right direction, so it was it was worth uh spending the effort to do that. Yeah,

and we have some more learnings that we want to share with you. Um I will start with the ones that didn't go so well. Basically also like a summary. First thing, yeah, Ilian mentioned it a bit. Like the Nuxt 3 migration was a bit tough for us, honestly. partly it was also our fault because with Nuxt 2 we and like as I said, like we started with

a very early version, right? We implemented quite a lot of custom workarounds for framework functionality. And all those workarounds, they fell on our feet when we wanted to upgrade. So, a lesson learn learned was here like try to stick to the framework. Try not to work it around too much. Next thing, yeah, we underestimated what our users would do with the app as you have seen um

regarding the performance. And also not isolating the embedded standalone UIs, yeah, didn't turn out that well. And one thing also I would like really like tell you or like hope you you don't use it that much because it was a pain Um in the initially we used a lot of deep styles um as Ilian mentioned and they were a pain later on. Um so, we try to

avoid them now um everywhere. Um of course, on the flip side, there are many things that went well. Like for example, we focused on this approach of doing things incremental. That was it's really good for us, also for the users. We were able to get people testing things. And this combined with this mix-and-match state where we are able to like let people still use the legacy features

combined with the new UI, it was very good for for it for feedback. Um we kind of maybe inadvertently focused on this mantra to make it work, then make it good, and then make it fast as indicated by the performance section. Uh maybe in hindsight we could have looked into the performance a bit sooner. But of course, we are also understanding a bit the domain and like

what we wanted to implement and getting expertise implementing this like new canvas. And like it was good that people could try it out and we at least at the end discovered this use case. And of course, importantly, listen to user feedback. Um but also don't get discouraged by it. Like we have a large forum in the community. Uh people are very like passionate and vocal, especially because

the tool's been around for so long. They have opinions like very strong opinions about like how things should work. And sometimes like they're right and we it's good to listen to that feedback because sometimes it get you a bit depressed. Um yeah, and of course, we wouldn't have been here if it wasn't for like all the great many tools that exist in the tool in this this

community. So, I like us to to give it up for the open source That was our journey, our story. If you have any questions to that or you are facing similar challenges and want to want to have a chat, um feel free to reach out to us here today or online. And in case you're curious um how we solved certain things, uh you can check our code

um on GitHub. And yeah, thank you all for listening. >> See you around.

From event

VueJS Amsterdam 2026

12 Mar 2026 – 13 Mar 2026

All event videos
Back to Watch