VueJS Amsterdam 2026

Tim Benniks From Vanilla Chaos to Vue Zen Rebuilding EA’s 2013 Need For Speed Rivals Web Campaign

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

About this talk

In this talk, Tim Bennix shares his experiences transitioning from early web development practices to modern frameworks. He emphasizes how development has evolved from complex custom solutions in the early days of single-page applications to the sophisticated tools available today. Tim discusses his work on the Need for Speed Rifles advertising campaign, showcasing how he had to invent solutions for routing, state management, and animation without the advanced libraries we have now. He reflects on the importance of community-driven solutions and open-source tools in simplifying development processes over time. Finally, Tim explores the role of AI in current development landscapes and advocates for utilizing modern technologies to push the boundaries of what can be created.

Full transcript

I do the dog now. Alrighty then. So, I was actually supposed to be the final speaker for tonight. So, a lot of my slides are all about beer time and parties and I'll keep it short for you. However, I have a new timer here. We can go into this. And so, this talk is about everything is becoming a oneliner. And I know you're thinking, oh, it's all

about AI. No, that comes a little bit later in the talk. And so, uh, my name is Tim Bennix and I work at ContentStack, which is basically a platform that started as a CMS, but it has a whole bunch of other stuff um, for hosting, automations, things like that. And so there I lead developer experience and I'm also an ambassador for Nux and Alolia and Superbase and

Cloudinary. And I think this is the eighth time I'm speaking here. So I want to really thank um, the organization for letting me do that. This is really really good stuff. Um, this is one of the best ones. Like you saw all the cool things that were like announced today. That's just this is the place to be for us. And so um my accent might sound a

little strange to the Dutchies in the audience. You'll know I'm Dutch. You can hear it, right? But I live in France and I work with people in India and with people in the US. And so that's when you get this really weird mix. But actually, if you across the water, that's where I was born. So I'm really happy to do a talk, you know, in my hometown

essentially. And so let's tell a bit of a story. And so this talk was really meant to be like the last talk. So we're not going to go super deep in code. It's like just let's talk about our history where we started, right? Because in 2013, it was really the golden age for ad agencies. And so I worked here in Amsterdam um at AKQA. And so the

golden age of ad agencies literally means you have all these customers, they throw money in your face and say, "Build me 15 amazing things. We'll pick one and if it works, we're happy." That's how things like Nike Plus came to me. Like those kind of things we could really innovate and try and really the money was flowing and like all the things they asked of us were

like it was literally outrageous. And so we didn't really have that much in terms of frameworks. I know PGS kind of started in 2013 maybe, but I didn't know about it. Well, we had one thing which was essentially this one that we all know and love. And honestly, this changed the game for us because before that, I had to do DOM manipulation in five different browsers in

five different ways. So we did have some help but we didn't have you know what is a single page app or how do we route something or how do we do like alo isomorphic stuff that was actually we needed stuff like that back then and so today I want to talk about Need for Speed Rifles which is a game that came out on the PS3 I think

in 2013 and we had to make um the advertising campaign for this project and so it had to be a single page app, but we didn't have the word for that. We just had to build something and make it feel good. But we were not allowed to use Flash because if I had that, it would have been amazing. Some of the younger people here might not even

know what it is anymore. But yes, I was pretty happy not to use it, but then we had to invent a bunch of stuff. And so Need for Speed Rifles is this game where you're essentially um you're a cop and you have to, you know, make sure people follow the law, but you can follow the law by being nice with the rules or you can just destroy

the cars on the road. And of course, we know what we're all doing, right? And so, um, remember this, by the way. Oh, I don't have audio. Okay, we need to fix this though because that would have been nice. Can we try again? Because maybe it was quite low. games. >> Yes, everything. >> When I was making this talk and I found this, I'm like, "Oh, my

youth came back to me." That was just so much fun. And you also have like it's the in the it's in the game one, but this was not a FIFA game. We also did those websites, but I couldn't find that source code anymore. Anyways, so let's do a little quiz time. I'm going to go and click on this link because I found the code for Need for

Speed Rifles in an old Dropbox folder and I thought if I remove Sidecore and all the enterprise stuff and all the languages I can probably rebuild this front end just in the old way and put it on for sale and you know that actually worked. So I'm going to click this and we go through the experience and think about at that time it was inside the Need

for Speed website and the quiz is you're all developers here you know exactly how to build things and when you see something it's like oh how would I build this so first think about what do you see animations audio things like that how would you build that back then if you were building how would you build it with FGS and so well let me just click on

this and see if it works if the internet is happy because this is old code. Oh, it works. Okay. I think we can zoom in a little bit. All right. So, have a look at like just this screen, right? We have two choices. We can watch the commercial, which we won't do now, or you can actually drive. Like, how would you do these animations? How would you

tween this? Did you know we didn't really have a choice of custom fonts? We had to do all that ourselves. So, did you come here to play fair or did you come here to win? >> Let's find out. >> Consider we didn't have subtitle features yet. >> Take the curve. Take the bridge. Now, take the lead. >> All right. What is your choice? Are we going to

just pass him or we're going to just destroy this guy? Let me just click the other one just to see the memes we were trying to do back >> Congratulations on your epic underachievement. Tell your friends how original you are or try again. >> Shall I see if the share to Twitter with the little bird still works? >> How about that? Oh, I won't share it now.

But there you go. Well, we have Facebook. I think this is just going to die. Decent. Sharing on Facebook was always the hardest thing. You remember this? Anyways, let's choose deception then. >> Impressive. Now explore the aftermath. All right. We didn't have Well, we had WebGL, but it was really cumbersome. So, we had to do something else to get this 3D feeling to happen, right? But we

didn't have flash and so it still had to look really smooth. And we even had like this little, you know, blur thing that didn't exist in CSS. So, this is actually I think it's like an SVG filter or something. And so, the interesting part of this whole thing is that it had to be in 35 languages. And so, we didn't want to make 35 videos with a

voice over and a dude. So all the sounds that you hear are actually events and MP3s and it's all concatenated together on like a timeline. And so also you couldn't have a video that you controlled exactly where it would go in the key frames. So these are actually images that are all loaded. So we had to slow the game down to a,000%. So, it was going really

slowly and then we had all the virtual cameras around the cars, took a picture of all of them, and then we would actually put that together into a video with FFMP pack, and I could then cut it out again to choose which frames I wanted. And then you can do this And of course, I tried to rebuild this whole app in few, right? We'll show that in

a sec. That stayed exactly the same because it's so weird. Nobody would make a library to do that. All right, let's see. >> Ready to raise the stakes? Get in the door. Rewrite the law. >> Well, we know the mercy one. Let's just we'll we'll go through cuz it's basically almost done. Duty calls. But so does victory. >> And you know what's was crazy about this one

is that like it slows down, right? But we didn't have the frames. And so if you wanted to do a video that has slow motion, you have to invent the frames. But there was no AI. So what we had to do like this is 13 years ago like these video editors could invent frames. That's why sometimes on the end you can see it's a little bit warbly

and so we just had to invent that. And then I had to cut that out again. So we had like this gruntjs. I'm not sure anyone remembers what that was, but like this is like a build system we had before, but we couldn't really configure it. It was more No, we couldn't really code in it. It was just a configuration, but we had FFMPAC to kind of

just then extract all these files again. And high value target. Don't stop. Don't think, just do. You know what to do. >> Just look at what you've done. >> You see the warbling? Those are like fake frames we had to put in. Anyways, we don't have to continue. It's all the same basically, but did you notice it didn't load once and each of those 360 ones were

like 200 images that it had to load and all the choice ones were also images that are all pre-loaded. So while you would see one scene, it would preload the next one that also didn't exist. And like it's just ridiculous the things we had to build. But if this doesn't look good, everybody who wants to buy this game on his their PS3 or whatever it was, it

just needs to be smooth, right? So let's go back to our slides here. And so let's see if you were guessing like I gave away a little bit. So what are the things we had to build for this that just literally didn't exist or or becoming a little bit like how do you call this like community patterns just like we have now right with MCP we're trying

to do things. It's similar here. So spa didn't wasn't the thing but people were building it like we just all had a different way of putting things together. So we have to just kind of figure out hey we have templating we have routing we have fuse we have controllers right and so all the stuff we take for granted now like JS template language like in few it's

so nice and easy and it kind of just works well for us that just didn't exist we just knew John Rzi the guy who built jQuery had like this templatey thing that he came up with with variables in it and so we just asked him how did you do it because the world was so small and I could just ask John Resi and then we figured it

out and put it in here. And so then we of course had URL routing history, deep linking. I didn't show you deep linking now, but if we had to QA a certain thing, you didn't always have to like watch all this stuff. We had to be able to just deep link directly into it. Um, then we had state management. We had to know which things you had

clicked because we also had like a lot of analytics and events flying. So we needed to know where you were. Then we had internationalization and it had to be for 35 languages. And so initially they thought, "Oh, we'll just render images for the words." Like that's an insane idea, right? And so we had to figure out how to plug in one language into it and then so

the whole app would understand it. Um, so the video player was actually completely custom because all the audio and all the subtitles were custom as well. Like we didn't have subtitle track. So I had to figure out what are all the, you know, the blocks of time where something needed to happen. So it's like an event manager essentially. And so then of course JS audio playing. So

all the audio you hear like a hover the mouse. It's actually an event that plays an MP3 that's pre-loaded before. Um then we had canvas animation. So all the animations that you saw that looked like videos were actually just 50 frames that we played at 60 frames per second in a canvas over a timeline. Like why the hell would you recreate how a video works on the

web? Well, because otherwise this wouldn't work because you would have to render a video with a key frame on every video to be able to do it. And even now that's a little bit tricky. And so if you go to the Apple website now where you have these lovely animations, they actually use this type of stuff still. Um, for that we needed a tweening library and we

needed to update the images and the videos with grunt like I just said. And then also we didn't have the luxury of a few file where if you have a piece of JavaScript that it just gets executed. That didn't happen at all. So for us it was based on DOM nodes and we had to find the DOM node and then scan it and then say oh I

want to do this thing with this DOM node. I'll show that in a bit. And so it was really a crazy project because we had 11 months of creative people at the agency figuring out hey how do we market this thing? And we were really trying to think of like, okay, everybody wants to probably torrent this game. Why don't we spread a fake torrent and then when

you get it, you actually get this website, things like that. And EA Games actually went quite close to saying yes to stuff like this. But in the end, it was politically not good enough. Like that was a little crazy to do that, especially in that time when was skyhigh. So in the end, they spent all this time and we only had five weeks to build this, but

I was the only front-end dev. And so there was just no sleep basically. Luckily, we had two backend devs and a QA. They were great, really great people, but we didn't have full stack. I'm sure I'm not sure we still have full stack now, but that's for another talk. Um, so this was basically me all the time. Like I love doing all that stuff. And now with

AI, of course, that's different. We can do like five projects at the same time. And so let's think about what we have now, right? We have FGS that does our single page app stuff. does routing, templating, dom manipulation, events, all the things that we had to think about, you just have, right? And so internationalization, it's a really nice plug-in just works. The whole feed infrastructure, especially with

feed plus now, super good. We didn't have any of it. I think I had something called uglify.js, which literally just removed the spaces. I think that's all we had. And then we had this sidecore back end. I'm not sure if anyone here knows Sidecore, maybe a few, which is basically it just took all the files we had and then concatenated them all back, you know, to together

into one JavaScript file and CSS as well and just remove the the white space. That was our infrastructure. That's it. No builds, no tests. Um, we have right now really really nice animation libraries of which gap is one. But you can do a lot in few also with CSS, right? and transforms and transitions. And of course, we have PA for incredible state management. I had none of

this. why not rebuild this whole project with modern tools and see what's the difference? And so, I honestly really tried to use AI to do this because it's a lot of work to try and rebuild this. It could not get it like these animations and when something moves where with the dump connections, it just could not. And I even like this morning I was like I need

to get that new project a little bit closer to the original because I didn't get to finish it. The AI just screwed it up completely even the fancy models. So um I didn't fully finish it but it's close enough right and so if you look at the differences between 2013 and 2026 it's a lot easier because everything has been abstracted but it's somewhat similar. I'm surprised how

close I got back then with the our community patterns to what modern tooling uses right now. So let let's have a look. Let's have a look at routing. So this is my router. It's simplified because we had a lot more scenes, but NFS was like Need for Speed Rifles. So that was our name space. We had that back then. And so inside is a function and these

functions all like start preload or start uh like scene one setup or start scene two setup would essentially just fire a controller and the URL in another function would actually it looks looks at the URL and then fires a function in the router which then fires its own controller for preloaders or scene setup or the 360 thing and then we had to always destroy that controller. So

this is you can see this as mount and unmount because on mount all the events get bound to the DOM. Well, we had to then always unmount it first and then do it again because if you have double events things get painful very very quickly. And so this actually looks kind of close to this which is our few router, right? Of course history out of the box

that's so nice. And you have a few file that just does all the things. You just have to you just import it lazily and there you go. And that's but it's it's not that different. This this is just a lot easier. And of course it's unit tested. It's typed. We didn't know what TypeScript was obviously. Um so then templating this one was kind of crazy. So what

we did this is what John Rasic did back then. So we have a script with a type X JavaScript template. And in there you would just put your Java or your CSS and your HTML. And do you recognize those curies that use MP4? It kind of looks like few. No, just a little. And this was actually something they called mustache templating. And I think that's still the

name still exists, but there was uh or mustache, right? And there was this there was this really cool library that would actually grab your variables from JSON or wherever and then replace it. And we had some simple if statements. We we had some loops here and there, but not really. And so this kind of just worked because we would just we would have one index html with

all these templates just there and we would take that DOM, clone it and put it in the app based on the route and that controller. So we would then bind the controller to this HTML that we put together. And this kind of sounds like what F does automatically, right? And so we'll talk about what that data widget means in a sec. And so we would have this

like get template and you see there's the mushdash. render. Luckily, I didn't have to write that myself because that's like a lot of, you know, string parsing, I guess. And so, we could render the template. So, the target would be the DOM node we put it into. And so, we would get that from a get template, put it in, and then we would scan the DOM to

see, hey, is there any JavaScript we have to attach to these DOM nodes? And that's what that NS scanner actually is. And so, what we did is like the new HTML would be in the DOM. And for that that new DOM node we had a scanner digit that looped over all the DOM nodes like jQuery used to do and we would actually say hey there's data- widget

and the name is video player. So what that would do like video player was already loaded in the browser. We just know hey this DOM node needs this JavaScript and then it has data options with a whole bunch of stuff and this is also how we did all like the localizations and translations. It would just all be rendered in the HTML. we would grab it and then

fire it off and then if new HTML would be rendered in that same gap basically or that same hole we would then you know destroy all these bindings and then rebind it again or back then if you did an Ajax call which we call fetch nowadays um we would also then if the HTML was replaced unscan or destroy the old stuff and put the new stuff on

and I'm so happy I never have to do this again but it actually worked pretty and now of course we have this and this is the lovely part about what I especially love in few is just this of course a simplified version but this is just one file where I have a little bit of my JavaScript stuff I have bit of my CSS stuff if I wanted

to I have a bit of my HTML and then this like the fact that we have this component called choice player like we didn't have components that was not a thing so It's so nice to just make a file that has its own stuff. You put it in, but it's just one file. And that's the part that I really like uh about FuggS where it still feels

like my old school self where I have everything there and I can deal with DOM and do stuff like that, but all the complex stuff has been taken care of, right? So, this is this was a lot nicer Um let's have a look at state So this is what we had. I don't know why I called it JSON data, but I guess it was, right? So, and

this was a big big object because it had all the languages and all that stuff in it and all these like 360 views had like 200 files that it was preloading and so all the file names and the fact that they were loading and all that stuff was actually in there. And so you can see the logo animations, subtitles, ids of you know template selectors, DOM nodes.

The thing is this was completely mutable. So if I had a bug in my code and this would be muted done. Whole website is dead because we didn't have that concept of a single page app. We couldn't just reload because it goes back to the beginning because we didn't, you know, keep the URL state. And so yeah, that was really challenging and I had to build like

my own kind of little helper functions like for a certain action like for example load the preloader to get that part back from the JSON data and then when it was done we actually removed it from the memory so it couldn't go wrong and but it was a lot of work like this I simplified this but this was like 600 lines you don't want that like we

actually want this which is PA so it's a little small but I guess on this screen it should work and So everything is typed and you get getters, you get actions, state setters. It's so much nicer in PA and others like our storage. So like they all have this lovely um you know just DX is everything, right? And we didn't have it but it still worked. Um

we had this other thing which I now built in here because the UI in this app like with these choices and you go into different places, right? and you can have to reset certain things and then click there and it goes to the next thing. That UI is fully reactive. But we didn't have that. We just had to click on a DOM node and hope for the

best and see if all the events work and fire. Here I could just make a composible called use choice interaction and the the UI would be interactive. And so I could actually then have functions with clicks for example like a handle enter or handle leave that would change that UI in this little reactive object. And so it's so easy in FuggS now to just click a thing.

This thing keeps track of the state and this might update if we needed it, you know, in PA. Um, let's see what else do we have. Animations. So we like everything you saw in that website like when things moved from side to side, but also like the the images that would play like a video that all used a tweening engine. But there were some tweeting engines, but

nothing worked. So I just made my own crappy tweening engine, but I only had five weeks. So you do that in two days and hope for the best. And it kind of worked and it had like staggering things or uncomplete and things like that. And so this actually kind of worked. But I looked at it now and it had all sorts of memory leaks and it had,

you know, request animation frame globally running all the time. and then events would just go into it and hope for the best. But if you like I don't know why this website worked honestly but it worked. And so funnily enough I just wrapped that old thing into use tween and built it in a new one and yeah it's not for production it's fine. Um of course we

could also use transitions which are so nice in view. You just use transitions and CSS. So a lot of the things are like the moving around is just a transition. However, um Oh, yeah. Well, this tweening engine sucked. It's fine. However, I looked at it and this morning we were talking about feed plus, right? And I thought, let's make this code modern because it feels like there

is something to this because I have no slide for it, but my API looked so much like GSAP right now that I like, oh, maybe there is something to this what we came up with back then like that tween.2 in the timeline thing we had. And so about 20 minutes ago I made it work in feed plus because I thought my talk was like in three hours.

Um so now we have turbo tween and it actually works. So if you want welcome the age of AI, right? So when you go to mpmx you can actually find this and this library is only 5 kilobytes and it has no dependencies and it works on SSR TypeScript first. It works in few and react because if you have AI you say make it work in react it

kind of did I don't care but it did and it's very easy to install lots of docs and it works on feed plus and I think I have a little comparison table if you think about it gap is like the market leader almost right it's like five times bigger it doesn't have native doesn't adapt to just few out of the box it's kind of crazy. And so

if you're into this kind of stuff, feel free to download and play. Um, it has all the playright tests and it kind of just works pretty well, but of course, like anything, you just release quite quickly. It might not work for everything, but if you want to and you like stuff like this, feel free to try and let me know. All right, so let's step back and

see what this whole experience taught us. Right? So over time all these architectural things that I had to come up with with my colleagues and friends they kind of now became configuration. You just install PA and you install feed and it kind of just works because this is what Fugue and the Fuggs ecosystem is so good at right no config just run. Um then I don't think

the magic increased at all. It actually got just got abstracted away a little bit and so the magic is still inside but it's all just much easier now. And so if we look at 2013 to 2026, it's basically the painful implementation in the community patterns where I was sitting right and so over time it becomes libraries like few then it becomes standards and then it's boring but

because it's boring you get to do the cool stuff that I had to invent like I got bold just doing those things but if I did if I had fews then this experience would have been even better, like a lot better actually. So boring is good. And so most folks in this room probably didn't write an XML HTTP request or made a tweening engine because they didn't

have one. I would say that's progress, right? I would say use the tools you have now to actually do cooler And so we see this question evolve a little bit, right? It's kind of like now here's the AI stuff I promised. It becomes a bit of a command now. So you basically I would say okay how do I do this routing thing let's say right now you

just figure out which one fits best in our case in few we're good but sometimes like with void it might be filebased or stuff like that right so you get to choose but maybe next year you just say I don't care what router it is just add it please you don't look at it and so actually that boring default if we have that boring default actually open

skynet really quite cool. Oops. Right. Having this AI is going to help you, but it it only can do that if it has this really good like all that below all the stuff that the people that speak at this conference, for example, worked on make this AI so good. Without that, it's you have nothing essentially, right? And so Fuggs is really one of the biggest shoulders we

all get to stand on. So AI gets a lot better because without that it's kind of just it doesn't know what to do. You need libraries and we need like the feed pluses and the voids and the nux to be able to know what to do and make it work. And so are you this or are you this in this age of of abstraction right? I personally

say I'm more than happy to just use whatever we have and stand on the shoulders of all these people that built this cool and just really build the next impossible thing. That's what I want to do. And so that's me. Thank you.

From event

VueJS Amsterdam 2026

12 Mar 2026 – 13 Mar 2026

All event videos
Back to Watch