 It looks like it's about one o'clock if my computer's right, so I suppose we'll dive in since there's kind of a lot to cover here. So the title of this talk is, What's the fuss with all this JavaScript? So real quick, a little bit about me. My name is Blake Hall. I'm a developer and trainer with DrupalizeMe and Lullabot. If you haven't checked us out yet, we've got a booth downstairs, 407 and 411, they're right next to each other. I bought by and get some pony stickers. I forgot to bring some with me now, but I'm sure we've got some down at the booth. Lullabot, for those of you that might not know, is an interactive development design agency. We've built a bunch of big Drupal sites, been around for quite a while. Today what we're going to cover, we're going to talk a little bit about the problem that JavaScript's trying to solve and where JavaScript frameworks kind of came from. We'll do a really quick kind of one-on-one level intro into Backbone, Angular and React and kind of compare and contrast all of them and then hopefully we'll have some time for questions at the end. So a little back story, I've been doing Drupal for give or take 10 years and I got kind of burnt out with it a couple years ago and I just sort of didn't feel like I was learning a bunch of stuff and wanted to go play around with other things. So I spent last year going to JavaScript events instead of Drupal events. This was taken at NodeConf in Petaluma. It's a tech conference that involves camping. You're out in the woods, it's really hands-on. I highly recommend it, it's the closest I've ever slept to another Lullabot. That was a tent for Jared Bittner and I, but I highly recommend it if you have any interest in Node whatsoever, it was a really, really fun event. Another great one was JSConf that was at Amelia Island in Florida. The parties there were ridiculous. The last night we had sort of an adult carnival. So that's a bouncy castle for grown-ups. I got to put on the giant arm-length boxing gloves and punch Eric Durand, which was really, really satisfying. And it was just a really good time, there were a lot of really good talks. I highly recommend getting outside the Drupal ecosystem if you haven't done that for a while. Like I said, it was a lot of fun. Grilled turkey legs, amazing, funnel cakes, all kinds of stuff. So what does this have to do with any of this? This talk was actually kind of either shamelessly stolen from or inspired by a couple of talks at JSConf last year. Marco Rogers did one on finding common patterns across different front-end frameworks he's worked on. At the time, he was one of the team leads at Yammer. I think he's moved on since, but super interesting talk. It's on YouTube. You can go kind of check it out. And then Ryan Florence did one. I'm not even going to try to pronounce that session title, but it was sort of a mash-up of Ember, Angular, Backbone, React, Polymer, yeah, okay. Another really good talk. He goes into a bit more detail in that one about sort of the different areas of concerns between the different frameworks that I think we'll have time to tackle. So those are two really, really great resources to kind of check out if you're interested in this stuff and want to kind of go in more depth. There will be links to those in the show notes for the slides. I'll get those uploaded as soon as the session is done. So meanwhile, back in the Drupal world, I double-checked this morning and Backbone and Underscore were committed to core as part of the Spark project about three years ago already. So they've actually been in Drupal 8 for quite a while now. So just like when we added jQuery back in, I don't know, what's that, Drupal 5, there's a new tool in the toolbox to kind of figure out how to leverage and take advantage of. So I think it makes sense to kind of step back and look at what other JavaScript frameworks are doing as well and see sort of where Backbone fits into that landscape and when it's appropriate to use Backbone versus maybe some of the other tools. Another thing to kind of set some context is I pulled these numbers yesterday, actually, and I saw this morning on the carpet that Drupal.org was actually first launched in 2001. So the website's been around for, give or take, 14 years. Back when I started 10 years ago, there were about 350 contrib modules. So there was actually a point in time where I'd installed and played with every module that was on Drupal.org. I don't know if you can see those in the back, but right now we're at 30,000 modules. So I've lost touch quite a bit. I haven't installed probably 26,000, some of those at least. And I also, I went down and filtered and it's something like 17,000 actual modules and then the rest are sandbox projects, which kind of blew my mind. I hadn't looked at those numbers for a while. I was sort of back at the envelope guessing we were at 12,000 modules. So 30,000 is a bit crazy. But just for comparison, in 2009 NPM came out and that's sort of JavaScript's package manager of choice. So it's only six years old. It's sort of the home for all of these JavaScript libraries and frameworks or at least it's an easy place to sort of download and deploy them. And if you can see that number, I'm not sure if you can in the back, but there's 147,000 packages. And this was yesterday, this morning when I checked it was 149,000. So in six years they've managed to share five times as many packages. I know it's not a total apples to apples comparison, but it'll give you a sense of sort of how quickly that community is growing and how much JavaScript code is out there, which again was just sort of ridiculous. 148,000 packages in six years is a lot of code. So where did all this kind of come from and how did JavaScript sort of rise to popularity? So back in the old days, and by old days I mean 1996, MapQuest kind of launched for the first time. So I think back in 96 this was probably a good example of a pretty complicated UI. So you've got some buttons that are basically doing form submissions and full page reloads anytime you want to do any sort of navigation at all. So this is sort of the complex internet circa 1996. Then this Ajax thing kind of happened somewhere between 2004-2005 with Gmail and GMaps and whatnot. And a lot of times we're still doing the similar kind of Ajax stuff that's been around for now 10 years. And a lot of times it's not actually Ajax, right? We're just doing kind of naive HTML replacement via third party API request. And more or less if you think about it, it's just a transformed version of what we were doing back with MapQuest. It's just happening in the background and we're doing some client side processing. So this has been around like I said for about 10 years already. So 2010 or so Backbone came out. It was written by a guy I believe was at the New York Times at the time or maybe he transferred to the New York Times after the fact. But it was sort of a thing that was built to help manage the complexity around some of these client side interactions with data and being able to keep your client side browser and the server in sync. So it was just sort of improved code organization to handle all of that Ajax management stuff that was happening in more complex applications. Browser functionality was sort of increased quite a bit and people were building apps that were a bit more native like at least back then about five years ago. So now we kind of find ourselves in this situation where there are pretty much JavaScript frameworks coming out left and right every day, right? And how do we go about making sense of it? How do we figure out where to invest time and energy? Hacker News certainly isn't a great place to sort of figure out where to throw your business and kind of which particular framework to put your time behind in investment and learning. So stepping back a bit, let's talk a little bit about what these frameworks have in common and what kinds of problems they're trying to solve a little bit. So this is a really, really basic definition both Ryan and Marco used it last year and I think I agree with it pretty much. If you're going to have a client side framework you want it to do some sort of data modeling. So an object oriented style like method of encapsulating and representing your data. You want to have some sort of presentation layer that you can handle updates to that data model and keeping things kind of in sync dynamically. You want to do some kind of routing so you can use the back button in your browser and so things are URL addressable and whatnot. And then obviously you probably want some sort of method for talking to the server that's feeding you data so you don't have to do page refreshes all the time. So really, really basic definition but for the purposes of the next hour this is what I'm kind of considering a framework. The other thing I want to point to, I'm sure some of the code samples that are going to be up on the screen are going to be hard to see in the back. They're all lifted from this to do MVC.com site. If you haven't seen this before I highly recommend checking it out. It's basically a really, really simple one page to do list management app written in every single library you can imagine basically. All the codes on GitHub, you're comparing apples to apples in that case and you can kind of see in most cases the actual author of the framework is the one that's contributed back to this project. So it's sort of like a best practice version of an implementation in language X, Y, or Z. So it's really kind of a handy resource. Here's an example of what the to-do list app actually looks like. All of them are pretty much identical. The CSS is the same. The markup's obviously different depending on what the framework recommends. The one that's screen capped here is actually just vanilla jQuery stuff. So you can, if you're already familiar with jQuery and you haven't touched one of these frameworks before, you can sort of look at that and make sense of that and then compare and contrast it with some of the other frameworks that we'll get to. It uses local storage, so as long as you're not quitting your browser, you can kind of maintain your to-do list. It's just some pretty basic functionality. You add new items, you can delete items. You can filter them based on their status if they've been completed or not. And then you can sort of flush the logs so the completed ones disappear. So it's a really, really simple single page app. Most of them are in the neighborhood of 200 lines of code or so in the more complicated portions depending on which framework we're talking about. So let's start with the backbone example. I mentioned it a few times already. It's in Drupal Core and we're at Drupal Con. So since we have access to it, it seems like a good place to begin. It's also the oldest. So one of the sessions that I watched kind of prepping for this came from JSConf in Uruguay last year. And the original author of Backbone basically said the problem he was trying to solve was building the ideal web API for the client. So if you're in a browser, what would the ideal way to interact with remote API be or what would it look like? And one of the things he mentions that I think is really, really true, especially if you've done a lot of jQuery development, is it's really, really easy to just grab data from the DOM and treat that like the actual source of truth rather than something that's coming directly from your server. So if you wanna say highlight posts on a page that have more than ten comments and you've got all that data in a table, you can kind of pull that and sort it differently. But that's not necessarily the greatest object-oriented way to organize things. If you have an actual model that has that number associated with the actual data itself, it's a little easier to reference, especially if the DOM's changing because of some other crazy ad on the page or some other plugin that somebody kind of stitched together. So the moral to that story is basically the DOM is a user interface. It shouldn't be your data source, at least according to the backbone folks. So most back-end devs especially are probably familiar with the MVC pattern. Backbone kind of calls it MVP, Model View Presenter. There's a whole bunch of semantics about a bunch of different MV asterisk patterns. I'm not gonna pretend to understand the differences between all of them. But if you wanna go read Wikipedia, Backbone considers itself Model View Presenter. Here's a pretty good slide I think that kind of wraps what Backbone is trying to do at least at a high level into a nice little picture. Basically, you've got user input on the actual page is gonna trigger some event in the view that then triggers a data change in the model. The model will sync with the server. It emits a change event, and then the view re-renders itself in response to that. So the presenter layer is sort of not clear in this diagram. And that's one of the reasons I kind of left it out in the last slide is it sort of doesn't matter where it is. You've got a view that is showing the data. You've got a model that is the data. And then there's sort of some magic that's happening in between to get those two in sync. So let's take a look at the actual Backbone model from that to do app real quick. I don't know if you can see it there, but on line 11, basically there's a base Backbone model class. And anytime you're creating one, you just extend it with your own new custom class. In this case, it sets up a couple of defaults. So there's an empty title and completed is set to false. So it's a really simple data model. And then there's the idea is that you add sort of extra rich methods that sort of add functionality to your data model. In this case, the only method is toggle. And that sort of sets the completed state to either true or false, depending on if the box has been checked. So it's pretty simple kind of 00101 stuff. Just come up with your data model and extend Backbones built in class and build it out. So the view layer. Again, there's another base class that you extend. In this case, it's backbone.view. You'll notice that on line 16 there you're passing in an actual template. Backbone's default render method is a no op. So there's no template rendering at all that kind of comes with backbone. So there are quite a few folks that are using Backbone plus react now, which we'll mention again a little bit later. But you basically need to come with your own method of rendering a template. And it comes to backbone. Since it depends on underscore, lots of folks use underscore for the templating system. But it's pretty decoupled and you can kind of swap in whatever you like. So something like twig.js might make sense for Drupal folks if you're already doing twig development or handlebars or kind of whatever else you're familiar with. The other thing that we're doing here in the view class is that we're kind of adding the event binding that's going to happen. So that's how that communication happens between the model and the view. You've got the events that happen on the view side and then the methods that they should call to effect change in the model. I mentioned this before, but here's the actual render method. So you're basically responsible for, in this case, they're updating this dot the element that's from the HTML file. And then when the data comes in from the model, that gets updated via the render method here. And then as an aside that sort of best practices, you return this from the render method so it can be chained later on if you need to do kind of something more fancy. So I sort of mentioned that that presenter bit is a little bit amorphous. And at least for me, that's kind of okay to think about. This is sort of the data picture and the data model that you can use for what's going on. And when it comes down to it, it's sort of what I would call like an observer pattern. So you basically are setting up kind of a key value observation pair. So you've got a particular event that's happening on the view layer after user input that's talking back to the model to change the model data. And then the model that's emits an event that then the view responds to and re-renders itself. So we'll see this again, especially with React. One side effect, again, that we'll talk about in a little bit, is Backbone has another concept called collections. And they're basically just a way of nesting models together. And how you set those up can really affect how this key value event binding react with each other. And you can have some pretty crazy complex situations that develop if you don't set things up cleanly, which is a problem that React actually helps solve. So one thing that's sort of interesting, I think at least, is to take a look at who's actually using this out in the wild. It's probably not a surprise that Backbone kind of has the most sites since it's been around for the longest. But some of my favorites that I found from their Wiki are Ardio. So the entire navigation interface for their web app, and I think the desktop app too, is Backbone. Airbnb is also using Backbone, Foursquare, Bitbucket, WordPress.com. So just like Drupal, WordPress is apparently fans of Backbone. And then the tonight show is starring Jimmy Fallon. The NBC team here in LA actually rolled out a decoupled site that's using Backbone to render all the front end stuff. So it's kind of built by a local company here, which is kind of cool. And it's a project that Lullabot's done a bit of work on as well, which I think is kind of cool. All right, so next up we've got Angular. So Angular is a project that's kind of sponsored by Google. The original idea is they were trying to build a JavaScript framework targeted at designers and sort of non-back-end devs, which to me is fascinating. Because once you start diving into Angular, concepts of dependency injection are everywhere. And that's not something that most designers I've met are super familiar with. I'm not even, I'm learning still. So Google must be filled with really, really smart people. The other thing that they're kind of shooting for is the way HTML and the browser eventually should work if you're on the Angular team and you work at Google. So we'll talk a little bit about what that means in a second. So Angular kind of came around after Backbone, obviously, to sort of help solve some of the pain points that were exposed with this single-page application architecture. One of the things Angular does quite a bit differently than Backbone is that it uses a more declarative programming method, which winds up being the easiest way to think about it, for me at least, is it's template-driven rather than model-driven. So when you look at Angular code, you'll see the templates look quite a bit more complicated. And there's sort of more magic happening at that layer than there is the data modeling layer. The two big kind of key features or pieces of functionality in Angular are data binding and directives. So those are two things. You'll see all of the blog posts and pretty much everybody talking about in one way, shape, or form. So taking a quick look at two-way data binding, this is sort of like the whiz bang feature that gets all the attention on hacker news when it first came out. Basically, you've got this declarative template setup that has Angular directives in it. And then Angular will compile that. And then it's basically constantly watching the data model and live updating the template in real time. So you'll often see in demos like an input text box and then outputting the input of that in text right below it. So it's really handy for sort of complex UI interaction where you want real-time updating. But one of the side effects of that is the way it has to do that dirty checking can lead to some performance issues. They're actually changing that in Angular 2 to a model that's more similar to React. So looking at the sample code from the to-do app, you can see that we're calling add to-do on ngsubmit in the form input. So in your template here, you're basically defining the method that's going to get called when the form input runs. And then down here, we've got an example of a directive highlighted, the ng-repeat. There's this to-dos data object that we're looping over and filtering through. So you've got kind of logic in your templates, if you will. So looking at the actual JavaScript code, here's the method that actually handles adding the to-do. So we're setting up a new to-do. We're grabbing the text and trimming it that came in from the input. We're setting completed to false because it's a new to-do item. And then we're using this store.insert to save it to our to-do store. So if we go up, scroll up in this file, it's the controller. You can see that store.todos is mapped to this global scope object. And that's basically how Angular handles all of its variable management. So there's this scope thing that you'll see dependency injected wherever it's needed. And you can basically do scope.variable name and stick stuff in there that's then available inside of your template. So if I go back to the template, this to-dos that's on line 25 that we're looping over, that's the same as scope.todos. So I mentioned that ng-repeat thing is a directive. In an hour-long session where we're trying to cover three frameworks, talking about directives in great detail would take way too long because it's one of the more complicated parts of Angular. But you can basically think about it as a way of creating a domain-specific language for your HTML document. So I've got a simple example coming up that walks through what exactly that looks like in practice. But basically, you're teaching HTML new tricks. You're inventing your own new tags that have complex UI interaction and behavior. Things like the video element that was in HTML5. If that didn't exist, you could reinvent something like that in Angular, which is pretty cool. Here's the example again of the ng-repeat. So that's one of the core directives that comes with Angular. It's just looping over each data item that gets passed in to the directive. So moving on to the, this is a totally trivial but simple example that kind of illustrates the point and the power of directives. So let's say we want to add share buttons all over our site and the people that are doing the content input aren't necessarily really great at HTML or they don't want to copy and paste like the 75 share buttons that are gonna go on every blog post. So we can use this new custom markup and have a share button tag and pass in the link attribute that we want those share buttons to have. So this markup is pretty simple and pretty easy to understand. You can probably teach people that know HTML how to do something like this. The actual Angular directive looks something like this. So we create a module called share buttons. We register a directive called share buttons. You'll notice there's some name normalization stuff going on where you've got the hyphenated version is the module name and the HTML tag and then the camel case version is the directive name. It's just an Angular convention. Kind of get used to it quick. And then with the directive API in the callback there, you return an object that you can restrict the type of directive you're dealing with. So in this case, restrict E means Angular will only treat this as my custom directive if it's an actual HTML element. So that share button tag is represented by E. There's another option where you can do, you can use attributes as well. So that would be an A. And then you would pass in like the list item. We had an ng repeat here. That's an attribute, not an element. So you can kind of tweak how the directives work, which is sort of handy. Scope is definitely the most complicated part, especially to get in too quickly. But basically that sets up how the data binding is gonna work between your directive and the template. So if you want two-way data binding or one-way data binding or you wanna inherit scope from a parent directive if they're nested, you can do all kinds of fancy and crazy stuff there. In this case, we're just setting up a really simple one-way link variable that gets passed into the template. And then we've got a template URL. So that's the file that's gonna get loaded and actually rendered when Angular compiles our custom directive. So taking a look at what that template file looks like, this is just the full markup that would get output for a Facebook, Twitter, and Google Plus button. So you can see in each case, there's this double curly bracket link thing. And that's what's getting passed in from that original share button markup we had. So when Angular runs through and renders this output, it'll drop whatever link was passed in as an attribute to that custom tag into the output. And then this is sort of what the final product would look like. You could style it however you want or you can have it kind of custom. So you can imagine situations where you can create these directives with really, really simple tags and pass in some data values and then render like a canvas element that has a drawing or some sort of calculator widget or sort of whatever you can come up with, which is pretty powerful. Being able to make your own HTML tags and sort of define your own markup depending on the actual domain you're working on is a really cool thing. And I think it's one of the reasons Angular kind of got super popular. So 2.0, I think it's coming out sometime. I don't know when. Google's sort of not committed to anything necessarily, although I heard somewhere they were planning on releasing an actual Angular 2 app around now. And that was at the conference back in February. So I don't know if it's actually come out or not yet, but it's all the developments happening on GitHub, it's all kind of out in the open. You can kind of follow it if you want. There was a big kerfuffle last year at their European con because they had basically announced they weren't gonna preserve backwards compatibility. So all of the Angular 1 apps that had been written would either need to be rewritten or they'd need to sort of figure out how to solve that problem. So for me, it was kind of fun to watch another community wrestle with that kind of stuff because we've done that in the Drupal world for years. But the bottom line is I have no idea when 2.0 is gonna come out and I'm not in touch enough with the Angular community to sort of provide any sort of best guess for that. But looking at some blog posts about how it works, it's pretty radically different. Both Angular React and Ember have all kind of taken the best ideas from each other and are now working towards something that I think in the end is gonna wind up to be somewhat similar, but with wildly different syntax and sort of functionality. One example with Angular 2 is they're using something called AT script. So it's like a typed JavaScript that compiles to regular JavaScript, which is really different. And instead of doing the two-way data binding with dirty scope checking, they're gonna use an architecture similar to Flux, which is what React uses, which we'll talk about in a couple of minutes. Oh, they're not? Cool, I didn't know that, thanks. So who uses Angular? I pulled these from builtwithangular.org, which is linked on sort of their official site. So there are probably tons of other people, but I just grabbed a couple. It sounds like Google's using it internally for double click, but most of their big products aren't using Angular, which to me is a little bit curious. A Drupal site, the weather channel is using Angular, which is kind of cool. It seems like Angular is really caught on, especially in the Drupal community in the last couple years, which I think is kind of neat. Another example is MSNBC. So this was another Lullabot project that's got some Angular code going on. So I'm trying not to be too biased, but Last is my favorite framework, React. So this was originally released in 2013, so it's definitely the newest kit on the block. And it's quite a bit different than the others. And I think the differences are sort of the big strength and the reason why it's the most interesting, at least to me. One key thing that's different is it's really just a template engine. It's really just a view layer. There's code that kind of can come along for the ride that does the rest of what Angular or Backbone can do as well, but really React is just a way to handle templates. So like I mentioned before, there are a lot of people that have kind of wired together Backbone and React to take advantage of the way React handles display and performance, but still using Backbone for data modeling, which I think is kind of neat. So React is built around this concept of components. So you build out components in usually JSX files, and it's got sort of a XML-like syntax that then compiles down to JavaScript. But you can also write just native JavaScript and it works the same. It's just a little bit harder to read, at least in my opinion. So basically you set up the different components of your page and then you can nest those. So in the case of R2Doo app, we've got one component that sort of contains the whole app, and then each to-do item is another component inside of that. And then the second line here, you're basically just grabbing an element from the index file to put the component into. So if we take a look at the render method for this particular React component, it basically has the markup that's gonna get displayed, and then it also is tying together the event binding along with the state from the React component that gets displayed. So calling out kind of how edit functionality works with the React component. On the particular label that's next to the to-do item, we're defining this on double-click thing, and then we're saying call the handle edit method when the item's been double-clicked on. That handle edit method, it basically says set the on edit property and then set the state to be whatever they entered into the edit box. So this state management thing is sort of how React components deal with data. They all sort of manage their own internal state. And then the render method again is using that state value with the edit text that got set in the previous method. So one thing I think that gets conflated a bit when people start reading about React, and it was definitely hard for me to wrap my head around, is how React and Flux interact. React by itself isn't really a framework in the definition I threw up before, but once you tie in a Flux-like library, then you sort of have something that resembles more a framework. Flux itself isn't actually a library. It's more an architectural style. So it's sort of a competitor to MVC rather than a competitor to Angular, I guess. So one way we can kind of visualize it is I mentioned before, you can wind up with a lot of complexity when you're doing this observer pattern if you don't set your models up right. So one of the classic examples was at Facebook. If you get a new chat notification, there's the chat icon in the upper right-hand corner. There's the actual chat message that pops up. There's somebody's online status if they just open their phone to send the message. All of that is representing the same data in terms of how you would do the data modeling on the client side, but you're not gonna set up one view that controls all of those different components. So basically you can have these weird circular dependency cascade effects going on between your models and views and things can get pretty hairy pretty quickly. So what Flux basically does is simplify that and say all of the event and data flow is gonna be unidirectional. So it's only ever gonna flow one way and we'll just re-render everything every time. So this is sort of in contrast to that backbone image we had before where you've got user input that happens with the view layer. That triggers an action. The action then goes and talks to this thing called a dispatcher. The dispatcher then handles updating data in the store. So that was the set state in the to-do example. And then the store triggers the render method and basically everything's re-rendered constantly. And the way React gets away with this is with something called the virtual DOM. So it's not actually re-rendering the full DOM by itself every time, but it's keeping a lighter weight version of the DOM that it's making changes to when it does the re-render. And then in batches, it's writing that out to the actual DOM basically with a diff algorithm. So it's kind of similar to the way game engines work, actually, which sounds like it'd be a performance nightmare, but it turns out that it's actually kind of an okay thing. So who's using React? It actually kind of came out of Instagram, so their whole web interface was actually where React sort of came from. And then I mentioned that Facebook's using it. So if we're worried about performance and sort of how this re-rendering would affect our app, I think I would guess Facebook's probably the biggest site on the web, and they're probably dealing with the most complex data model, at least of any site I've ever worked on. So if it's working well enough for them, it's probably gonna work well enough for anything that I'm dealing with. Another recent project that launched with React, I only know about this one because I worked on it earlier this year, is the SNL 40th anniversary site. So this is another example of decoupled Drupal using React components on the front end. So there's a handful of other frameworks that we could kind of take a look at and compare. They're all on the TodoMVC site, I think. These are probably three of the more popular ones you'll hear about. Ember is really big, especially in the Rails community. It's sort of a more traditional, more full-featured MVC framework. So that's sort of a good one to look at. Marionette is sort of backbone plus some extra convenient stuff. I'm probably gonna misremember this, but I think it came out of or is heavily used by Etsy. And then one of the newer kids on the block is Ampersand.js. That comes from a company called And Yet, and it takes a much more modular approach and uses smaller pieces glued together similar to a backbone, but a little bit different. And then another resource I would really recommend is another Lullabot, John Hannah, wrote this really great blog post on choosing the right JavaScript framework. So he sort of goes through these in more detail and kind of walks through how they all work and why you might wanna pick one over the other. But that's all I've got for slides. We can dig into the actual code examples and sort of see how they work and run in a little more detail. But otherwise, I'd love to sort of open it up for questions and sort of hear what other people are doing with JavaScript frameworks and decoupled Drupal specifically. Cool, thanks. Well, I'll be down by the booth in a little bit if anybody has any questions or wants to talk anymore. Thanks.