 All right, thanks everybody for sticking around for my talk. I'm going to go ahead and get started. For those of you who don't know me, my name is Ryan Stout. And if you Google my name, you will find nothing about me, because there is a comedian who has my name, which is, I guess, good for me, because I happen to have at Ryan Stout a Twitter. And so at least twice a day, I look down at my phone, and there's a tweet from someone I don't know. And I'll look, and it says, you're so funny, and I can't help but think to myself, yes, I am. And so I just want to give a little context in case I make a joke that is not funny. I've had way too much encouragement from random strangers on the internet. But what I really want to talk about is complexity and web development. So I've been building web apps since 96. I had kind of my first form, mailer, and pearl back then. And I've sort of noticed a pattern, and I think a lot of us in the web development community see this pattern, where we start out with sort of a simple stack, and then new technologies come along, new techniques, and we want to add that into our stack. And so we keep adding and adding, and the complexity goes up and up and up. And we're able to build better things, but at the same time, things start getting more complicated. And so I think it kind of takes, someone has to sort of stop, and it's kind of like packing a suitcase. You have to kind of stop, and at some point you're like, crap, there's too much going on here. You dump the whole thing out, and you have to start over. And so at this point in time, I think a lot of people in the web community are sort of starting to do that. We're starting to look at what can we sort of rearrange, what can we do without, how can we simplify things and still build everything we want to build? So this is kind of a story of how, one way, we might be doing that in the future, and how we can start to look at that. I want to do a little bit of history, though. If you've been in web development for a while, you've kind of seen complexity come and go. I think 2004 and shortly thereafter was actually kind of a low point for complexity, which is good. Rails had just came out, and I was doing professional job development at the time. And a lot of the things that we were doing were unorganized, repetitive, you know, there was sort of all this logic that we were writing by hand, and Rails came out and was able to sort of move a lot of that into the framework, and then basically give us a structure that we could easily organize our apps with. And so in 2004, the other thing to keep in mind too, if you weren't doing web development back then, is really all we were doing was producing HTML. And so Rails was able to take the previous 10 years of producing HTML and sort of figure out a good abstraction for that. And then the next year, Gmail had come out in 2004, so 2005, the Ajax buzzword came out, and everyone was really excited, and really all that meant was, hey, let's render some views and send them down to the client without a full HTTP request. And so we started doing that. The next year, we started sort of putting some more JavaScript in, and Rails core team I think was, had the foresight to realize that as time went on, we were gonna be sending more and more data to the client. And so they decided to standardize on REST and JSON, which I think was smart, and kind of gave us that as a way to ship data down to the client directly instead of just rendering views. Then in 2007, we're doing kind of more of the same. Skip to 2009, and we're sending so much JavaScript and CSS and everything to the client that we need some way to meet the best practices. So Rails introduces the asset pipeline, and then it wasn't really until 2011, at least for me, that I started doing full MVC on the client. So I was using Ember, I think about this time, and building really a full MVC app on the client, but still synchronizing data back and forth between the browser and the server with Ajax and REST, or XHR and REST. Then in 2012, we had so many little JavaScript libraries that you're using for frontend stuff that Bower came out, started using that. And then in 2013, kind of humorously, the routers for some of these frontend frameworks didn't really get good until the last couple years. So now we're doing full routing on the client and the server, and basically in 2014, this is the situation. We can kind of look back longingly at 2004, but we want all these features, we want to be able to do all these things. And I think what's interesting is, for those of you who have friends who aren't in the web community, I've got a couple of friends who have been doing mobile and desktop development, and people just now getting into web development, they think this is crazy, and I think the reason they think it's crazy is because it's crazy. And maybe that's just me, I could be totally wrong, but I think we've kind of been a frog in boiling water for a little while, as far as duplication and kind of overall complexity. So sometimes I get up in the morning and this is kind of how I feel. Something that shouldn't be biting me is. So what's the solution? Obviously it's turbo links. I'm just kidding. Sorry if anyone was on the turbo link team. I think the answer is isomorphic app development. And isomorphic is a math term for similar in form, and if you want to get a buzzword popular, you can't go wrong with taking a math term and rebranding it because they sound really cool and no one knows what they mean, at least in the web community. So we're using isomorphic here to mean sharing code between the client and the server. If we look at the complexity, kind of this complexity chart, it's not really hard to see how we can simplify things. We need to stop the duplication, find a way to share this between the client and the server. And then once we do that, we have models on both sides. So now we can take our models and instead of using REST and JSON and manually writing all these REST and JSON APIs, we can actually just have the models know how to communicate the data back to the server and then using something like WebSockets, we can also have that automatically update on all the clients. So I'm gonna call this autosync. I'll talk more about that in a minute. And then ideally, you know, we'd like to unify our package management or our asset packaging. So again, isomorphic is sharing code between the client and the server. For those of you who haven't heard of Volt, Volt is an isomorphic web framework for Ruby. And you're probably thinking, you know, how can you write an isomorphic framework in Ruby? JavaScript is the language of the browser. We're actually using a project called Opal, which takes Ruby code, you can write normal Ruby code and compile it to JavaScript. And if you haven't used Opal, it's pretty great. I'm gonna talk about it more in just a second. So Volt lets you, through Opal, share controllers, models, views and routes between the client and the server. So you can have the same code run on the client and the server. I just wanna kind of drive that home. I'm really excited about this, so I just put some exclamation points on there. Volt gives you a bunch of things you'd normally get in a front-end framework. So we give you reactive bindings for the DOM that know how to update whenever your models change. So you write a declarative DOM with Ruby in the bindings and things automatically update. We give you automatic data syncing. So if I have a model on my client and I change that model, it's going to sync back to the database and then also based on some rules that you can set up, sync to all the other clients. So if you have a shared text field or something, it's gonna go out to all the clients and everyone can kind of type in it at the same time. And as a developer with Volt, you actually don't have to do any work to make that happen. Volt kind of handles all that for you. And then kind of the last, I think, interesting thing that Volt gives you is you build your apps as nested components. So one of the patterns I've noticed with web development is that we tend to start building something and then you'll think, okay, I'm gonna pull this out at a later point and stick it in a jam and I'll reuse it. But the problem is it's almost too late by the time you get around to doing that. You've already kind of coupled it into the app. So in Volt, we try to make it where all of the parts of your app are built in kind of these siloed components, we call them. And then you declare the dependencies between them and then you can easily say, okay, I need this part and all of its dependencies. And there's one command to kind of stick them in a jam and reuse them. So let me talk a little bit about Opal again, the Ruby to JavaScript compiler. There's kind of this perception that compiling to JavaScript is gonna add a lot of complexity. And I think in our heads, this is kind of the complexity picture that we see there. We think on the left, here's JavaScript. I've got kind of the base language and then I've got JavaScript was basically built in 10 days and then that 10 day version was standardized and not a lot of the semantics have actually changed. So you have problems with this and type coercion and there's no standard library. There's the whole category of WTFs in JavaScript which I'm not saying Ruby is perfect but there's far more in JavaScript and if you've built any large JavaScript apps or used it for five minutes, you'll know that these things will bite you and it is really hard to build large apps in JavaScript, I think, and then you've got problems with false units and things like that. And people kind of see it though, they see on the other side, okay, well compiling to JavaScript, I'm gonna have all this debugging complexity, I'm gonna have large file sizes, the performance isn't gonna be good and bridging to JavaScript is gonna be hard. And I think if this was how the picture actually looked, I don't think it would make sense to compile JavaScript. But what I'd like to show is that it actually looks more like this. I will concede there is additional debugging complexity but I think I can show it's pretty minimal and the other issues are basically not issues so we can kind of walk through some of that. Talking a little bit more about JavaScript, this is a slide from Douglas Crockford, Douglas Crockford presentation. Crockford is kind of one of the big names in the JavaScript community. He wrote the Good Parts book and here he says, I stopped using new years ago, I stopped using Object Create, I stopped using this, I stopped using null, I stopped using falseness. And part of me wonders, one, what does his code look like at this point? And then two, if there's so many fundamentally broken things about this language, why are we using it? And I've written JavaScript for years and I do like it. One of the reasons is that it's always a good idea to demonstrate to your coworkers that you're capable of withstanding a tremendous amount of pain. That's a joke obviously. And Ernie Miller I think kind of got, kind of hit the nail on the head with some of this. I used JavaScript for years and kind of sung its praises for a while and eventually I kind of thought, yeah, maybe there is a better way to do this. What's interesting though is with JavaScript, people kind of expect JavaScript to work and in a lot of ways it doesn't and with compiling to JavaScript we actually have the opposite problem where people expect compiling not to work and it does. So here's a quote from someone I saw online. They said, experimenting with Opal, every time I expected to find an issue, nothing happened, maybe it'll be time to retire CoffeeScript soon. So I think this is interesting. It speaks to that perception where we're sort of used to dealing with JavaScript's warts by hand. And so I think as developers we think, okay, well if I'm compiling to JavaScript I'm gonna have all the problems of JavaScript warts and then the complexity of the compilation. But what compiling is actually great at is hiding some of that complexity in the compiler. If I'm a C developer, I don't have to know which registers, which instructions work on which registers. That complexity is in the compiler and only in the rarest case of performance optimization or something like that, do I actually need to dig down into that? Talking real quickly about file size is another concern. This is, sorry, this is uncompressed minified and minified deflate file sizes for different libraries. Here's min deflate, because that's really kind of what we care about. Opal and Volt, so this is everything Volt gives you and a small Opal runtime library sits between Ember and Angular. And we're basically feature parity with both libraries plus a full data-syncing layer which Ember doesn't ship with and a full router which Angular doesn't ship with. And I can honestly say I've done no work whatsoever to try and reduce the sizes. It's just kind of, you know, Opal doesn't actually add a lot of overhead as far as file size goes. The other big concern is debugging. I wanna talk a little bit about why debugging in Opal is actually nice. One of the reasons is Opal is not, there have been other projects to compile JavaScript where they will compile to a bytecode and then ship a virtual machine. And Opal doesn't do that. Opal does what's called transpiling which means it tries to map concepts in Ruby down to concepts in JavaScript. And Ruby and JavaScript are close enough that this is very doable. So local variables in Opal map to local variables in JavaScript, instance variables map to object properties, methods map to object properties with a dollar sign prefix and classes map to prototypes with a couple of extra things to help with super and things like that. So for transpiling, here's some sample Ruby code. And then I just kinda wanna show what the class body looks like when it gets transpiled. There's a little extra things, but this is kind of a quick breakdown of it. Hopefully you can see this. Here, def actually gets set to the classes prototype. So this is the generated Ruby code, or sorry, generated JavaScript code. So here it's assigning instance variables. Here is the initialized method, which I think is pretty straightforward. The only weird thing is the scope.get is constant lookup in Opal. And then the dollar sign minus is the subtract method. So it treats it as a method instead of an operator. And then here's string concatenation. So if we look at the Ruby and the JavaScript side by side, I think it's pretty easy to see why there's not a lot of performance hit or extra overload overhead. And then debugging ends up being fairly easy. But this is actually not ideal. We can do better. So Opal has source maps out of the gate. So you can actually go in and when you get a stack trace, you can see your lines. The stack trace lines will actually be in your root, will point to your Ruby code. And then you can jump in the inspector and see the Ruby code and kind of inspect line by line. So that's pretty useful. To make this even better, there's a new feature in several of the browsers called framework black boxing, which lets you take parts of your code and say, this is a framework. So you might say like, this is Vol and Opal. Don't include that code when I'm seeing stack traces or stepping through a debugger. It basically treats that like native code. So you end up with these really nice short stack traces that point to your Ruby. And it's actually really nice. One of the other nice things to help debugging is there's a, you can run IRB in the browser with Opal IRB. And I think the last thing is Opal tests against Ruby spec. So what that gives you is you can kind of know that it's a faithful Ruby implementation. So I run my Volt tests in both Opal and MRI and 99% of the time when I run into an error, it's in both. And then I have all the tools of MRI available to me to fix it. Also talking about performance. There is a little bit of performance hit, but it's not actually too bad. I showed the last one, the JSON, to JSON and Stringify. By the way, these are benchmarks that I threw together quickly. So just a couple of things. But the JSON, to JSON one is actually calling to JSON all the way down through the object. Whereas JSON.Stringify in browsers is actually implemented in the C, C++ coded browser. So that kind of just shows, you know, there's not a ton of overhead here and the JavaScript interpreters are pretty quick for that. And the only thing Opal kind of lacks in is math because of the way it does operators. There is an operator flag, which will inline operators, but if you're doing a lot of math, I would say you probably, you might need to drop down to the JavaScript. And anytime in Opal, you can bridge to JavaScript using Bactics. And again, because locals are the same in instance variables and stuff, it's really easy to sort of access that inline. Okay, so hopefully that was a quick overview of Opal, but hopefully that kind of showed you that the picture actually looks more like this. And that we do get a pretty big win by compiling to JavaScript. The thing that I think is interesting is the community that actually is most open to compiling to JavaScript is the JavaScript community. And I think that's because, you know, they're the ones working with it the most. So it's interesting to see all the two JavaScript languages that are coming out of the JavaScript community. Okay, so let me talk a little bit more about Vault. Sorry, I'm throwing a lot of stuff at you, but Vault gives you, another thing Vault gives you is collections. So we try to abstract this concept of I need to store data somewhere. And so we have all these different collections that store in different places, but have the same interface. So Page is a temporary memory collection, Store is the database slash syncing to other users. Params is the browser's URL parameters, which you can route into the URL with the router. Local stores, local store, cookies are cookies. There's a couple others. And then one of the other things I just have to mention too is that, you know, when you have a normal MVC framework like Rails, the way MVC works, right, is that a request comes in the controller, it goes to the model, grabs the data, brings it back to the controller, puts it in instance variables, and then ships it off to the view. But Vault is really more of a front end framework, so we actually use the MVVM pattern. We still call our controllers controllers because that is used in a couple other different places and the term view model just never sat well with me. So when you see controllers in Vault, that's also the view model. And so on the front end, we have to keep these around, right, because anything can change at any point. So in Vault, we load up the controllers in the view and then it starts at the view and actually any time a binding hits, it's gonna call a method to the controller and the controller can either respond or it can say I don't have that data, but I have a model and the model has the data or responds to the method actually, and then that returns all the way up. And then at any point, if our data changes, the view is gonna call that method again and grab the new data. And we have bindings that intelligently update only the things that kind of changed. So let me do the dreaded live coding demo real quick because I think that's a good way to get a feel for this. I'm just gonna do this real quick and then I'll jump back. Okay, so just curious, how many of you have seen Vault before? Okay, that's actually not too bad. Okay, so I've already, this is basically a blank project out of the box and I'm in the main component and I'm just gonna do a simple to-do zap and on the side here I have the app showing. So Vault does automatic code push, so any time I save, things automatically reload. I can go ahead and for to-do, I'm gonna go ahead and make a form and I'm not gonna go through all the details, I just kinda wanna show you what it's like to work in Vault. So I'm gonna add an add to-do method that gets called when the form submits and then I'm gonna go ahead and make an input, make a field and I'm gonna bind that, I'm gonna go ahead and bind that to our page collection to a new to-do object on the page collection and then to label. Can everybody still see that? Okay. So over here we've got that field and then when add to-do gets called, I'm gonna define that on the controller and I'm gonna say, I'm gonna set up the model for the model or for the controller to the to-be page and I'm gonna say okay, when add to-dos gets called, I'm gonna append that new to-do object to to-dos and then I'm gonna go ahead and clear out new to-do and so we're gonna just make a table real quick show the to-dos and then we're gonna bind to our label and then over here now we can say one, two, three and everything updates and we had very minimal code. So it's not really a to-do list though until you have a checkbox. So I'm gonna go ahead and make a checkbox. I'm gonna bind the checked attribute to the complete value on the to-do and then what I'm gonna do is go ahead and make the class for the label change based on whether or not it's complete. So I'm gonna say if the to-do is complete, show the complete class and then I'm gonna go ahead and grab some CSS and just drop that in. Volt by default automatically loads all your CSS for you so you don't have to handle that and now if you can see that, let's see, now just through the bindings I have the checkboxes automatically working. This is not anything super new other than the fact that it's in Ruby. So what I think, actually let me do one more thing we'll make a delete button and then so what I actually think is interesting is that at the moment our controller is storing all this stuff in the page so we can actually switch to store. Page is the temporary memory and then when we reload all of this gets backed in the database but what's also interesting is if I open up a new browser over here, everything is synced to any other clients that have this open and I didn't have to write any code to do that. It's the same API no matter whether I want to store in the page or in the params or anything like that. So I think that's pretty cool. Let's go ahead and do one other thing. Let's go ahead and make so that you can select a to-do, this will show a couple of things. I'm gonna say whenever they click on the TR I'm gonna set the index on params to be the current index and then I'm gonna say okay if, actually let me go to my controller, I'm gonna make a current index method that just returns the index from params and then if that's not a sign sets to zero, I'm using the special or syntax and then converts it to an integer. So then over here I can say okay if the current index equals the index, show the selected class and now we have where we can select and you can see if you can see it the URL index is actually updating as we change this and we could actually go and do the other way we could hit it and then change the URL and it goes the other way if that makes sense. So the last thing we're gonna wanna do is show our current to-do. So we'll make a current to-do method, we'll take our to-dos and look up the one at the current index and then in here we could go ahead and, sorry, we can say if there is a current to-do let's go ahead and show its title and then we'll go ahead and do a text area and just bind that to some new attribute so we'll say like description and so now what we get is we can flick through these and it loads up the current one and then we've got this description that kind of sticks around with it. So that was a quick demo, hopefully that was interesting for you guys. Couple more things that Vault gives you. Again I mentioned components so it's an easy way to kind of bundle up client side, server side code and all that and then you can provide those what we call tags. So let me actually show one other thing real quick. So with one other thing you might wanna do here is actually validate the to-do field so I kinda wish that you couldn't do an empty to-do for example. So what we can do is we can actually create a model so we can say bundle X, Vault, generate model to-do and then that's gonna go ahead and create a to-do on our model. We can say validate, label, make sure the length is at least five and then in our controller here we're gonna go ahead and create a new method so when we're working with validations we use what's called a buffer because everything is synced automatically by default but a buffer kinda gives us something that we can work with and then save back to the main model when it's ready. So I'm gonna say page.new to-do equals to-do's.buffer and then this index gets hit whenever this part of the page loads. So we're gonna call that and then we're gonna change how we save because now we're working with a buffer instead we're gonna call save and then if that passes we're gonna call new and then the last thing we need to do is pull in a component, this one's called VaultFields and this is for actually displaying like the field validations. So here we'll go ahead and bundle and restart and then in our view, the one thing I'm gonna change is instead of using this I'm actually just gonna use the tag that it provides. So tags look like this, I'm gonna say the label is to-do. Yep, hang on. And then what we get now is validations that basically automatically there's sort of real-time validations so we didn't have to do anything it just, we set that up on the model and then now it won't save until it actually passes the validations. Okay, so I kinda wanna show that. So that shows components. We have a bunch of components already, obviously I'd like to see the ecosystem on this grow but we have field error messages, pagination, file upload, Google Maps, login sign-up templates, all that stuff. The other thing that Vault gives you is we call them tasks, this name may change we'll see but tasks are basically a way to call server side code from the client in sort of an RPC fashion where you get back a promise that either returns the error, resolves the error or returns the return value. We also have validation and permissions to kind of say who can do what, who can change what, who can access what. And then just a recap, hopefully this kind of showed how we're sort of trying to rethink how we build web apps to kind of fit everything back in the suitcase a little neater. We're able to kind of simplify things by not using REST APIs for our internal things, at least for me as a web developer. I've spent the last five or 10 years building way too many REST APIs just solely so my front end could consume it. Seems like we can get rid of that whole thing. You also get the benefit of writing in one language. We're trying to sort of do some new stuff with components and then I think the other big benefit that Vault gives you is the centralized state. So it's really nice to have all of the state in your app sort of in one place so that I can serialize that to anywhere I want and then bring it back up on another browser or at a later time and everything is sort of in one place. And then I didn't have time to get into it but we also have this unified router that lets you, you know, share the routes between the client and the server. So again, thinking about this, you know, what we're trying to do is basically make things simpler again but without losing all the power. So all the capabilities that you were able to do before. So we have a long way. Vault's still a major work in progress but if you're interested in getting started with it, we have some video tutorials. We also have fairly complete docs although, you know, obviously docs always need improvement but I think ours are pretty good. And then I'm always around on Gitter Chat. If you've seen that, you can go to vaultframework.com and there's a link to it. And then just a little bit about the status of it. I originally was planning to announce Vault here but Matt's tweeted about it. I actually have no idea how he found it because I hadn't promoted it at all. It was just a GitHub repo. So maybe he spends all of his time looking at GitHub refos, I don't know. So when this happened, we actually got about 50,000 hits to the GitHub page. So somebody's seen it, I don't know. I mean, not everyone here obviously but then there's a lot of excitement about it. So some of the things we're hoping to do soon, we want to add more data stores. Currently, Mongo is the only one and there's kind of a weird reason for that and that's that Vault has to implement, re-implement a query parser and it's really easy to do in Mongo. But we're planning to add RethinkDBs on the list. Long-term, we'd like to get, you know, Postgres and some of those other ones. We want to do Rails integration. Well, I don't but a lot of people do. I'm not bashing Rails. I do like Rails but a lot of people want to use it with legacy apps. So we'd like to get some sort of integration where you could write part of your app in Vault, part of your Rails app in Vault. And then probably in the next month, we'll release, we have sort of working and it will be working server-side rendering of HTML so that when the page first loads, it loads up the initial state, renders that all to HTML, sends that to the browser and then as soon as the opal JavaScript is loaded, it ties the bindings in. So that's great for SEO. It's great for initial load time and things like that. And then long-term, we'd like to do Ruby motion integration. So ideally, you know, as developers, we also build a lot of mobile apps and so it'd be really great if we could share code to our mobile apps as well. And I think we can, you obviously won't be sharing views but I do think you could be sharing models and controllers to a Ruby motion app. So that's a ways off, but I thought I'd mention it. Also, if anyone likes what they see and is interested and works for a company, feel free to bug your company to sponsor us. We have a couple of people I'd love to bring on board in a more full-time capacity, so feel free to do that. And then I want to say thanks for all of the people who have contributed and who have helped us get this far. You can check it out at VaultFramework.com and does anybody have any questions? All right, thanks you guys.