Code and the Coding Coders who Code it

Episode 57 - Marco Roth

Drew Bragg Season 1 Episode 57

Marco Roth joins us to unveil Herb, his revolutionary toolchain for Rails views that's reshaping how we work with HTML and ERB. Having identified a critical gap in the Rails ecosystem—robust tooling for the view layer—Marco decided to build the solution himself, learning C along the way to create a parser with unparalleled cross-platform compatibility.

Far from just another syntax checker, Herb represents a comprehensive vision for modernizing Rails views. Marco walks us through his layered approach, starting with immediate editor feedback for markup errors and ambitious plans for reactive views inspired by Phoenix LiveView. The most exciting prospect? Allowing developers to write modern, interactive applications without abandoning Ruby for JavaScript frameworks. "I want to bring back some awesome experiences from JavaScript to the Rails ecosystem so we can keep doing Ruby," Marco explains, highlighting how Herb could transform ActionView after two decades of relative stagnation.

We also explore Marco's approach to managing multiple ambitious projects alongside a consulting career, his upcoming conference schedule (including RailsWorld, FrienlyRB, and Euruko), and his work on Ruby Events—a catalog of over 7,000 Ruby talks that serves as an invaluable community resource. Marco shares insights into his development process, the challenges of mapping tag helpers to HTML, and his recent implementation of Tailwind class sorting in the Herb formatter.

Whether you're frustrated with Rails' front-end limitations or simply curious about innovative tools reshaping the Ruby ecosystem, this conversation offers a fascinating glimpse into the future of web development with Rails. Marco's work reminds us that with the right tooling, we can build modern, reactive applications while maintaining the developer happiness that drew us to Ruby in the first place.

Send us some love.

Honeybadger
Honeybadger is an application health monitoring tool built by developers for developers.

Judoscale
Autoscaling that actually works. Take control of your cloud hosting.

Disclaimer: This post contains affiliate links. If you make a purchase, I may receive a commission at no extra cost to you.

Support the show

Speaker 1:

Hello everyone, Welcome to another episode of Code and the Coding Coders who Code it. I'm your host, Drew Bragg, and I'm joined today by the one and only Marco Roth. Marco, for anyone who somehow is not familiar with your work, would you please do a brief introduction?

Speaker 2:

Yeah, my name is Marco. I have been doing Rails for the past decade or so and over the last few years I've been focusing a lot on open source and now conference talks, and I've been mostly dabbling in the Hotwire and JavaScript ecosystems and have it be more to what I like to write myself. So I don't have to go into the deep rabbit holes of SPAs and React and all of these kind of stacks. But that's what I want to do. I want to just bring back some of these awesome experiences that we have in JavaScript back to the Rails and Ruby ecosystems so we can keep doing Ruby and Rails for the time being.

Speaker 1:

Awesome. So the way this episode is going to work for anyone new to the show is I'm going to ask Marco three questions. I'm going to ask him what he's working on, what kind of blockers he has. If he doesn't have a current blocker, he can talk about a recent one he had, the steps he took to solve it, etc. And then, to wrap up the show, we'll ask him what's something cool, new or interesting that he's recently learned or discovered or built. It doesn't have to be coding-related, but this is Code Encoder, so it totally can be. So, margo, you are a busy man with a lot of things going on, but when someone asks you what you're working on, how do you answer it?

Speaker 2:

Yeah, it's been interesting to kind of hop back and forth between all these projects and it's been super fun, also a lot of learning doing all of these projects.

Speaker 2:

But most recently I have been focusing on a new project that I call Herb. It's on purpose of an H in the beginning to the, I guess, american audience, just to kind of avoid the confusion between ERB and Herb. That's the whole project. So that project is tooling for HTML and ERB files and the H from HTML, the ERB from ERB, so that's Herb, and the H from HTML, the ERB from ERB, so that's Herb. And it's an ecosystem of tools that tries to help you build better HTML ERB files kind of have more tooling, make your day easier to work with these files. We have been seeing a lot of awesome tooling in the Ruby ecosystem, especially lately with Ruby LSP, but we haven't really seen anything major or if tooling at all for the view layer in Rails especially. That's kind of what I want to tackle. I want to kind of focus on improving that, making it easy to work with and have a great experience inspired by the JavaScript ecosystem mostly and bringing back some of that experience to Rails.

Speaker 1:

And you're talking about it like it's a pipe dream, but I have the VS Code extension installed and I'm running it at work and it's awesome. It already does a lot of very helpful things making sure the HTML markup is good. It's like blurting me if I don't close a tag properly or if I messed something up, and I know you gave a really awesome talk at RailsConf. If anybody hasn't seen the video yet, you should definitely check it out, but it already feels like it's an incredibly useful tool. I don't think it's going to be a useful tool. I think it already is. It's one of those tools that, as I'm using it, I'm like how did we not have this before? What made you I don't want to say come up with the idea, because the idea is like I feel like we all at some point was like man, I wish my editor would just yell at me if I don't close a tag or if I screw something up in my ERB or whatever. But you actually made it happen. What was the thing that made it happen for you?

Speaker 2:

Yeah, I mean I've been mostly using HTML ERB for most of the applications I've worked on throughout the years and I kind of acknowledged the fact that there is no tooling and I just kind of worked around it and now I'm really good at formatting the files by myself. But I was like, yeah, why don't we have a tool for this? There hasn't really been anything that's really solved it once and forever. I feel like there have been tools, there have been projects to kind of tackle this, but most of them didn't really have this easy to set up feel or easy to kind of make it work for you use case and for your application. There was always some hassle to make it work and I just wanted to kind of make it work for myself. Just for that I have the tooling that I wanted to have for working with these files. That's kind of one of the part of the motivation. The other part was that I have been working on dev tooling for the past few years too. Most of the stuff was in the Hotwire ecosystem as well. So I've been working on stimulus LSP and triple LSP and I've been wanting to make a stimulus lint plugin for the longest time too. But when I was working on those. I wanted to make them work for ERB as well. Right now, still to this day, they don't work with ERB. They only work with HTML. So you can have HTML in your ERB files and it works in those. You can have HTML in your ERB files and it works in those. But as soon as you go and reference tag helpers or write Ruby to output HTML, the extension doesn't work anymore. So I was working on those.

Speaker 2:

I had some other projects where I was like it would be cool to have an ERB parser to just make it work and make it easy to work with. So I had kind of that part of the inspiration there and I was like, yeah, let's just tackle this from the ground up. And it's obviously not something I have been doing a lot. I have been dabbling with compiles and parsers in the past, but I haven't really had a big project to just work on it that way. So it was in a way also kind of a way of learning new technology, new tools, new languages, program languages, but also just having like a side project to hack on. I guess at this point it's more than a side project, but still it's kind of a side project besides my regular day work, so it's cool to have something to work on. So the parcel itself is written in C and I haven't done any C before the project, so it was a cool way to learn C.

Speaker 1:

Cool isa. Certainly a choice word for working with C. Yeah, the thing is, I was scared to touch C.

Speaker 2:

From what I heard, it's one of the worst languages to work with. It's super hard to learn, super hard to manage, but I found that now working with it a little bit, that it's not actually that bad. I think it gets a bad rap for what it is, even though it actually is not that bad. If you kind of sit down and look for what you need and how it works and then it is such a simple language it doesn't change at all. It has been the same for the last decades at this point. So it just is super easy to learn and super easy to pick up in that sense because it is just a super simple language you can do things with and in my case I was looking at C because it is A fast if you kind of want to write a parser. But that wasn't the main motivation. The main motivation was more that it's more compatible with other tools and also portable. So if you have been looking around in Ruby ecosystem, we also got this new Prism parser for Ruby, which is also written in C and it has also a C API and it has a bunch of backends to make it work for JavaScript. It makes it work for Java. It makes it work for Rust. It's all because it's super simple in C. Not simple, but it's the most low-level language you can think of, which isn't a high-level language but it's still portable, so you can use it from all these other languages.

Speaker 2:

So I was looking to write this parser in Ruby first, because that's what we know and do every day. But then I realized all these other tools I work with are written in JavaScript or in the web or are somewhere else. So I don't really have a way of using the parser if it's written in Ruby. But if I go down a level and say I write in C, I can write Ruby bindings, use it from Ruby. I can write JavaScript bindings, use it from Nodejs.

Speaker 2:

And now we can also use Web Assembly to compile to Web Assembly and then use it from prettyjs. And now we can also use WebAssembly to compile to WebAssembly and then use it from pretty much anywhere. And thanks to C, now I can use it in the browser, I can use it in JavaScript, I can use it in Nodejs, I can use it in Ruby and it just works in that sense. So that was the main motivation and as a side effect, it is fast as well, which makes it ideal to build dev tooling to build editor integrations and have it pretty much run on every keystroke even though it doesn't have to, but it can run on every keystroke and it's fast enough to give you fast and valuable feedback in the editor.

Speaker 1:

Yeah, I was going to ask about the language choice because when you pull up the Herb repo, it's not a single language. I mean, most of it is actually TypeScript. But you have TypeScript, you have C, you have Ruby, c++, regular old run-of-the-mill JavaScript, like there's a lot going on. You're what is it called polygot when you write in multiple languages? Like I can write JavaScript because I have to, but if I had to build a tool in JavaScript, that's out of my normal wheelhouse. So you already do JavaScript and TypeScript in addition to Ruby and you do it expertly well, and you just decided I'm going to add C into my stack. And where's the C++ coming from? It's not a huge amount, but it's there.

Speaker 2:

Yeah, the C++ is for the Nodejs bindings, so we have native Nodejs bindings. Nodejs is written in C++, I think mostly. So you need some glue code to make that work for Nodejs extension but also for the WebAssembly integration.

Speaker 1:

So in your RailsConf talk which was fantastic and you got Andrew Mason all pumped about it too. He came back from RailsConf and the first thing he did was like we're running Herb on Podia's code base and seeing where it breaks and all this stuff. He was pumped, leaving your talk. And then I got to watch the recording and I also was very pumped. It was like installed the VS Code extension. It was like this is awesome. It is a little simple right now but it still is.

Speaker 1:

Like I mentioned filling these gaps already, like it's already yelling at me for maybe it's code that I didn't write, that someone just like didn't close a div or like the formatting is just weird and it will highlight problems, which is so nice. It's so nice to have that kind of almost like expected tooling. But in your talk you laid out a pretty awesome vision for what this tool can do and you said there's things that you're definitely going to do, like making the formatter and linter work and then make it configurable, which I'm sure everybody appreciates Bike shedding on how we format things. Again, we're going to need a standard Herb at some point. But one of the most exciting things was the ReactiveView stuff. I believe you said it was inspired by Phoenix LiveView. That feels at least from my end, where I do predominantly application development. I've worked on small dev tools but nothing to the size and scope of her. But that seems ambitious to me. How ambitious do you think it realistically is versus? I think that this is going to happen.

Speaker 2:

It is super ambitious and that's kind of what I want to go for.

Speaker 2:

I feel like for the past 20 years in Rails the framework has been around. Actionview hasn't changed that much, maybe for the better, because it's been super stable. You can just rely on it. It just works even five years from now. But the thing is that applications nowadays expect more interactive UIs. It requires more ambitious views as well and also more ambitious tooling. Most of the tools nowadays, if you just install or use a JavaScript framework, it just has the tooling and all the bells and whistles built in. You don't have to do anything and it just has it all there.

Speaker 2:

And that hasn't been really the case for the Ruby and Rails and especially the view layer in Ruby and Rails at all. So it just felt right to go and try to innovate in this space. We have had approaches from like view components and nice partials and like other gems that are trying to make it at least a bit nice to work with. But it still feels like I'm missing something foundational that makes this all work and feel like it is a modern alternative to what we have today. That's why I think we have to go a bit more ambitious, to kind of lay out the vision, to say this is where we could go and it's what we could have if we go and focus on it and kind of build this thing. But also, because it's so ambitious, I wanted to kind of layer it into multiple layers so we don't have to do all at once and just start at the very beginning to make it just nice to work with, then maybe see if we can make it reactive and later we can see if we have more other ideas that we can integrate with this new approach that we have.

Speaker 2:

So one of the first things I want to kind of work on when this is about to come out is the way of how you get feedback from your view files if something goes wrong. Nowadays, if you just have an error in your view file, it might give you a nice error, but most of the times it doesn't. It is quite frustrating to see or to figure out what's wrong with it. So I just want to, now that we have this parser, we can parse these view files ourselves. We know where something goes wrong and something is wrong in the view file, so we can pinpoint the error in your file and say this is actually where you did something wrong and just having that feedback built into Rails. So you kind of reload your file and it just says online 20, character 25. This is where it's like something is wrong about this. And that's kind of the first step, just to make it more actionable and kind of more inspectable to see what is going wrong.

Speaker 2:

And the next step would then be to see if we can make it maybe more efficient to render some of these Vue files, because render calls are somewhat slow if you don't do them the right way. So there's stuff we can do to optimize maybe some of these render calls and maybe how we compile these files, these Vue files, because all the Vue files are getting compiled into actual Ruby code that the app is running. But if we can kind of have some optimizations there, because we have now all this introspection, these Vue files, we can maybe make this more efficient, more performance. That's something to look into. I'm not sure how feasible that is and if it actually makes any sense, but it's something to explore now that you have the tools available to look at this.

Speaker 2:

And then, as I mentioned, the next step would be to see if we can make it work with Reaction View, which is like the reactive views. The idea here is that we go and look into all the variables and methods you are using in your view files and somehow we are keeping track of the state, like you have it in React, for example, where you define the state, you are looking at the state and render it out, and when the state changes, the view itself knows how to update itself and to reflect the changes and then it will render or re-render the changes back to the browser page. So the same thing is kind of what we want to do here, just that we don't do it on the client side but we do it on the server side and maybe have it emit some turbo streams or some other ways of getting these updates back to the browser. But you don't have to kind of worry about what is changing and how it's changing. You're just updating the states and the kind of engine itself knows how to reflect these changes and bring them back to the client, which makes it super like nice to work with.

Speaker 2:

This is, as you mentioned, most inspired by Phoenix Live View and to some degree also from what we have been doing with Stimulus, reflex and Cape already in the past, which is kind of like, was an early port of Phoenix Live into the Rails ecosystem and it kind of died out a bit after, like Hotwire was announced and kind of became big.

Speaker 2:

So there are still some, I think, nice ideas in the seamless reflex that we don't have when it goes on in Hotwire today.

Speaker 2:

But I think now that we have or are thinking about how we can kind of improve the view layer in Rails, that we can bring back some of these ideas, and these reactive views are kind of one part of that.

Speaker 2:

And as a super ambitious last step for what we can do, if you have all of this figured out, which will take a few months from now, is see if we can make it work with existing SPA frameworks so that you can mount React components, you can mount Vue components, that you can mount Svelte components I don't know. Just have it like a super nice way, an easy way to use these existing components that you might have already, be it from your own style guide or from your own design system or from a third-party one like ShadSian or any of those other frameworks, that you can just use or register these components and then use them in your erb files as if they were html and it will figure out how to compile this, how to transpile this, how to make it hydrate the the html what it needs, and just having this experience of writing HTML ERB, as you are used to from today, just having all these modern alternatives and tools right built into the Rails view layer.

Speaker 1:

Can I have that now? Because that sounds awesome, like all of that sounds. I mean, it really is something like you said, like Action View hasn't changed much in the 20 years Rails has been out. It really hasn't. I mean, the biggest change, at least that I can recall, to ActionView was the render in, and that I don't know if you would even consider that necessarily ActionView, since that was kind of like other objects, giving them the ability to render for view components. But yeah, I mean, for the most part, action View just kind of sits there.

Speaker 1:

I think that when people complain about the Rails frontend, I sort of feel like that's what they're talking about. Action View is so basic. If I want to do anything fancy, I'm reaching for Inertia Rails or React on Rails or something else to like bring that JavaScript SPA that, like a lot of us don't want to work on that stuff. I mean, we occasionally have to, which makes what you're saying sound even nicer. It's like, hey, when you have to use a react component or a view component, view JS component, as it were, this would give you the ability to do that. But there's a good chance of not having to reach for some of that, depending on the problem you're trying to solve because the tooling is so much better now, because Action View is better. I mean, you talk about it in your RailsConf, talk about how breaking down the file into this AST and being able to generate HTML back and forth and the Ruby and everything gives you.

Speaker 1:

So it's like this layering effect which I find so interesting. Right, you have this really big problem and you've very effectively taken the smallest step possible to solving this very large problem. But that necessary step, man, I wish we could do all these crazy things and it's like, well, these are crazy things, but you've already built a tool. That's like well, now we kind of see how we can get there, and that's so cool. Is it a mental model? Do you have just a giant whiteboard? How do you go from really big, ambitious problem to, okay, what is the smallest step that I need to take to make this happen? What goes on in your brain?

Speaker 2:

Most of it was from working on Simulus Reflex, so I've been maintaining that library with some friends over the past few years and, working on that, I was already kind of thinking about this. I was wishing to have something like this to make it easier for me to work with and make it work and having this problem there and then also trying to contribute to Turbo and making Turbo Rails kind of a nice thing to work with and then also hitting limits there of what we can do and what is possible, and then kind of feeding back into what we were talking about earlier with the tooling, with the LSPs, with the linters that we don't really have. I was like, yeah, maybe it's just time to go all the way back time to lowest level I can think of and just try to reroll this whole thing from the ground up, and the first thing that you need to have a parser to know what you're working with. And I was like, yeah, this is super ambitious and I don't know how I want to do this. I was talking about this idea in previous talks too, that it would be cool to have this and I have been trying to make it work with some less ambitious hacks to make it work and it works good enough for most cases. But then if you need to have this extra detail or this extra context, it's not able to deliver that. And that's where I was like maybe you have to just do it right for once and do it pretty much all in on that and make it right.

Speaker 2:

And this is also largely inspired by the whole architecture of Prism itself. So it is using Prism under the hood to parse the Ruby code in your view files, but the design is also largely inspired by Prism itself. And yeah, like as I was working on the parser and then also slowly the linter and the formatter, I was like what if we just also look at rendering HTML ERP and kind of try to improve what's possible there? Because we have all these tools now we know exactly what is going on, what you're trying to do, so maybe we have a better foundation now to also improve what's possible with the current view layer. And it was mostly like, yeah, this is too much, this is too ambitious. I don't want to kind of commit to that. But having worked on this and having prototyped a little bit of how this could look like, I was like, yeah, I think that is feasible and viable, at least to make it into a prototype to kind of show this is what's possible.

Speaker 2:

I am not super sold on the whole implementation now that we have to figure out how you store states. How do you persist state between requests? How do you think about browser sessions, browser windows, like, do you share that state? Do you kind of have it isolated? That's like all details that they have to figure out which are super tricky to figure out too. But at least that's more high level than right. It's not to the super low level that you have to think about how you do your parseless file, because that is now a somewhat solved problem. So I think it is quite interesting to go pretty much from doing front-end work in the browser working on Stimulus and Turbo and all of these tools pretty much to the whole opposite side of the spectrum, to go super deep into parsers and doing C work, different challenges and these super tricky things to work on. And it is just super exciting and also fulfilling because I get to solve the problems I have been having for the longest time in Rails myself. So it's fun to work on these problem space.

Speaker 1:

Yeah, and it makes you a really popular guy too, because you're solving the same problems for a lot of us. I don't think those problems are really unique to you, or at least from the people I've talked to. The work you do tends to come up in conversation whenever there's conversation about the front end side of Rails. So I think the work you're doing I'm glad to hear that it's solving your problems, but also thank you for solving mine so you're doing a lot of amazing work. You've kind of set yourself a pretty awesome and ambitious roadmap and, in addition to already having this work done you already mentioned this isn't your day job. This is essentially a side project, but you also have a pretty speaking of ambitious. You have a pretty ambitious speaking schedule. You just spoke at RailsConf. You mentioned speaking at Yoroku during your RailsConf talk. What other conferences are you going to be speaking at in the near future?

Speaker 2:

Yeah, it's been quite the ride to being able to speak at all these conferences and I've been enjoying traveling and speaking at them and sharing my work that I've been working on in these conference talks, because it's also a big motivation for me to get things done. And I guess you could call this talk-driven development, TDD, I don't know or conference-driven development, it is. You have like a deadline and you want to deliver something by that date, so you have to get something done. And it is quite motivating to get something done for a conference and then being able to share it and share it for the first time and have it kind of be exclusive for the conference to say this is now available, this is now released, A thing you can actually install and have in your hands and you didn't know about it before. And it just gives this nice feeling of attending a talk in person and saying, yeah, now you have this thing that you can use in your day-to-day work. And that's been really rewarding in a sense too, to get all the feedback and the excitement from the people that are at these events and that's kind of feeding back into the whole cycle of making this work for myself but also work for the community in general.

Speaker 2:

But to kind of come back to what is up next is I get to speak at Railsworld now too. I got asked to replace Xavier. He cannot make his keynote spots this year, so he was asking if I can step in for him. And I was like I have this talk scheduled for Yoruku, but I don't really have this ready yet. But maybe I can make it work for Railsworld. So we kind of were able to arrange something and now Joe is doing the keynote for him, that's replacing him, but I get to have his spot, Joe's spot in the schedule and I. That's awesome, yeah, it's exciting. Yeah, it's exciting because again, it's the big stage. So I'm looking forward to having that. And then we are doing the Friatland this year too, which is the free conferences, back-to-back in three weeks. So we are doing Railsworld, FriendlyRP in Romania and then Yuruko in Portugal. So in Romania and then Yuruko in Portugal. So we're doing back-to-back conferences and I get to speak at both ResVolt and Yuruko and that's going to be a lot of fun.

Speaker 1:

I guess my next question has to be like how? How do you find time to do all this traveling, all this speaking? This is a side project. This awesome set of tooling that this speaking, this is a side project. This awesome set of tooling that you've already created is a side project In addition to your day job. I feel like I struggle just to manage my day job and occasionally speaking at one or two conferences a quarter. Is there a trick? Do you have a magic potion that slows down time or makes you really good? Do you have just an amazing planner journal that you're just like today I'm going to work on X and then you exit? How do you do it?

Speaker 2:

Yeah, it's a good question and I somehow asked myself somehow how this is all possible and doable, because I was like, yeah, I don't know how this works. I don't know myself. I think it's mostly hype that I have for these tools myself, so it doesn't really feel like I am working on these things. But I was kind of lucky enough to not have to work like a full, full-time job.

Speaker 2:

So I'm doing consulting work for clients, I help clients, do projects with Hotwire, and I have had a lot of clients that are super flexible with me coming and going. So I kind of work in phases where I focus a month or two on doing just client work and then coming back to open source, and that allows me to do both at the same time. So I'm working for like two, three months and then not working for two, three months on a client work at all, and that kind of balances it out in the end. And having that kind of mix also gives me the immediate feedback to bring these tools back to my clients to say I have built this, now Can we see if it works for your case too, or kind of just validate the idea or like the whole project. And that's been super nice to kind of have this feedback cycle as I'm working through for these ideas.

Speaker 1:

Yeah, that's like when you're dogfooding the app that you're working on, like you're going to use the app you're working on, you're building tools and you get to use the tools you're building at your. I don't want to call it a day job because it's like a month job.

Speaker 2:

But yeah, it wouldn't be possible if I wouldn't have these awesome clients that I work with that are so flexible for me coming and going and yeah, otherwise it wouldn't really be possible.

Speaker 1:

Yeah, unless you went to somewhere like Shopify where they're like oh, you're on the team that does nothing but developer tooling for Rails and Ruby, and even then you might not get to work on the thing you want to work on, Right, yeah. So yeah, definitely a cool setup. But, yeah, you get around. Sir, you are all over the place with the talking and the attending conferences, but it is always super cool to see the work that you're doing. One thing that probably doesn't always come out in your talks when you're talking about something that you've built or are hoping to build is what kind of blockers you run into. I think a lot of us I'm assuming listeners feel free to text me and let me know if I'm wrong but I'm assuming most people listening to this do application development, where we get to use your tools, but we're not building tools ourselves. What kind of blockers do you run into when you're building a tool versus building an application, and do you think the problem solving there for blockers is the same or pretty different depending on what world you're in?

Speaker 2:

Yeah, I think it is quite similar, at least from the problem solving, I guess, approach or the steps you go through debugging a problem. One thing that's been really nice working in like library, more abstract level codes is that you have test cases. In my example it has now been parsing and formatting and linking test cases and they are so fast to execute. There's no system tests, no slow tests to kind of wait on and see what you're changing is actually not working the way you expect it to. But with these like low-level tests, you save the file and you can keep them running in the backgrounds and it runs your whole test suite in milliseconds and it's really so impactful to work that in a way it's really productive to iterate and see if stuff is working. If you take the time to define these test cases up front which is something you can really easily do with a parser or a linter to say I expect to have an error here, I expect to have a offense here, or I give the format of this input and expect this exact output, and as long as it's not exactly the same, you know stuff isn't working the way expected to. So it's really kind of nice to have this instant feedback cycle, which you don't really get in application development usually. But I guess one thing I've been kind of struggling to get right in Herb in the last few weeks is parsing the ActionView tag helpers. So in Rails or in ActionView I guess you can say that you have different ways of expressing or writing HTML. You can have the raw HTML in your view files, but if you are interpolating a lot you kind of tend to also use tag to div content tag. You use form helpers, you use input helpers, you use all these different kind of helpers which eventually evaluate back to HTML when they are rendered out. And since the idea of Herb is to give you more feedback about your view files, we want to kind of understand what these tag helpers are going to output in the end. So when you write tag to div we know, at least at static analysis time, that this is going to be a tag with div and it's going to have these attributes. Some of them might be kind of variable dynamics that we cannot really figure out at parse time, but most of the stuff we can actually evaluate and kind of figure out what it's going to render out as. And now that Herb is kind of trying to improve the tooling and kind of give you feedback for also your ERP helpers. We want to understand what these tag helpers mean exactly, so we want to parse these as well and kind of translate them back into HTML. So when you parse a Vue file you as a tooling developer just see the HTML as if it would be written as HTML instead of the ERP that you have in your actual file. So trying to kind of make that work, to parse the Ruby inside your ERP tags and then mapping this to an equivalent HTML representation of that, has been quite tricky.

Speaker 2:

I have a working version for a few tag helpers. But having to figure out where these attributes are, where they are located, how a hash in your tag helper like if you have data and then you have give this whole data attribute a hash, so you have data controller, for example, which are the controller is the key inside of this data hash. But this is going to evaluate back to a data dash controller attribute in your rendered output. But if we just parse this as Ruby we don't see this exactly and where is the whole name? Like we in the parser want to map this back to a location in your view file. So we want to know this position in this document. This is where this attribute name is.

Speaker 2:

But in the case of a Ruby hash, we have to make it work to know. Okay, this is the data part here, this is the controller part here, and we put this together and dasherize it and then we have the attribute name. So, kind of just coming up with how to map all these helpers back to HTML so we can write these lintels and formattles more efficiently has been quite tricky. But once this works out it's going to be quite effective for parsing these files.

Speaker 1:

That is an interesting bit of a blocker, because I guess when I was thinking about Herb, I was thinking about oh, like, everything inside of an ERB tag gets handled as Ruby, and then you just look at the HTML side of things and you create an A. But because we can write Ruby that writes HTML, you have an entire extra step that I wasn't even thinking about. So we should all just stop doing. That is what.

Speaker 2:

No, I think you should. That's the thing. I think you can improve your view code if you use these tag helpers. It doesn't make sense in all cases, but in a lot of cases it might make sense.

Speaker 1:

I run into that a fair amount where I'm putting a lot of interpolation into. I have a div and then like class equals and then I'm using the ERB tags there and also ERB tags for the ID, and then I've got this long list of data and I'm like this should just be the tagdiv helper. That would make this so much easier to read. So I am one of your pain in the butts who writes a lot of tag helper stuff. I do it myself too.

Speaker 2:

I do it myself too, yeah, but the thing is that we had formatters in the past and we had linters in the past, but none of them were really tackling this kind of problem before. And that's the kind of a blind spot in these tools now. So you can validate the HTML stuff but you can't really validate what these tag helpers are going to output in the end. And if you write lint rules for example, if you say all your image tags should have an alt attribute to describe the image and you use image tag with the image path helper to render out your image tags, you don't get to validate these helpers with these rules. So you cannot really enforce that. This rule is kind of satisfied and your code complies with that. So we have to map this back to say, okay, when you see an image tag helper, it's going to output an image, an img tag in your HTML, and all the arguments you pass through, the keyword arguments, are going to be attributes in your HTML. So if we map this back, the linter can see that this is just going to be an image tag and it has these and these attributes. So the linter rules don't even have to care about if it's written in actual HTML or if it's written in this ERB syntax where we use the Ruby helper to generate this HTML for you. So our inter-rules get super smart and they also will just work on these image tag helpers or these view helpers in general that we have in Rails and that's going to unlock so many possibilities and ways to catch errors and accessibility concerns too, where we can now ensure that all these variations of how you write your HTML are covered by OWLint now, and that's something that's really powerful, I think, for tooling in general. So you write this out and in the editor you see right away something is wrong about this and you can immediately fix that.

Speaker 2:

The other thing where this is going to be super useful is for also lint rules again.

Speaker 2:

So if you are writing HTML, you write out your raw HTML and we kind of see that you are interpolating in each attribute. We might be able to recommend to you and say you might rewrite this as a hack helper now because you are using all this interpolation here. So it might just be easier for you to just use this Hack Helper but you don't have to interpolate at all. So we can rewrite or have a autocorrect feature where we rewrite all these instances to a View Helper or the other way around, where we say we see this View Helper here we can say refactor, right-click on it and say map it back to actual HTML. So it can go both ways. And these kind of refactoring tools is what we don't have at all nowadays. So it would be just really nice to be able to have no friction from converting one format to the other and have these tools and linter rules and formatters just be compatible and interchangeable. And that's what this is going to enable, if you are able to map these tag helpers back to regular HTML.

Speaker 1:

I wonder also one part that ActionView struggles with is really the only time we get to test our views. If it's not a view component Sort of a system test, I guess you could write a controller test and then look at maybe. But do you think that the work you're doing with Herb that allows you to do this parsing would potentially make it easier to test things like partials or views?

Speaker 2:

I think there is something to it and I haven't really figured out or thought about too much how this could look like. But I think that we also could improve the testing story. Or at least we can hint you early that something is not right about your partial. To say, if you use an instance variable in your partial, you shouldn't be doing that. You should be using local variables and try to pass them as local variables into your partial. Using local variables and try to pass them as local variables into your partial. That's something we can catch now with a linter rule. To say, if you see an instance variable, flag it and then you have to fix it and otherwise linter wouldn't pass Right. Right, or use the strict locals from the new Rails 7.1, where you say please use that instead, and that's how we as a community can guide people to write better view files as a result.

Speaker 1:

I like the new strict locals. They were a little weird when they first came out. When I first read the PR that introduced them, I'm like, okay, I get it. And then I've actually used them a few times I was like, oh, this is awesome. This is essentially just a very simple comment that gives me better feedback, especially six months down the line when I'm like I don't remember what I was supposed to be doing in this partial or I have a big conditional and I'm like, do I actually need to pass this here? What happens if I don't? That kind of stuff really does help when you've got that.

Speaker 1:

Essentially what Herb is doing for us. It's tightening the feedback loop. It just makes everything that much easier. I don't have to wait until I go and render the view and I get that error message. As I'm writing it, herb is telling me like, hey, you're screwing up, maybe don't do that, which I appreciate greatly. It was sort of like when Prism first happened. Things just got better. Instead of it blowing up and being like there's a problem in this file, have fun, find it. We got an error-tolerant parser and now it was able to say there's an error here, go fix it, which makes life better.

Speaker 2:

So yeah, I guess that's not a direct answer to your question where we have not better testing tools necessarily, but I think we can write more tools around it to kind of rescue you from actually writing these bad view files in the first place.

Speaker 2:

And the same is going to be true for, like, render calls in your partials or in your view files. So if you can go and analyze these render calls and see what you're rendering and what you're passing into them and then maybe give you a warning that's hey, your call to render doesn't match the signature you kind of provided in the strict locals, right, so you can kind of give feedback how this is going to map to each other. Or you're rendering a view here which we don't know about. We cannot see that this view existed on your file system. Create it for me, so you can kind of analyze all your render calls and all your views and partials and kind of build up a tree of what is rendering what, and then maybe also find unused partials or unused view files or all of the kind of tooling that we haven't even been thinking about because we didn't have the foundation to, yeah, build these tools now. So this should be enabling a lot of static analysis, which we haven't been able to do before.

Speaker 1:

It is super awesome, which makes the next question really difficult for you, because the next question is what is something cool, new or interesting you want to share? And I feel like the Herb tool or tooling or tool chain would be a perfect cool, new and interesting thing for you to talk about, but you already talked about it, so you have to come up with something completely new. For what is something cool, new or interesting that you've recently learned or discovered or built that you want to share?

Speaker 2:

Yes, I was going to say that I was kind of planning on talking about Reaction View at this point.

Speaker 2:

So there you go, because we kind of did that earlier. But yeah, just being able to work and learn new languages and tools has been super rewarding. I think that having a side project you can have work on and learn and try out new things is super important for us as engineers. And it doesn't have to be as ambitious as I guess Herb is, but just kind of dabbling with stuff you wouldn't be doing in your regular day job is so nice to level up, and I would say that I have learned most of the things in the past few years thanks to open source. I wouldn't have done any of that if it wouldn't be for open source or for any of the libraries I've been working on.

Speaker 2:

And I know it's quite hard to get into open source if you don't know where to start, how to kind of tackle these issues and where to find even issues to work on. But yeah, so that's just what I wanted to say here. So if you are out there and are looking to kind of want to help out with open source, please reach out. I will be happy to work you into one of these projects that I am working on to help you get started, or even something about the other project I've been working on, which is Ruby Events. It has a lot of easy things to kind of work on there too. Most of them aren't even like Ruby related, they're just data issues. So if that's something you kind of want to just have a first step into open source then please reach out and I'm happy to help you get started with that.

Speaker 1:

Yeah, I'm glad you brought up Ruby events because if you didn't, I was going to. You also run Ruby events, which is a drastically different side project than the side project we've been talking about, Herb. This is much more application style. For anybody who isn't familiar with Ruby Events, can you give a high-level overview of what the site is and does?

Speaker 2:

Ruby Events is, in the most basic form, a collection of Ruby talks and Ruby events, as the name implies. So if you have been missing any of the talks at a conference in the past, you will probably find them on Ruby events and you can find all the recordings, information about speakers, information about the sessions, information about old events that happened years ago, and it just allows you to see what has been happening in the Ruby community. I have been using Ruby events as preparation for my talks to figure out what has been done in the past. So we categorize most of the talks using AI to kind of tag them into topics and you can search for them or kind of go on a specific topic and see what talks are on that topic. So it gives you an easy way to browse what the Ruby community has been talking about and sharing in the last 20 years. So we have over 7,000 talks now and over 3,000 speakers, and it's a super rich resource for anything Ruby events related.

Speaker 1:

Yeah, that's a lot of talks and a lot of speakers. That's a lot of content. Now, the one thing that I at least noticed selfishly from my own page that I actually like I like this a lot, but I did notice it is if there's no recording, like I've spoken a few times, three times now, at Sin City Ruby, and those talks are not recorded, but it still gets listed under my speaker profile as a talk that I gave even though there's no video, which I think is awesome. Whose idea was that? Because I think that's great.

Speaker 2:

Yeah, so I know that people have been giving talks and I know that they have shared something in a talk and it hasn't been published. But just being able to know that this talk exists and actually happened it's not just me making up something, it's so valuable. So just allowing the speakers to have it indexed there and have them share the slides or maybe some other resources to the blog posts or some of the reposts is really valuable. So that's why I want to just focus on also adding all these conferences that don't have recordings maybe not yet or not at all to still be kind of visible on the platform so you can discover and see what has been talked about in the past.

Speaker 1:

So at Ruby events, people can go and look at videos of past events. So they can go. They can look and look at videos of past events. So they can go. They can look at events that are coming up, events that have happened. They can see the videos. They can look up specific speakers, specific topics and you also list out any open call for papers. Is that all pretty manually updated stuff or is it fairly automated at this point where you have good ways of getting that information in and it does its own thing? Or do you have people that submit PRs to add? Or do you just stay on top of freaking everything and update as needed, which wouldn't surprise me given your tendency to be like oh I've got a little bit of free time, let me go build a new view layer parser or keep yourself insanely busy, but I'm hoping it's slightly more automated than that. I wish.

Speaker 2:

Yeah, it's mostly all manual at this point still, sadly. The reason being is that we have such rich metadata about all the talks and all the events. It's quite tricky to even find this information on the website of the conference itself. Sometimes conferences actually list out the talks, sometimes they don't. Sometimes they use a third-party platform, sometimes it's JavaScript-based, so you can't really easily grab information out of it. So we have been looking at ways to automate most of it or some of it. So we have been looking at ways to automate most of it, or some of it at least, but it's been quite tricky to make this reliable and not hallucinate over things.

Speaker 1:

Yes, the age-old AI issue of. Let's just make sure it doesn't hallucinate by not using it. I like that.

Speaker 2:

Yeah, the funny thing was that I was kind of most impressed by the AI was that it made up new YouTube IDs. So, like you know how, the YouTube URL has like an ID in it and it was just going through existing talks and kind of trying to enrich them with metadata and then some of them just try to change the YouTube ID to something else because they are random, right. So it would just go and make up new YouTube IDs which wouldn't actually exist. So it is even more worked into verify all these IDs all are actually legit, are they? Do they exist? Are they the right ones? Just because I don't have that much time to focus on working and making AI work, I just have been doing this mostly manually Okay, but AI gets also better. So we have been looking to ways to make this now work with active agents and similar tools to go through. Give it some context. Have it actually use a browser to browse these pages and then try to extract this information.

Speaker 1:

I really appreciate the site in general, just like one place to find Ruby events that are coming up, find talks that have happened. Youtube's usually decent for tracking down a playlist as long as Comfreaks was the one, it's not too bad, but it is nice to have them a little bit better categorized. I'm not as stuck in YouTube's UI of like, if you're not in a playlist, who knows what's going to play next? And I might be looking for a specific speaker or what have you.

Speaker 2:

So we have some tools actually to automate it from YouTube playlists. So if there's a YouTube playlist on YouTube, we can import them and we have it quite easily imported as an event on reviewments. So if there are videos already, it is super straightforward to import them.

Speaker 1:

I will give you a feature request, live on the air. You need a leaderboard. You need, like a speaker leaderboard to see who has given the most talks, because I thought for sure it would be Matt's, but just at first glance Matt's has 75 talks and Aaron Patterson has 89. So I don't know if anyone beats 89, but I feel like it would be better to have a leaderboard where I can just go and see that information. So in your infinite free time, if you wouldn't mind implementing that, that'd be great I mean it's lucky for me because it already exists.

Speaker 1:

So does it where? Where, show me it's on rupee eventsorg leaderboard oh, you just don't have a link up at the top. You are sneaky.

Speaker 2:

Yeah, it isn't a drop down oh, my god, there it is.

Speaker 1:

Yes, okay, no one has beaten Mr Aaron Patterson 89 talks, 74 formats, 200 of them have actually talks attached to them, so like over 300 events that don't have any talks attached to them, so there are probably even more Aaron Patterson talks.

Speaker 1:

That is a safe assumption that there are more Aaron Patterson talks out there than you probably know about. How can people, if they want to help improve Ruby events, what are some of the ways that they can contribute? Like, if you said there's probably missing events and they find them, say, or they find a video that isn't tied to a YouTube playlist, is there an easy way for them to submit that, or is it just as simple as going to the GitHub repo and open a PR? How does people contribute?

Speaker 2:

Yeah, the easiest way is to just open pull requests. We have a data folder on the top level of the Rails app and it is a bunch of YAML files which just have the definitions of these talks. So there's a quite simple format, quite straightforward. You just have to go and add them one-to-one and then, whenever we deploy the next time, they're going to be added to the website.

Speaker 2:

Nice, we do have a page on slash contributions where we show all the ways you can help out with data. Some of them include adding GitHub panels to speakers or adding dates to events where we don't know when it actually happened, like the actual conference dates or the location where the event happens. We don't have that for all the location events too. So they're like easy ways to make it an impactful contribution just going through and seeing which of these events don't have any of them, and we kind of list them out to kind of give you a nice overview of what's missing or what we know is missing. There's probably more missing than we know of, but at least what we know is on this dashboard.

Speaker 1:

So you have a GitHub repo. I'll include these links in the show notes for people to more easily get to them. But you have a repo for Ruby events. You have a repo for Herb. I'll include links to your GitHub links to socials. What are you most active on?

Speaker 2:

I have been cross-posting to all social media platforms. So if you just go to my website, which is marcorufdev, you see all the socials in the bottom of the page.

Speaker 1:

So found on all socials, fabulous. Is there anything else before we wrap this up, is there anything else you wanted to talk about that we haven't already mentioned or gone down that rabbit hole for?

Speaker 2:

I don't think so. I think that's mostly it.

Speaker 1:

We certainly covered a lot, but I know that you also have just a lot going on, so in case we missed anything, unless you want to jump back to some herb stuff. I mean sure, what do you got? What are you thinking about? What's on the top of your head?

Speaker 2:

Most recently it's been the formatter that I have been working on to improve the outputs. So the formatter itself as it is right now is mostly like an early preview, where we notice some stuff's still broken and some stuff is going to be over formatted. But I have been adding a lot of fixes to make it more reliable and more consistent. So when you format a Vue file in your editor or using the CLI, it produces a good result already. And one of the nice things I have been working on this week is adding Tailwind class sorting to the Format2.

Speaker 2:

So Tailwind has an official recommended way of how you should be sorting your Tailwind classes and it's been the default in JavaScript applications that you can just save your file and it will auto-format and auto sort these classes for you. And given that we have this format now written in TypeScript, we can use this plugin too and make it plug into the Herb formatter. So whenever you kind of save with the Herb format and you have the setting enabled, it will also go and format your tailwind classes and you can now write your own rewriters and your own rules how you want stuff to be rewritten as the formatter is formatting the file. So if you have any custom rules that you have in your company or in your code base or for your framework. You can now write some of these form or rewrite them and have them part of the formatting flow.

Speaker 1:

I didn't know that Tailwind actually had a recommendation for the ordering of their classes. I guess that makes sense for something that's so utility-first to help better organize. Is that one of those places where it's like, hey, we can do it if you're writing raw HTML, but if you're writing raw html but if you're writing using a tag helper, maybe it doesn't work there yet. Or is that something that probably will work in both places?

Speaker 2:

there is like ways to format html or like have it format in html with the already existing plugin they have, but it wouldn wouldn't then auto-format the ERB the right way because it has no knowledge about it being an ERB interpolation right there. So if you're interpolating in your class attribute, it would know that this is ERB and it would kind of scramble up all your classes and your if conditions and the else's and so on. So you have to kind of guide it to say this is ERB, we're going to handle this, but these are classes. You can format those. And once we have the tag helpers the actual tag helpers mapping also in place, we can also run them as part of the rewriting of the tag helpers. And then you can have it also auto-format or auto-sort the classes in the ERB helpers, which is going to be, I guess, really cool if that works out.

Speaker 1:

There's so many cool things that you can do on the Vue side of things to make life so much easier. I'm sure, given that you work a little bit more on the front end than some of us do, you know of them all, which is how you come up with your roadmap. But it is cool to see some of these tools making their way to the Rails ecosystem, where Ruby, being so focused on developer happiness, it would make sense for us to get developer happiness tooling for our Ruby and, in this case, rails applications, which actually begs the question have you thought about Herb for non-ActionView Ruby applications, like maybe Hanami or Bridgetown or something else where it's Ruby probably uses ERB templates, but isn't ActionView?

Speaker 2:

I mean, the good thing is that ERB the parsing as it is right now is quite universal, so it should work on these view files too. Maybe we can have options to enable or disable the ActionView helper parsing, for if it's going to be parsed in the Hanami app or if it's going to be parsed in a Bridgetown app where we don't have them available, so that you can pass it options to say, please enable this analyzer or this kind of transformation or have it a little bit more dynamic. But since we don't really have the ActionView tag helpers anyway right now, it should be working for all of these as it is today.

Speaker 2:

So it works fine on everything for now, until the next feature release, and then maybe I want to make this work for any HTML EPU file that you can think of, if it is in Rails or not. So I'm also looking in ways to make reaction view work in Hanami apps, if that's possible and something that community wants to have too. So if it's going to be viable which I'm not sure it is at this point, but if we are going there and's going to be viable which I'm not sure it is at this point, but if we are going there and are going to explore what is possible, I also want to include Hanami or maybe even simpler Sinatra or other apps that are not Rails.

Speaker 1:

That'd be superb. I'm sure there's lots of people out there that would benefit greatly from the tooling across the Ruby ecosystem, not just Rails. But as a Rails dev myself, I greatly appreciate the tooling across the Ruby ecosystem, not just Rails, but as a Rails dev myself, I greatly appreciate the tooling regardless.

Speaker 2:

Yeah, and the same is true for the linter. We have custom linter rules now that are specifically built for Action View, which wouldn't make sense in other contexts. So also for those, you would kind of scope them the right way or have them enabled or disabled for how we're going to use them in your app.

Speaker 1:

Well, you have lots on your plate speaking at multiple conferences, going to multiple conferences, this whole Herb ecosystem and Ruby events so I don't want to take up too much more of your time because your time sounds pretty stretched thin as it is. We've already talked a little bit about how people find you. I will include those in the show notes so that people can find you and hopefully contribute and help out or reach out to you if they want to get started on open source or developer tooling, since you are the guy. Thanks so much for joining the show and getting this recording. It's been a little bit trying to get you on, but I'm glad that it finally happened. And as the Herb project evolves and all of your other projects, feel free to hit me up next time you want to have a chat about whatever you're working on and get it out until they open. I'd love to have you back on.

Speaker 1:

Yeah, thank you so much for having me Listeners. We will see you in the next one. Bye.

People on this episode

Podcasts we love

Check out these other fine podcasts recommended by us, not an algorithm.

Remote Ruby Artwork

Remote Ruby

Chris Oliver, Andrew Mason
Ruby for All Artwork

Ruby for All

Andrew Mason & Julie J
IndieRails Artwork

IndieRails

Jess Brown & Jeremy Smith
The Bike Shed Artwork

The Bike Shed

thoughtbot
Code with Jason Artwork

Code with Jason

Jason Swett
The Code Gardener Artwork

The Code Gardener

Alan Ridlehoover & Fito von Zastrow