Opal

Isomorphic App Development with Ruby and Volt

Isomorphic App Development with Ruby and Volt

by Ryan Stout

In this presentation titled "Isomorphic App Development with Ruby and Volt," Ryan Stout discusses the challenges of complexity in web development and introduces isomorphic app development as a solution. Stout begins by examining the evolution of web development from the early days of HTML and the introduction of frameworks like Rails, which aimed to simplify coding by organizing application logic. However, as technologies evolved, the complexity of applications increased, leading to a scenario where developers often duplicate logic between the server and the client side.

The key points discussed in the talk include:
- Understanding Complexity: Stout highlights how developers often add layers of technology, which can result in overwhelming complexity akin to overpacking a suitcase. He advocates for finding ways to simplify and streamline the development process.
- Isomorphic Development: The concept of isomorphic development is presented, where code can be shared seamlessly between the client and server, reducing duplication and complexity. Stout explains that this leads to better communication between the frontend and backend of applications.
- Introduction of Volt: Stout showcases Volt, an isomorphic web framework for Ruby that leverages the Opal project, allowing developers to write Ruby code that compiles to JavaScript. This enables them to share controllers, models, views, and routes seamlessly across the client and server.
- Automatic Data Synchronization: A significant advantage of Volt is its automatic data syncing capability, which allows models to reflect changes in real time, enhancing user interaction and app functionality.
- Component-Based Architecture: Volt encourages the development of applications as nested components, which aids in code organization and promotes a clean separation of concerns within the app design.
- Real-Time Collaboration Features: Stout describes how Volt allows multiple clients to synchronize changes in real time, improving collaborative functionalities in web applications.
- Live Coding Demonstration: The latter part of the talk includes a live coding example where Stout demonstrates the ease of creating a to-do app with Volt, showcasing features like automatic UI updates, validations, and seamless data management.
- Future Enhancements: Stout concludes by mentioning future developments for Volt, such as improved Rails integration, server-side rendering, and support for RubyMotion to facilitate mobile development.

Overall, Stout emphasizes how Volt can help reduce the complexity associated with building web applications and improve productivity by focusing on clarity and sharing code across different environments. He invites developers to explore Volt's documentation and resources to get started, expressing his enthusiasm for its potential growth and features that aim to bridge the gap between client and server-side development.

00:00:18.680 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.
00:00:25.519 If you Google my name, you will find nothing about me because there is a comedian who has my name. This is actually good for me because I happen to have the handle 'ran Stout' on Twitter.
00:00:31.039 So at least twice a day, I look down at my phone and see a tweet from someone I don't know telling me I'm hilarious. I can't help but think to myself, 'Yes, I am.'
00:00:43.559 I just wanted to provide a little context in case I make a joke that falls flat. I've had way too much encouragement from random strangers on the Internet.
00:00:58.239 What I really want to talk about today is complexity in web development. I've been building web apps since 1996, starting with my first form mailer in Perl.
00:01:09.400 I've noticed a pattern, and I think many of us in the web development community see this as well. We start with a simple stack, and as new technologies and techniques emerge, we keep adding to our stack.
00:01:20.960 Although this allows us to build better things, it also increases complexity. Things start getting more complicated, and it takes someone to stop and evaluate the situation.
00:01:35.880 It's kind of like packing a suitcase; at some point, you realize there’s too much going on, and you have to dump it all out and start over. Many people in the web community are now looking at ways to simplify things.
00:01:47.600 This talk is about one approach to achieving that. Before I dive deeper, I want to touch on some history. If you’ve been in web development for a while, you’ve likely seen complexity come and go.
00:02:04.479 Around 2004 and shortly thereafter was kind of a low point for complexity. Rails had just come out, and at that time, I was doing professional Java development. Many of the things we were doing were disorganized and repetitive.
00:02:39.959 Rails was able to move a lot of that logic into the framework, providing a structure to organize our applications. Additionally, before working with Rails, in 2004, we were mainly producing HTML.
00:03:00.480 Rails took the previous ten years of HTML production and figured out a solid abstraction for it. In the subsequent year, Gmail launched, and so did the buzz around AJAX, leading everyone to embrace rendering views without full HTTP requests.
00:03:23.239 As years passed, our JavaScript usage grew, and Rails introduced the Asset Pipeline in response to sending more JavaScript and CSS to the client. By 2009, we were sending so much data that best practices began to evolve.
00:03:52.479 By 2011, I had started employing full MVC on the client-side, using Ember and syncing data between the browser and server with AJAX. The landscape continued to change and by 2012, the JavaScript ecosystem had exploded with various libraries.
00:04:06.319 In 2013, we began experiencing improved routing for front-end frameworks, leading us to a state in 2014 where our applications were more complex than ever, yet we desired many features that seemed unmanageable.
00:04:22.479 People outside of our web community find this complexity astonishing. I believe they find it crazy because it is crazy. We've kind of been in a boiling frog scenario regarding the duplication of logic and overall complexity.
00:04:37.360 At times, I feel overwhelmed by this situation. So, what’s the solution? Obviously, it’s Turbolinks—just kidding! The answer lies in isomorphic app development.
00:05:01.120 Isomorphic is a mathematical term meaning similar in form. To popularize a buzzword, you can’t go wrong with rebranding a math term because they sound cool, and nobody knows what they mean in web development.
00:05:08.640 In our context, isomorphic refers to sharing code between the client and server. If you look at the complexity charts, it’s apparent that we need to eliminate duplication by finding a way to share code effectively.
00:05:25.840 Once we achieve this, we can have models on both sides of the application, allowing them to communicate with each other seamlessly. We could also use technologies like WebSockets to automatically update clients in real time.
00:05:43.920 This concept of autosync is something I want to discuss further. Additionally, we ought to unify our package management and asset packaging strategies, reinforcing the idea that isomorphic code is about sharing between the client and server.
00:06:07.680 For those of you who haven't heard of Volt, it is an isomorphic web framework for Ruby. You might be thinking, 'How can you write an isomorphic framework in Ruby? JavaScript is the language of the browser!'
00:06:24.000 We're leveraging a project called Opal, which allows you to write regular Ruby code and compile it to JavaScript. If you haven't used Opal yet, it's quite excellent.
00:06:39.120 Volt allows you, through Opal, to share your code—controllers, models, views, and routes—between the client and server. This means you can run the same code on both ends.
00:06:53.760 I'm genuinely excited about this possibility, and trying to emphasize this point. Volt provides many benefits similar to those found in front-end frameworks, including reactive bindings.
00:07:09.440 It has DOM bindings that know to update automatically whenever your models change, allowing you to write declarative DOM manipulations in Ruby. Additionally, it features automatic data syncing.
00:07:29.040 If I modify a model on my client side, that change will sync back to the database. Based on certain rules you can establish, it will also sync to all other clients, enabling shared functionality.
00:07:47.200 For instance, if you have a shared text field, others can type into it simultaneously. As a developer using Volt, you don't need to do much work to make this happen; Volt handles it internally.
00:08:05.720 Another interesting aspect of Volt is that you can build your applications as nested components. A pattern I've seen in web development is that we start building something and plan to extract it into a gem later.
00:08:20.040 However, by the time we get to that point, it’s often too late, as it becomes too integrated into the app. Volt encourages building your app's parts as siloed components.
00:08:39.520 You can declare dependencies between these components, making it easy to package them into a gem whenever necessary. Now, let’s return to Opal, which is the Ruby to JavaScript compiler.
00:08:53.440 There is a common perception that compiling to JavaScript complicates things, leading to a belief that it adds significant complexity. In our minds, we picture a lengthy path from raw JavaScript to compiled output.
00:09:07.640 On one side, we see the base JavaScript language with its inconsistencies and issues. However, if we truly evaluate the situation, compiling to JavaScript offers major advantages.
00:09:26.320 I can concede that additional debugging complexity exists when using Opal, but it’s minimal. Other concerns regarding performance and bridging to JavaScript can be largely mitigated.
00:09:41.200 Douglas Crockford is a significant name in the JavaScript community, and in one of his presentations, he mentions halting the use of certain JavaScript functionalities, highlighting its many broken aspects.
00:09:54.560 Having written ample JavaScript over the years, I believe the reasons people persist with it sometimes relate to enduring various pains. There's also a belief that, given our experiences with JavaScript, using Opal should come with inherent problems.
00:10:13.920 However, what compiling to JavaScript excels at is concealing some of that complexity. With C development, you don't need to know the intricate details of registers; the compiler does that work.
00:10:30.720 Similar principles apply to how Opal operates—we're able to focus on Ruby while it handles the translation to JavaScript. Now, let's quickly discuss file size concerns, which are always relevant.
00:10:43.360 I'll share some uncompressed and minified file size comparisons across various libraries, including Opal and Volt. Opal, along with Volt, isn't adding too much overhead when it comes to file sizes.
00:10:56.160 In fact, Volt offers a full data syncing layer, which would equate to certain advantages over other frameworks like Ember and Angular. I can assure you I haven’t done any work to minimize file size.
00:11:09.120 Debugging in Opal is also quite pleasant. Unlike other Ruby to JavaScript compilations that use bytecode and virtual machines, Opal transpiles Ruby to JavaScript.
00:11:26.640 Ruby and JavaScript are similar enough for this to be practical—local variables in Opal map directly to local variables in JavaScript, and instance variables become object properties.
00:11:40.800 Methods in Opal match up with object properties prefixed with a dollar sign, giving you easy-to-trace behavior. Additionally, Opal's generator provides source maps, making debugging straight-forward.
00:11:57.000 Thus, when you encounter an error, you can directly reference your Ruby code for clarity. Recent features in browsers allow for framework black-boxing, which treats Volt and Opal's code as native, simplifying debugging further.
00:12:09.760 You can even engage with IRB in the browser through Opal for immediate feedback. Opal is rigorously aligned with Ruby specs, so testing in both environments yields consistent results.
00:12:20.960 As for performance, while there may be slight hits, they aren't substantial, especially considering robustness in JavaScript testing and performance are generally quite satisfactory.
00:12:35.360 If you're engaging in extensive calculations, it may be preferable to drop to JavaScript for efficiency. Thankfully, anytime during Opal, you can bridge back to JavaScript seamlessly.
00:12:55.760 Hopefully, that was a brief yet comprehensive overview of Opal's advantages. It becomes clear that compiling to JavaScript isn’t just feasible but beneficial.
00:13:07.680 Interestingly, the JavaScript community appears most open to compiling, likely due to their hands-on experience. This makes it exciting to see how these new JavaScript languages are evolving.
00:13:20.160 Returning to Volt, it introduces a concept of collections, which help abstract how we store data. There are various collections designed for different storage locations but with a similar interface.
00:13:30.400 For example, 'page' is used for temporary memory, while 'store' is for databases, and 'pams' deals with browser URL parameters. This categorization allows for streamlined data handling.
00:13:48.640 In contrast to traditional MVC frameworks like Rails, which process requests on the server side, Volt primarily operates as a front-end solution, utilizing an MVVM pattern.
00:14:05.520 We still refer to our components as controllers, even though they essentially serve as our view model. When you engage bindings in Volt, it’ll automatically signal methods in the controller.
00:14:17.680 If the controller doesn't have certain data, it can then respond with the model that does hold that data. This creates an efficient method of maintaining accurate data in the interface.
00:14:25.920 In showcasing this feature, I want to do a quick live coding demonstration. Immediately, I’ll create a simple to-do app to illustrate how to utilize Volt effectively.
00:14:38.560 As you see, Volt implements an automatic code push feature that reloads changes instantly upon saving, streamlining development further.
00:14:53.120 For the to-do items, I'm going to create a form that will register the input, bind it to our collection, and establish a proper interaction channel within Volt.
00:15:04.480 The input field will link with a new to-do object in the page collection. By leveraging binding, it allows accurate retrieval and processing of input seamlessly.
00:15:18.240 Once the add function is called, the controller updates the model accordingly. Additionally, I'm implementing a table to display the to-dos dynamically.
00:15:29.440 I aim to make everything work fluently, catering to changes in labels and bound values so that users experience a seamless interface.
00:15:44.480 Moreover, introducing an interactive checkbox to each to-do allows toggling completion status, which enhances user engagement significantly.
00:15:58.720 Consequently, the application becomes richer in functionality, with the ability to reflect completed tasks through visual cues in the UI.
00:16:15.600 I then created a mechanism for the to-do delete function, enabling users to manage their tasks more effectively. As the controller stores these elements within the page, transitions between states are smoother.
00:16:29.840 With the added ability to synchronize multiple clients in real time, whenever a change happens on one client, it automatically updates others—it’s incredibly efficient.
00:16:44.480 The user experience remains intact regardless of whether you operate with the 'page' collection or a 'store' in your app. Thus, we see tremendous synergy in using Volt.
00:17:00.480 Next, I want to implement an index selection within the to-do list. This process will allow users to click and interact with index values effectively while navigating through their tasks.
00:17:14.560 By managing current selections through an integer index, users will find navigating their to-dos more intuitive and cohesive with the app’s capabilities.
00:17:31.120 Once that’s done, we’ll implement a method to extract the selected to-do details and display its attributes, enriching user interaction with streamlined access.
00:17:44.160 Now, I’ll add outputs for titles and descriptions within the interface while ensuring data consistency using the designated control paths.
00:17:58.080 This quick demo emphasizes how easily users can work within a modern Ruby framework like Volt, offering a replicable balancing act between simplicity and functionality.
00:18:12.720 I want to highlight again that Volt provides ways to build components, simplifying bundle packaging for both client-side and server-side implementation while maintaining code clarity.
00:18:23.920 Validations can easily be integrated into your application logic as it processes actions, ensuring prompts that offer users more guidance in interaction.
00:18:35.360 Users can set validations effortlessly to enhance their applications, which demonstrates how efficiently components can be set up within the Volt ecosystem.
00:18:48.880 There are numerous components available, including field validations, pagination, file uploads, and authentication templates. Volt’s continuously growing ecosystem is pivotal to its potential.
00:19:06.960 Additionally, Volt handles tasks—that is, executing side-server code requests from the client, effectively using promise styles to manage responses and permissions.
00:19:25.760 In summary, we've seen how we can rethink how we build web apps, focusing on clarity and organization while eliminating the need for excessive REST APIs for internal structures.
00:19:43.600 For me, as a web developer, I've found that I've spent the last few years overbuilding REST APIs just for the front-end to consume. We need to eliminate that redundancy.
00:20:03.200 A unified approach, condensed into one language, allows us to reduce the complexity while simplifying component and state management within our applications.
00:20:19.520 I didn’t have time to dive into it today, but we also have a unified router that helps you share routing between the client and server, reflecting ambitions to streamline the development process.
00:20:36.560 As we explore these possibilities, we hope to retain all the capabilities you were able to incorporate in previous frameworks while paving new paths for effectiveness.
00:20:50.920 Volt is still a major work in progress. If anyone is interested in getting started with it, we have video tutorials available and documentation for reference and guidance.
00:21:05.680 I’m active in the community, and you can reach out on GitHub for any support. It’s thrilling that the initial buzz about Volt reached such a wide audience, marked by significant interest from fellow developers.
00:21:23.280 We're aiming to expand functionality soon, including adding multiple data stores and better Rails integration for those working with legacy applications.
00:21:36.560 Server-side rendering of HTML is also on the agenda, which will enhance initial load times and SEO. Furthermore, we’re contemplating RubyMotion integration for mobile application compatibility.
00:21:52.960 If anyone finds this exciting and works for a company that might be interested in sponsoring our efforts, please encourage them to consider investing in Volt.
00:22:08.400 Finally, I want to express my gratitude to everyone who contributed to this project and helped us to get where we are today. You can check out more information at voltframework.com.
00:22:24.640 Does anybody have any questions?
00:22:34.560 Thank you!