 Wow, that pun, that's going to sting for a bit, it's going to take a couple of days to wear off. Can everyone hear me okay? Alright, so yeah, I was trying to figure out, I wanted to find an image that would really capture the essence of what backbone conf means to me. And I had struggled to do so until last night by a stroke of good luck, I stumbled across the perfect image and here it is. I don't really know what else to say, Boaz and Sam having a good time sharing pasta, just hanging out. Yeah, so anyway, yesterday people talked about all kinds of uses for backbone. Personally I've been using it for a long time, but the only thing I've ever really done with it is build single page apps. Now the first thing about that is I actually really hate this term. I think it's kind of silly, it doesn't really embody what these things actually are. All the ones I build kind of have this concept of pages and whatnot within them. It seems like a silly phrase for this and I feel like we do better. And there's kind of this native versus web thing and it makes the web port. People seem to think of it as almost like a lesser thing sometimes. And I think that's backwards and I think if you're building for iOS, you're building a native iOS app, what that means is you're using the tools and libraries that are native to that platform. And what we're doing here is we're building apps with the tools that are native to the web. So I think we should call them native web apps. I think that's much more descriptive for what these actually are. And we're using JavaScript, HTML, and CSS to build apps. The delivery mechanism is actually secondary to that. So anyway, the point is your browser isn't your renderer, it's not just drawing the document that you got from the server, it is in fact your runtime. And the definition of this has been kind of expanded a bit to be arguably even like web views and whatnot. They're also your runtime. But the point is you have this kind of web runtime that you're using and you're building native apps for that runtime. No matter what you think about all that stuff, one thing that's very clear in the industry is that more and more logic is moving to the front end. And lots of people with lots of different backgrounds kind of are moving into that space as a result of recognizing that they want to build these richer experiences. And in doing so, they bring all their backgrounds and experiences with them. And so they bring their favorite patterns, their favorite preferences. And so we have this plethora of options for approaches for various things. And yet somehow, Backbone is still very, very broadly deployed. It's been extremely successful. And as Jeremy tweeted about back here, the top three newspapers by circulation in the U.S. are all Backbone apps. I mean, that's just one little niche. That's not a small thing. And so it might not be like the hottest topic right now that's been around for a while, but these are still very much like, you know, they're very, very broadly in use, right? So, you know, I think it's an interesting use case and we can think about, you know, why is it that Backbone has been so popular? And I think we can find some of the answers just by reading the homepage on the docs and kind of seeing the philosophy. And it says this, Backbone is an attempt to discover the minimal set of primitives that are generally useful when building web apps. And in an ecosystem where overarching decides everything for you frameworks that are commonplace, Backbone should continue to be a tool that gives you the freedom to design the full experience of the application. So if I were to try to distill that down, really, there's two principles there. You minimalism and flexibility. And Jeremy, if I'm wrong, now's a good time to let me know. Okay, all right. So, but then, you know, the other side of that is, if you take a very minimalistic approach to the tool set, that means that there's more stuff that you, that it doesn't do. I mean, by definition, right? So there's gaps that we have to fill. And if we're, you know, building apps like this a lot, we notice there are, in fact, other repeating patterns that Backbone does not address. That's not a critique against Backbone, it's just fact, right? And so the question is, well, then how do we deal with that, right? And how do we fill those gaps? You know, the parts that we see a lot of is kind of the add-ons, right, where you have, you know, like we saw yesterday with Marionette, et cetera. And, you know, and talking to folks who use Backbone at some of these larger companies, like, they've all kind of done the same thing. They've kind of built their framework on top of Backbone to some extent. So it's almost like they treat Backbone as kind of this meta framework, and then they build theirs on top of it. So, you know, that's kind of interesting, right? But another approach would be to just be like, whatever, it doesn't do what we need to do, so we're going to throw it out and use something entirely different, right? And that is more encompassing that has all the things that we need. And so that's where you get your embers, your angular polymer, you know, in combination reactant flux arguably could be put in this list as well. And, you know, I think that's where you kind of, I think that's what's being referred to here in terms of the overarching decides everything for you frameworks. You know, you're kind of going all in when you do that. You're saying, okay, I'm going to just jump, you know, head first into this thing, and hopefully it solves all my problems, right? And the thing that I find interesting about this is that they're higher abstractions. They're usually quite a bit higher in terms of abstracting. And what you end up with as a result is that you learn the abstraction. There's this really great quote by Chris Gale, who is the former vice president of engineering at Yammer. So, obviously, he doesn't know what he's talking about. I mean, he only sold his company to Facebook or to Microsoft for a billion dollars, right? But, you know, so he said this, he said, I'm more interested in optimizing a person's understanding of the problem than I am of the solution. And that just really kind of hit home with me, and I totally agree. So, and that's, I yanked that quote from Marco Rogers used to work at Yammer, and he might still work at Yammer. He gave a really good talk, kind of finding patterns across JavaScript frameworks at JSConf 2014, I think. So, what's that? Was it at TXGS2? I saw the video, I saw this from, yeah, whatever, and maybe it was. Who cares? Anyway, great talk, definitely go check it out. So, you know, I work at And Yet, there's about, and there's about 30 of us, we do a lot of consulting, we do, you know, so we have about 30 developers, but we have 40 people roughly. But we write lots and lots of different types of applications, so we're constantly kind of thrown into a new scenario, a new project, and so we don't just have like a product that has a certain approach that we're going to use over and over and over again. And so we come across like a very broad range of problems, and, you know, I'm one of the partners in the company, and so I care a lot about not just what we're doing now, but like where are we headed in terms of investing in skills that are laughing here. And, you know, I really want our team to be awesome JavaScript developers. I want them to be really familiar with the problems, not necessarily to be really amazing Ember developers, or really amazing Angular developers. I want them to know, like, how to solve the extra problems here and then not abstract too far away from that. So the third option I would suggest is to actually not have a core at all. And what I mean by that is, you know, I'd like to give you a little bit of background. I started using Backbone at like 0.3 or something, I forget. It was a long time ago. And we, you know, we were starting to build something that did similar, kind of similar approach, and then Backbone came out and like, all right, let's just use this instead. And, you know, for years we've been kind of building out, gradually building out this set of add-ons and things that we saw repeating patterns that we wanted to solve once and move on. And, you know, I came, personally I came from kind of writing a lot of Django. Who here has written Django? Oh, quite a few. Okay, cool. I absolutely love the models that are in Django. They're very declarative, very readable. And I kind of missed that when moving to Backbone. And so we built our own, eventually we built our own kind of model layer for Backbone. And that forces you to be much more declarative about what you're storing, et cetera. And, you know, also we kind of, along that, roughly around this time, Node was coming out and we started really using Node for lots of things. And Node has this very kind of unique mentality of everything being these very small models that you install with NPM. So, you know, we started using NPM and common JS modules for our front-end code as well. And this was before BrowserFi was a thing. Just because it seemed like it was a nice way to structure code. We kind of fell in love with that pattern, right? And then I wrote a book about it, kind of finding my, you know, kind of summarizing my conclusions and whatnot. It's free to read online if you want. And, you know, the thing is, like, as crazy as this may sound, after having kind of completely fallen in love with that approach, like, I think even Backbone is too monolithic. Like, throw tomatoes now. That's a good time. And I don't mean in file size. I'm talking about coupling specifically. And let me explain a little bit. So, you know, one thing that is a good example of this is the fact that models are useful for modeling other things, right? And take, for instance, you have, say you're building, hypothetically, you're building an SDK that has a, you know, a real-time connection of some sort that you're managing its state. Perfect use case for a model. You want to be able to set what the current state is. It could be connecting. It could be connected. It could be, you know, trying to reconnect. It could be disconnected, et cetera. Like, ideally, you just want some little observable object that you can set a state on it and, you know, watch for changes to, et cetera, and react to accordingly. So, that's a really useful use case, right? And another one that we ran into is, like, being able to model touch events in, like, a touch library. So, if you're not, if you've never done this before, the way that this works is you get a touch start, you get a touch move as you move your fingers, and you get a touch end. That's it. But a lot of times, if you're building applications that have kind of this rich touch type interface, what you want is you want to know when there's, like, a hold event, for example. So, you don't get that out of the box. And it's not trivial to compute it, right? Because what you need, you need to start a timer when you put your finger down. You want to be able to, you know, let somebody wiggle their finger a little bit. So, you have to track X and Y, and then distance from that original point. And then, you know, you have to start that timer, and then at some point you're going to trigger that, hey, you're holding this thing now. So, that's our single event. And then if you want to do gestures, now you have multiple fingers. And so, maybe, I don't know, putting those in a collection. Like, so, modeling the touch gestures with models and collections actually makes a lot of sense, right? It's very useful to do that. Now, the thing is, if I do this with Backbone, then the thing is I end up including, you know, my view code, the router collection, and this is meant to be a library. This isn't an application. This is just that little library. And, you know, in addition then, now there's a dependency on jQuery, whether I use it or not, and underscore as well. So, you know, and kind of a specific version of each of those. Like, there's kind of a assumed, like, I don't necessarily want to just assume that those are going to be on the page. I don't want to tell people when they're using my library that those should be there, right? So, eventually, we kind of decided to go a different route. And we did fork Backbone. As you see by this clever illustration here, we started out with kind of a plate of spaghetti. And then, you know, this ampersand grew out of it. It had a backbone. And then it lost the backbone. Yeah, okay, so we built on Backbone first. And then this is really just kind of the evolution of the stuff we've been working on for a long time. And, you know, the other thing is that the name is actually just a filthy lie. Like, because there is, in fact, no such file in the whole thing. There's nothing that you can just put, like, include ampersand in a script tag. That file does not exist in the project. In fact, you know, we just needed to name it something just so we could have something to talk about. Because, like, hey, I built the net with lots of different modules. Like, hey, it's kind of a curated set of specific tools, right? So, but in fact, there's nothing in the whole project that you can't, that you can just drop into a script tag without a build step. Like, we're at a point now in JavaScript development, like everybody should have a build step. Because you've got to minify and use it in whatever else you're going to do anyway. Like, you might as well, and, you know, you're going to want to structure your application in some way that makes sense to you as a developer. And ultimately, you know, deliver something in a compressed format, right? So we have a build step anyway. So, like, why not just install dependencies, you know, shove it all together and send it out, right? And so everything is in, everything is in separate common JS modules and in separate repos. So they're, you know, individually installed via MPM. If you want to use a model, you have to go install that model from MPM and use it. And you get just that model, you don't get everything else, right? And then you build it with BrowserFi or Webpack or, you know, any number of these tools. There's more coming out, it seems like, frequently. So, you know, so this is kind of what we ended up with, kind of as kind of a, if we look at what Backbone provides, this is kind of what we provide. And so, you know, if you're building a real-time application or just modeling state without doing any sort of RESTful stuff or really persisted models at all, state is kind of like the bare-bones state management piece that just does, like, here's, you know, here's your core state management is the observable object, essentially is what it is. And then, you know, we have the model which really just extends state. And if you look at the package.js file for that, you know, it's just requiring state and extending state and off you go. And then collection and REST collection is the same thing there. The collection itself is very, very bare-bones in terms of you can store whatever you want. You can store, you know, just plain JavaScript objects if you want and get events and stuff out of it. Obviously not model events if they don't, if those models are not emitting events, but, you know, ads removes that kind of thing, right? And then if you want something that's much more like a backbone collection then you have the option REST collection that includes, you know, the sync stuff and all that sort of stuff, right? Of course, a view and a router. So, the other interesting thing about, you know, doing this that we realized is since we don't really have a core, we don't have to be all that selective about what we make and include, right? Because, you know, if you're shipping everything in a single file, like, you've got to be picky and you should be picky. Because not everyone's going to use everything. But in our case, like, you're just installing gradually so we can build other things. Like, so we have, you know, we have a CLI. We have this kind of app pattern that's useful for, you know, thinking about your app globals, et cetera. View switchers, you know, and then help us around, you know, managing forms, et cetera. So, these are things I would never want to see in Backbone Core because they don't belong there, right? But, you know, as a result of having this very kind of shopping cart mentality, you go, I need this. I need this. I need this. It doesn't matter. We can ship those things as well, right? And they're all kind of individual GitHub repos. And, you know, I know this is for Jeremy, really. He loves Sember. You should go read his thoughts on Sember. It's actually quite, I disagree, but I still enjoy reading them. But they enable this kind of thing for us. Like, it's actually really useful for us when we're, you know, whenever there's cross dependencies between these, to be able to just, if we strictly follow it and we can trust that we're following it to the best of our ability, nothing's perfect, right? Then we kind of get that ability to upgrade without having to go, you know, upgrade hard-coded package files in a bunch of different places, right? So it's really useful for us. If you're curious about what it looks like side by side, and just in general when comparing frameworks, this is a really useful tool. Most of you have probably heard about it, but the ampersand is on there as well. They asked us to add it, so we did. So, I mean, you might be thinking, yeah, whatever, so what? Who cares? Flexibility, modularity. Go home. But, you know, the interesting thing is you end up only sending what you use to some extent. You know, there's obviously always a little bit of dead code, but, like, way less than you normally would. And so to do MVC, all the JavaScript assets for that combined, when you minify in GZIP, it comes down to 28 kilobytes, like, that's nothing. Like, that's smaller than jQuery is by itself. So that's kind of interesting, especially when you talk about loading on 3G or what have you, right? And also, you know, the other thing about that is, like, there's a recent study that came out, I forget the exact details. I'm sure you can find it by Googling, but basically, that measured parsing performance of a bunch of mobile phones. And, you know, it's not just downloading the assets, it's that if you have a bunch of JavaScript, you got to parse and execute all that stuff as well, right? Parse compile, et cetera. So, you know, the less you have, the faster each of those steps go. And I still think, you know, that that matters, right? And the other thing about going really modular is that you can remodel the kitchen without bringing down the building. And, you know, that's kind of a crude way of saying it, but it really is true. You can replace pieces as you need them. If some aspect of your tooling isn't doing what you need it to do, like, you can replace it. And you can replace just that one piece, whether having this huge, like, file size increase and you can kind of mix and match a little bit better, right? I have no idea how that slide got in there, especially after the last one. That's weird. So, speaking of, you know, modularity and being able to swap things out. So, as a bit of a test, like, I think React is a really interesting concept and a very cool library and they introduced some cool stuff. And so, you know, I wanted to try this out. And so, I built the to-do MVC app. I tried to convert the one that we'd already built to use React plus ampersand. So, it used React for the rendering layer, right? And that was an interesting exercise because, you know, I could just replace... I deleted two view files and then wrote two, like, React components. And that was all the code I had to change. So, like, that's all the data layer stuff still made sense. Everything else was, you know... And all I did on the React side is just anytime the model changes, just force an update. So, you know, it wasn't that big of a deal to swap out just a portion of it to use something else, right? Or to convert the whole thing, in this case. But, you know, again, modularity is not really the only feature here. We forked for other reasons, as well. So, just, we wanted a little bit more power out of our model layer, as I implied earlier. So, one example is kind of these smarter, stricter models, right? In Backbone, you know, you don't have to define a specific model. You can just, you know, store a name and then observe the name change, right? But you don't have to define that anywhere, right? And, but the thing is, like, a lot of these times, especially if we're creating kind of our models as the source of truth for our client side application, like, especially in a team setting, like, it's really important to us that those are readable. That's the thing I loved about Django, is, like, you could throw another developer on a project and, you know, they go read through the model's files. It's like, you have a pretty good idea of what you're storing, you kind of see what the relationships are. You can figure it out fairly easily. And we wanted that same thing here. So, we make you define what you're going to store in a model. And so, you know, here you have Ampersand State. So, you see this props thing. So, here we're creating the same thing. So, we're creating a property called name and saying it's a type of string, right? And so, you can still set it like you normally would and watch it, of course. A few interesting things is you can actually, this simple assignment here, the model.name, will still fire the event. Because we know what properties you're going to store. We create a getter for that, a getter and setter for that property as well. So, we can make it observable, even from simple assignments. So, you know, people have different feelings about that, but you can do it if you want. And then, the other interesting thing is that if you set it to a number, it doesn't match the type it throws. So, if you're, it's really useful for catching errors and checking your assumptions in your application as you're building. You know, like you think a value is whatever, and then come to find out it's not. And actually having it blow up on you is extremely useful when you're building. And so, you can kind of configure what it does with properties you haven't defined, et cetera. But we find that useful. And the other thing, you know, session state. This concept of session state is really useful, I think, in client-side apps. Where you have, you know, data that's very specifically related to a model in a collection. But you have no interest in persisting that anywhere, right? Things like this item is currently selected. I'm sure it's useful for that view, but I wouldn't put that into view. I wouldn't put that in the model, because, you know, other portions of your app might want to know what the selected model is, right? So having that stuff in your model layer makes sense. And of course, there's ways to do this in Backbone. You can just override 2JSON and delete it when it's coming out, right? But what we do is we just say, you know, we have this other thing. So you can define any number of other session properties, and they work the exact same way. The only difference is they don't get serialized, right? So, yeah, that's useful. Another kind of interesting approach is having these getters and setters. I mean, getters and setters in general are kind of contentious topics. It's a little bit messy sometimes. You can certainly shoot yourself in the foot with these. But they're useful for models, because what we can do is things like this. We can say, hey, today is a type of date. And then I know from the server I'm going to get it as a, you know, Unix timestamp. It could be a string. It could be a number of that Unix timestamp. And so I can set it in that way. But when I get it, when I go retrieve it, it's always a JavaScript date object. So you don't have to worry about kind of those transformations that kind of happen for you. And again, you look at your model and you can just kind of read that, right? Another thing that we added here is kind of the concept of kind of cached observable derived properties, which is a really long way to say computed properties. But so they're defined like this, right? What you can do is you can say, hey, this thing is derived and you can list as many of these as you want. So nickname in this case, what we're doing is we're saying it's dependent on the name property. And this is how it's calculated, really easy. It's only one way. You can't set through these. But just for the next slide, go ahead and remember that all that we're doing for the nickname is taking the first three characters here from the name. So then what happens is we can observe that in the same way. We can read that property without using, you know, calling a function or whatever. So as far as your template's concerned, all you see is, you know, nickname. And then if you set it to something different, if you set the dependent property on something different, that still produces the same result. It still doesn't fire, right? So it caches and compares against its cache, which obviously there's performance overhead for doing that. But it's really useful for a lot of things. So in this case, you know, setting it to Henry after it was already Henry, it wouldn't change because the first three characters are the same of the computed property, right? But if we change this to something completely different, then it fires, right? So being able to easily declare and observe derived properties is useful too. So you can derive from child models, you can derive from other derived properties. You can use these to manage relationships between models, which is useful. So if you have, you know, a known cache collection of models somewhere else and you have an ID in your model that's a property, you can then go, hey, give me the related model and you can define that as a derived property, which is useful for kind of managing those. Can't send directly. And again, the theme, the resulting code is more readable, right? So I'm not going to go through, you know, too much more detail than that. Definitely if you're interested, just go check it out in the docs. And, you know, we also have a pretty active getter chat thing. If you haven't used getter, it's great. It's like a web-enabled IRC for GitHub projects. But you can also connect with IRC. So yeah, come to hi there if you want. So once you kind of start down this path, as I was implying before, you kind of look at everything through this lens. You're like, man, I don't want, I don't want to like have, I don't want to include stuff I don't need. I don't want to like have any larger dependencies. I want all these little small things that I can use, right? And it's kind of addicting and, you know, arguably in certain cases not useful, but other times it is. You know, when you're building libraries and you're trying to include just a minimal amount of stuff, like it's really quite useful. So, you know, then the question is, well, what about under score? Well, if we look at MPM, it's by far the most dependent on package in all of MPM. That's, I mean, first of all, bravo Jeremy. He's got two things on here. But, you know, you look at that and you go, well, I wonder how many of those really are just using one or two methods, right? I would venture to say there's probably quite a few, right? It's not bad, necessarily. And I mean, if you're on the server side, it's completely inconsequential, like who cares, right? And I arguably, if you're building a whole app, yeah, by all means, just include under score, use it and be happy, like there's no reason that you're going to use enough of those things where it's worth it, right? I'm not talking about huge file sizes here, but when you're writing library code, it feels a little bit like, I don't know if I want to do all this, like I said before. And if I'm wanting a single function, if all I want is a nice cross browser each that I know will work on whatever browser you throw at it, what if I just want that, right? People end up doing silly things, right? So you take library code that otherwise would have dependencies and they just kind of rip out a few portions of them and include them in line. So this guy made this mini score thing and just created a few methods here that he wanted from under score. I don't know if he copied and pasted it. I don't know if they're tested well. So how do I know whether they're cross browser? He's re-implementing this stuff. And this is obviously not, if there is a bug fix, it's not just going to come in upstream, right? And then what about jQuery? I mean, arguably it's the same thing, right? Ideally, I want this as well. I want to be able to have a cross browser ad class that's optimized for newer browsers that just works. If that's the only thing in my library that I need from jQuery, I don't want to be dependent on jQuery. So I want individually installable cross browser tested as much as possible APIs that never get updated because why would I ever need to, right, in that case? And then a strict semver as possible, right? So if my ad class method supported all of these APIs, so you could either add a single class, you could add multiple classes as different arguments, or you could add an array of classes, like why would that ever need to change? That API contract should stay the same forever, right? That makes sense? I mean, if you understand semantic versioning, what I'm saying here is that that major version number should never change, right? Which means that there's never going to be breaking changes to that API, right? Everything is an optimization. You might have, you know, the implementation details might change, but there's no reason you had to break that API. So for items like this, you know, I want them to be, I want these things to exist. So obviously there's Lodash, and people ask about this as well, you know, when they show them what I'm about to show you. But the thing is those are all versioned together, and you can kind of install individual pieces from it. Some of them had kind of oddly deeply nested dependency trees. That makes me kind of wonder a little bit, and I'm not too excited about. And, you know, again, I don't want those APIs to ever change. I don't want my NPM, you know, outdated to show me that Lodash is now at 2.6 when all I did is use that one ad class method, right? Which doesn't exist in Lodash, it's something like that, right? So prepare your tomatoes again. I did other crazy things. So what we did is we made this project called AMP. And AMP is just what I've been talking about, which is, you know, individually installable models that do one simple thing. There's a bunch of utility models that do one thing. And as it turns out, maintaining tiny piles of, like piles of ridiculously small modules is a giant pain in the ass. Who's tried this? Like managing dependencies between these, like, you know, if I come up with a better way to test these, it's like, I don't want to, like, it's ridiculous, right? If you have them in, you know, 40 different GitHub repos, like, good luck, yeah. You're going to change your testing approach on 40 different GitHub repos. It's just not going to happen, right? So, you know, with that, and I think this is quite relevant here. Another flaw in the human character is that everybody wants to build, no one wants to do maintenance. I find this to be true. But, so what we did is we put everything in a single GitHub repo and then just basically scripted the crap out of it. It contains about 40 modules right now, and to add a new one, all we had to do is add an item to a list in a category. So we edit a JSON file, run a build script, and it creates an empty doc implementation and test file for us. We go fill those things out, and then we run the build again and push it. So, and then we cross-browser test everything with the CI system. So it's using, you know, it's IE 6+, not that we were targeting IE 6, but once we did 8, we got 6 for free, so apparently nothing happened in two versions. We'll just leave that be for now. Microsoft is doing good things these days. But then we use, you know, we use Travis CI to trigger a process on Sauce Labs that runs it through a bunch of different browsers. And, you know, we can run all the tests locally as well, of course, using Node or Fanim or whatever to run them locally. But, you know, so we end up with a shared documentation site and simple names that you can memorize, which is useful. One of the things about digging into load-ash modules is they kind of have these categories when they have, you know, load-ash slash modern slash whatever. And also when you're browser-fying things like that, it's using those paths. So you want, ideally, you want those names to just be as simple as possible, right? So what you can do is, you know, MPMI-save, amp, whatever. So, you know, and they're all kind of named with the hyphen. So add hyphen class, for example, right? And you just add them as you need them. There's about 40 of them on there now. A lot of them, you know, basically huge credit to Jeremy and the underscore people. A lot of them we ported tests over and just implementations too. So it's very, you know, it's very much inspired by underscore. But then we added our own things and we kind of tweaked some things that we wanted to be different. And everything's on that shared doc site and including the implementation. So inline in the page, because, you know, we're just requiring a few things and then we have a few lines of implementation, you can also just go read the test. You can go read the entire implementation in the doc site right there. So if there's any ambiguity about how this thing works, just read it, you know. And because the documentation stuff is all separated out from the individual published module, it just links back to the site. It means that those individual modules never really have to be updated unless there's something broken or something that we need to fix, right? So anyway, there's about 40 of them now. There's about five more in pull requests at the moment, I think. But we'll keep building that as we need them. But again, for things that are very small, very reusable, very much like, I don't ever want to think about this again, kind of problems, right? Okay, so those two things. The last thing I want to talk about is the view layer. I would say that's easily the most contentious, most painful portion of any, you know, native web app, right? Would anybody disagree with that statement? Is that not the biggest source of pain? Like, could everyone agree? I mean, maybe I'm just, maybe I'm alone here. Okay, so Phillip and I, so Phillip works on Ampersand with me and works at India. Awesome guy. He's been playing with React for a while and got really into it. He's like, hey, Anarchy, you got to take this thing out. You got to do it. And so we've kind of been going back and forth on this and kind of wanted to share some R&D that we've been doing in this space. And when I say R&D, I mean very recent R&D, like we started this, we've been talking about these problems for a long time, but we actually started working on this like probably five or six days ago. So very, very, very recent. But, you know, templating on the server as a concept is very, very simple. You've got your template, you've got your data, you smash them together and you send it down the pipe. Like, that's easy to understand. You know, just think about that, right? But on the client, obviously we're mutating state. We're dealing with state that's changing over time. And, you know, the DOM is stateful. And so we have to have a way to sync our state to the representation of that state that we want the DOM to display at any given time. And we want those things to be really fast. We want them to be really, you know, live updating, feel really responsive to a user. And so, you know, and Marco, I think, said it really, really well the other day. This is a reminder that the DOM is actually a giant, mutable global variable in the middle of your program act accordingly. It's true. I mean, it's kind of there as a consequence of kind of how things used to be done. If you've ever written something for, like, a canvas or something, you just refresh all the time. You just redraw all the time and you repaint. And you can do so inexpensively. You can't do so inexpensively here. And I think Jeremy called it. I mean, it really is. Like, in a finished back one app, you know, if you take kind of the recommended approach, you don't have to write the glue code, you know, that looks into the DOM, finds an element with specific IDs and updates it manually. You know, when the model changes, you just redraw the thing. The views update themselves, right? Ideally, we just be able to redraw. Now, we always know that that's not necessarily always the right solution, right? So, for a more concrete example, say that we have this, right? So, the top is our current state of the DOM. And then, after we run, or in the state of the particular view, let's say, and then at the bottom, that's the target. That's what we want to end up at. We want to add that, there's a new paragraph tag there. So, the simple way to do this is, you know, if the element contains that entirely, you just set the new inner HTML to G, just that string, right? The browser parses it and puts it in there for you, right? And if it's infrequent and if it's simple enough, like, that's fine. There's no reason to over-complicate these things. Like, you know, a lot of people over-optimize here, I think. And I think that's Jeremy's point in the docs. If you're not... If this isn't happening all the time, and if you're responding in some user action to change some state of view, like, you don't need to bind it, probably. You can probably just redraw the thing, right, and be happy. But for larger sections of DOM or if the user input is part of that, so if somebody has a focused input inside that element and you redraw, they lose focus. So, there's a few cases where this really doesn't... It doesn't apply all that well, right? So, you know, hypothetically, wouldn't it be nice if we could do this and say, you know, call this magical mutate element function, which I actually think should be part of the DOM. But, you know, we pass it an element and you say, hey, this is my target HTML. And then what it would have to do is it would have to go, okay, there's a new P tag here, so I'm going to create that element. I'm going to set its content and then append it. So, if this mutate function was smart enough, that's what it could do, right? Then we only update what's actually different and, you know, we don't thrash the DOM without reason to, right? And, you know, the other nice thing is if the DOM is, in fact, the same, we don't do anything. Whereas if we kind of blindly re-render, that's going to happen even if, even in the cases where the resulting HTML is not actually different, right? So, arguably, it's a little bit wasteful, right? This concept, we didn't invent this concept. It's this concept of DOM-diffing. Ding! But, basically, if we could do this with higher performance, then all of a sudden our whole binding problem becomes much, much, much simpler, right? Because then it's just like server-side rendering. You run it through your template and be happy, right? And so, if you're not familiar with React, that's essentially what they did. They approached this problem saying, you know, I think we can do this performantly. Which is really interesting. And, you know, so if you were to smash the two together, it might look something like this, where you have, you know, you create this, instead of your view, you create this React class. And, you know, what I'm doing here is just to get initial state, just creating this. Assume that this model is a background model, for example purposes. And then anytime the model changes, force update of the component. And the force update will then, you know, run this render function. If you haven't seen this syntax before, you'll be transforming the code ahead of time, and compiling it down to JavaScript functions. Because it's kind of ugly to write, so they wanted to make it as simple as possible. So then you kind of just return, your render just returns the new React virtual DOM, is what it is. But the downside to this is now you, you know, if you have an existing app or whatever, you have to switch to their templating system. You have to be okay with having these angle brackets in your JavaScript. Some people don't like that, I'm one of them. You have to use, you know, their virtual DOM setup and their application patterns really. I mean, if you're going to go React, you kind of should just go React to some degree. And, you know, so we, you know, the thing that I've always been fighting with, like can we just, like, steal their best ideas here? Right? Because there's some cool stuff in there. The thing that I don't like is having to tightly couple, you know, that type of architecture with a particular template. Like, if I've already got something I'm happy with, like, conceptually, it'd be really awesome if we could do this with strings. Right? I mean, conceptually, if we could do this performantly with strings, it'd be really cool. And then we can generate that HTML string using any template library we want it to. Right? So what would we have to do in order to do this? Right? First of all, we can't just, like, diff two HTML strings. Like, you have to understand what they're containing. Right? So you have to parse it. You know, you have to understand what elements are in order to get an intelligent diff out of them. Right? So you have to parse it into some sort of AST or virtual DOM. You then have to, you know, diff that AST, that abstract syntax tree if you're not familiar with that, against whatever the last one was, right? Conceptually. Or against the DOM. And then you have to generate a set of DOM transformation functions from that diff. Right? That's what we'd have to do, and then apply them to the DOM. That's what's necessary to do this, right? And, you know, individually, those are all solved problems. There's really performant HTML parsers in JavaScript. There's, you know, there's virtual DOM implementations that are not React. And, you know, so... But the big question is, you know, can we do this performantly? And can we do it without, like, sending tons and tons of crazy JavaScript down to the client? So everybody knows right? And especially one with regular expressions. Right? Everyone's seen this wonderful Stack Overflow question? But... See, I think there's a flaw in this logic in that because we're not parsing arbitrary HTML, we're parsing HTML that we just generated. Right? I agree. You shouldn't parse arbitrary HTML with Red Dex. You shouldn't do it. But what if, you know, if we make a few simplifying assumptions, and the reason you shouldn't, if you're not familiar, is because HTML is a complex spec. You know, you can leave, you don't have to close all your tags, you can have, you know, a list with just opening LIs that never get closed, and browsers should be able to deal with that. There's all sorts of rules about, you know, how it's supposed to fail. In the case of we have, you know, malformed HTML. So, conceptually, we shouldn't parse arbitrary HTML. But if we, for example, say that, hey, guess what? Close all your tags. All of a sudden, like, it becomes a hell of a lot simpler. So, you know, let me show you just kind of what we threw together, and you can tell me I'm crazy. So, what we did here is, as a mix-in, we wrote this thing, this VDOM mix-in thing that you see, we're extending here. And then everything else looks pretty much like a background view, right? We have, you know, this template here and that's just including, that's going to generate the whole new string that we want. And then in our render function, we're just calling this render with template thing. Passing in the attributes, right? What that mix-in does, if you look at it here, so this render with template, it's, you know, figuring out whether it's the first render, you know, determines whether your template is just a plain string and deals with that if it is already, which means that you don't have to do any of this stuff. And, you know, or if it's a function calls it, etc. And then what we do here is we parse the resulting HTML template and then we turn it into, we run it through this AST to VDOM thing, which basically takes the AST that that parser creates and then turns it into an implementation, there's a project out there called virtual DOM link coming up in a future slide. That's basically just that virtual DOM portion of React. It's not from React, but it's the same concept. And so then we, you know, we convert, we generate this AST and then once we have it, we store it and cache it. So now we're just diffing ASTs on each render, right, or virtual DOMs on each render and applying any diffs that come out of that to our HTML, right? So when it's all said and done here, you know, we're patching this element with the patches and there's a few things in here that are a little wonky just because we want to handle both ampersand and backbone with a single mix-in. The parser is all of 75 lines and it's got some pretty good tests and it's pretty quick. Obviously there's work to be done here. We, again, talking like five days worth of random hacking here while trying to prepare for this talk as well, so definitely not bulletproof. But I mean, surprisingly good. So let's see how this actually performs. So some of you have seen this test that Jeremy created where you need to come to the circles moving around. So what we did is we added an input element to that and just to kind of show how this works. So if we run it with backbone, you know, this kind of thing, right? So it's looping, getting in roughly 18, 19, depending on like the mood of my computer it seems, it's roughly in this range, right? So, again, and now we can't retain focus here because these are constantly being re-rendered, right? Now, this version is the one that's using HTML strings. Literally creating new HTML strings, parsing it, etc. And what we end up with something not too far off. It's basically the same speed and now you know, we retain focus, right? Which is kind of neat and, you know, we've got a ways to go here. I mean, it's not perfect, but you know, it's really fascinating, right? Like, we can take a few pieces from what they've been doing in React and kind of extract some things out of it and steal some ideas. This is the project that we're using for this very cool thing. Right now, we're using this because this was the easiest thing to grab and use to kind of diffing things. Arguably, there's some optimizations we can make here as well. We might end up using something different, but that's what we're using right now. And so then, what's the actual value? Obviously, simpler views. You have to do less glue code, less bindings and much easier to understand, much easier to reason about. Much easier to drop a new developer who's used to back end server-side HTML rendering and just being able to use that stuff. Use those skills here as well. Initial findings, roughly the same performance as the replace in Backbone. The file size is tiny. You know, you're adding minified GZP 7 kilobytes of code to your project and all of a sudden you get nearly equivalent performance, React style rendering in your template. So that changing really anything else. You're just adding a mix-in. Right? So I think that's powerful. And the other thing that if you've done any React you know one of the cool things that they do as well is kind of this nested view components. And Ember is doing the same thing with Ember components where you can kind of have this tag that have custom special meanings that are really views. So we can actually do this as well. I didn't show that here because it's still a little bit shaky. But we can do the same thing there. So things like rendering a collection for example. Normally what we do is do something like Marriott's render collection or we have the same thing in EmberSand where you really have to create this other object that manages that instead of just writing it in. So what you can do here is you can actually loop in your template and create these kind of custom components. And again because it's kind of using kind of the HTML component syntax for this if it hits a known registered component type in the tag then it will instantiate the view for that and pass in the appropriate models and stuff that you specify in there. So this works with any template language because ultimately you're just producing these HTML strings that we're using for this. So the nested view stuff and sub-views can be done in this way as well. So whether or not to show a sub-view can just be a simple if in your template and you're done. And you retain your choice of templating languages. So yeah, we've got this mix-in that works with both Backbone and EmberSand right now. We're going to optimize the crap out of it because right now it's very much just quick hacking. The mix-in code is there. I'll share my slides later so you can see it because these are hard to read. And then the little parser is there. The other thing about the parser is we have a stringify method as well. So it's very much like JSON to get you parsed in stringify methods. And what that means is it's very easy to kind of turn your AST back into a string at any point you want which can be useful for server-side rendering. But the current flow looks something like this. Any template language, HTML string, parse it into an AST, generate the virtual DOM, get the diff, apply DOM transformations. There's lots of steps. And very likely there's a few things we could do here too. So we've experimented with taking a template language that isn't just doing string content nation. It's something like jade that compiles into something else. And then instead of compiling to the string, just compiling directly to the AST. So we can essentially skip that step as well. You can still retain that flexibility but if you want to optimize, if you make your template return that instead, then you're kind of ahead of the game. And potentially we might be able to just diff the ASTs. If we can do this fast enough then we can cut out even more complexity. The VDOM stuff is great and it gets us a lot of stuff for free. But there might be a few things that we can do to tweak it that we want to do. So that's much experimentation yet to be done. But potentially this could be optimized further. And then other things. You might be able to do isomorphic apps more simply in this approach. Because you can render your application, mutate that AST and then just do two string and you've got your views, right? And then other interesting ideas. Maybe we could do the parsing in a web worker just to optimize things a little bit. I don't know if it's faster but we should try. There's lots of things that this enables when you can serialize your view state, basically your DOM state. Anyway, I think the thing that I want to leave you guys with is just that I think we should really instead of just jumping into hopping onto the next bandwagon that comes along and this is the coolest newest thing that's out there. I think it's important that we kind of remember that at one point everything was the hot new thing. I think we should really work on building much more flexible, much more decoupled, much more modular approaches because arguably that's what made Backbone successful to begin with. Being able to use it in lots of different ways for lots of different things. I don't want to see that work continue not just the hey, let's build a whole new framework that does all this new stuff. That's kind of my call to action for you guys. Let's push these things a little bit and not just assume that someone else is going to solve these problems for us. Those are the links ampersand, the amp project and the view mixing. Again, I'll post these slides in a little bit and that's all I got. Thank you.