092: Your Wails app... on mobile? With Lea Anthony

Morten:

Hello, Gophers. My name is Morten.

Dominic:

And I'm Dominic StPierre.

Morten:

Today, we have the man behind Wails with us. How are you doing?

Lea:

I'm good. Thank you. Thanks thanks for having me on again. It's it's a pleasure to be here.

Dominic:

Yeah. We we we talked last time, you know, it was it was very interesting. I think I I I think I I will I will have some deeper question this time. And because I I tried Wells. Wells.

Dominic:

Yeah. I I I it's it's it's pretty interesting. I I have an old machine myself, so unfortunately, there were some dependency that were I I could not install for some reason. But but yeah. Thank you.

Dominic:

Thank you so much for returning. So from what I heard, the v three is is pretty soon to be released.

Lea:

That's correct. Yes. It's been in a heavy alpha churn for the last, oh, I think nearly three years. So we're very, very much due to to do a release. The last probably month or so, I've been ramping it up a lot more.

Lea:

I think I've been accused of being a bit of a perfectionist in the past, and I think this I think this whole process has has proven everybody right. So I'm gonna just draw a line in the sand and say this is good enough for now, and hopefully the the beta release will be in within the next five days. So yeah.

Dominic:

That's that sounds fantastic. Can you, you know, can you recap what exactly is the major changes between v two and v three? And what about people that do a v two at the moment? Is is it is it you know, will there be a lot of things that they will need to migrate and things that that are broken in a sense?

Lea:

Yeah. Okay. So I'll start with the features because I think that probably answers the the second question. So the features for v three, we have multiple windows. So that was the first big one.

Lea:

The first one was very much designed around a single window application. So the ability to just spawn as many windows as you like, yeah, that was being done through a procedural API. And I think that's probably the biggest change. With v two, it was almost config driven. So you defined your application.

Lea:

You defined the window size and all of the parameters that you would want as part of your window. You would point it at a a embedded f s dot f s, if you know what that is. Yep. Yep. And it would basically serve the the files from from there.

Lea:

It I suppose it didn't have to be embedded. Like, you could just give it an f s dot f s. I know one company was using SquashFS of all things, and that's how they were pushing out updates to their to their front end. So yeah. So the so v three is very focused on procedural instead of instead of that sort of, like, config driven.

Lea:

So you can you can spawn multiple windows. You you have a lot more flexibility around the APIs as well, like, what you can do with those windows. Yeah. That's that's one of the core I I guess the biggest core fundamental difference is kind of config driven versus procedural. There's also a lot of features as well as apart from the multiple windows, like you've got a native system tray support.

Lea:

So in I think in Mac, it's called notification icons, I think it is, in the top corner. Yep. And I think another thing to talk about is probably the the bindings generator. I don't know. Did you play with v two at all?

Lea:

Think Or was it v three? Yep. So version two, what would happen is it would actually compile a version of itself that was headless. So when it ran, it would enumerate the bindings. And so bindings are functions that you wanna expose to the front end.

Lea:

They're go functions. And so it would enumerate those bindings, and then it would write that out as JavaScript or TypeScript to disk. And then eventually would compile itself again in non headless mode. So you had this kind of strange sort of double pass, like a two pass method. What was interesting about that was anybody who had any kind of long running process within their main file would just see a hang.

Lea:

And so that was awful. Like, it was a terrible UX. And honestly, was just a terrible way of doing it. But it it it does work, like, pretty much all the time. So for v three, something that I kinda dreamed about doing was having a static analyzer.

Lea:

So something that would read through your code and understand and understand what your bindings are based on just through the parsing of your of your files and the AST, work out exactly what it is that should be dumped on disk as bindings, and do it on the as part of the kind of build process. Does that make sense?

Dominic:

Wow. Okay. Yeah. And that that's nice. I I I did not knew that the that you build the ability, you know, is is that taking on Azure?

Dominic:

Wow. This this is interesting. Go Go is so nice for that. I mean, the the AST package is is pretty nice to introspect. So would are you any any major challenge building that?

Dominic:

Because it it it's it's way more complicated than than just saying, oh, you know what? I I will build a static analyzer. I I tried to build that for one of my small small package. I I do have a a small package for Go template. So it's it's just something on top because, well, for some reason, tempo for me is is not working and things like that.

Dominic:

But I I wanted a way to have my my template to be statically typed, you know, ish in in a sense. Also, just have some some kind of, you know, something that check. Oh, you know what? I'm passing this type and the template is is doing, you know, some wrong assumption about what it's it's receiving. So, yeah, I I was not doing the I I was not, knowing that you, you built that.

Dominic:

So any any challenges?

Lea:

So I cannot claim credit for building that. I am I am definitely not clever enough to to go through something that deep and complex. I was very, very fortunate to be approached by two people at roughly the same time. They opened up PRs for for doing this. And Wow.

Lea:

I think as a as an open source maintainer, you know, I've been, you know, involuntary open source maintainer. I never trained for it. Dealing with that was probably one of the hardest parts of the project. You know, you had to say no to somebody. There was no way you could have both.

Lea:

And it was a little bit tricky. But, yeah I think I just have to look at it from a long term perspective and yeah and just decide on one and it was I was really fortunate that it just kind of fell together that one of the approaches was more aligned with kind of what I'd had in mind. And so the person who developed that spent an incredible amount of time really honing that in, taking feedback from the community, yeah, extending it in in in ways that I I never thought could be done. For instance, we have a thing in Wales, which is, like, you can send events, and so it's kind of a unified unified events bus. So if you send an event in Go, you can receive it in Go, you can receive it in the front end, in JavaScript or TypeScript.

Lea:

If you send it in the front end, you can actually sorry. If you send it in the front end, you can receive it from from Go. And one of the things that you can't really do very well with events like that is send different types of information, like typed information across the wire.

Dominic:

Yeah. So

Lea:

what this person did, his name is Massimo by the way, he's an incredible, incredible programmer. He proposed the ability to actually register types against those events. So you could actually say, I'm registering this, let's say, person. So this struct, which has a name, address, whatever. And you can say, I'm using this in events.

Lea:

And so anywhere that you actually pass one of those into an event in your code, the static analyzer picks that up, understands exactly what that is, and can dump out perfect bindings that have that shape in TypeScript on the other side.

Dominic:

That's nice. That is nice. So and and it's the same for the other way around, I I guess, that when the event is sent from JavaScript, it it turns out to the to this this person ghost track.

Lea:

So in Go, you usually would write all of your types in Go, and so you'd be expecting that format coming in. It will translate it for you. Yes.

Dominic:

Okay. So so it's not coming as a bytes stream, so it's it's already it's already converted in in the Go side. Okay.

Lea:

Yeah. Correct. Yeah. Yeah. So the the the static analyzer is all about providing that sort of glue code for you to be able to call Go methods from JavaScript.

Dominic:

What is the advantage of calling these events versus calling direct functions? So from from the the little I I know so far about Wells because I I haven't used it, you know, in production per se yet. So I can call some go function from from the JavaScript side. Why would I publish an event in the end, you know, in that case? It would and is the Go side able to call JavaScript function as well or the only mechanism to to communicate with JavaScript from Go is via those events?

Lea:

So we did do a little bit of a deep dive into calling JavaScript functions from Go. It is possible, but it's not many people have asked for it. There's only been a couple of people asked for it. So I think academically, we kind of, you know, close the circle if we did that. But there hasn't really been that much, yeah, demand.

Lea:

The difference between calling a a function and sending events, it's a good question. It's one I asked early on. It's like, do I really want to support two ways of doing this? But they're inherently different. So a call to a function, you're expecting a result.

Lea:

Whereas with events, you're really just sending notifications out, and it's async. Mhmm. So they're two different tools for two different problems.

Dominic:

Okay. Yeah. Got it. Yeah. That's that's interesting.

Dominic:

So would you say that it was something that that was difficult for you to accept? Because let me let me try to phrase that correctly. But let's say let's say that you add up this this new static analyzer and and this, this programmer for some reason cannot contribute anymore. So now you have this, this major piece that is pretty important to the v three, but, yeah, but, you know, in a sense, the the main person behind it might not be able to, to continue to contribute. Was was that a concern?

Lea:

I think it's a concern for anything. Right? So it doesn't really matter it doesn't really matter how big the the feature is. If you didn't write it, you still have to reverse engineer it. You still have to understand how it works and, you know, way way you move it forward.

Lea:

That actually happened. I mean, Maslow had to take a break for a bit. And, yeah, it was interesting. I I think that problem has changed an awful lot over the last year. So I think it's much easier to ask an LLM to go and analyze a whole bunch of code and to provide you good feedback on structurally how that works.

Lea:

And so can cut down a lot of that cognitive load for you because it kind of breaks it down into chunks, and you can go and verify those chunks, which is a lot easier than just staring at my god. It must be, like, four hundred four hundred files, I think, is in that? 400 plus?

Dominic:

For the static analyzer?

Lea:

Yeah. It's pretty big.

Dominic:

Wow. Yeah.

Lea:

Yeah. It's pretty big. I might have exaggerated that. It seems like 400 when you look at it.

Dominic:

Oh, yeah. Definitely. Definitely, I I I I can imagine that an LLM can at least try to guess what's going on there way faster than than a human can. That that is for sure.

Lea:

Yeah. And and, honestly, a project of this size, you kinda need to rely on that. If I was doing this as a full time job, then for sure, I could spend an awful lot more time manually looking at stuff. But these days you kind of have to wonder whether is that the best use of my time? Like, time is time is the most precious resource.

Lea:

And where you spend it, you have to, you know, you have to be careful. Right?

Dominic:

Totally. So so you would say you would say that for you, I would guess that LMs are kind of, you know, helping more than because we we are hearing a lot of a lot of open source project these days that are receiving a tons of PRs and and, you know, not always the good quality PRs and whatnot. So, you know, what is the situation for for Wales? Is is it is it a problem for you at the moment or or or it's more, you know, it's okay for now?

Lea:

It's okay for now. Somebody brought this question up actually on the Discord channel. Look at me saying Discord channel. Discord server. There we go.

Lea:

Mhmm. Yeah. I was they were asking, you know, you you worried there are some projects that are being swamped, completely swamped by AIPRs?

Dominic:

And it was

Lea:

funny because it was around the time where I was going through a whole bunch of issues that were raised, and I was thinking: Man, these are like one liners, you know? One, two lines. It would have been much better if this was just a PR and it probably would have taken less time. So my response to that question was really, I would rather have a PR than no PR. Yeah.

Lea:

Because if there is no PR, then I have to do the PR. Then I would have to review the PR anyway because I'd probably using be using an LLM to generate the code for the PR. And so if somebody else has already done that stage for me, then that's fine. Now the relevance of the PR is another thing. Right?

Lea:

Like, is is this something I wanna accept? And that's you know, you could eyeball the the PR description for that, or you could get an LLM to summarize it for you. And so I think there's different levels of governance that you can introduce and different levels of ways of using AI to to to manage that. So I think I think my general answer is I think I'd fight fire with fire.

Morten:

So you you haven't you haven't adopted, like, a AI policy yet? It's more like, if it's good, it's good?

Lea:

I think that's my policy. Yeah. Yeah. I think Nice. If it's good, it's good.

Lea:

If it's not good, it's not good. I don't care who wrote it or what wrote it.

Morten:

Yeah. That was funny because we we hear like, I I follow what's it called, Hasimoto, Mitchell Hasimoto, the guy behind Hasicorp. And I think he adopted a sort of similar approach, but he also added a vouch system to the ghost repos. But I think he adopted the same approach, right? Like, I don't I use he also uses AI and if it's good, you know, it drives the project forward.

Lea:

Yeah. And I'd I'd agree with that. That there's an element of the it's interesting you say about the the the I think he murdered a project, didn't he? Was it Vouch? I think it was.

Lea:

Yeah. He was trying to yeah. He was trying to automate a way of building a web of trust around PRs. I think it's a good idea. Do

Morten:

think it's

Lea:

a good idea.

Morten:

Believe they did something around, like, you have to open an issue, and then if you get vouched for by a lot of contributors, you can actually implement that issue, and then you you are in the in the, what's it called, pool of trusted people to to actually then continue open PRs and add PRs to the to the project, which seems like an interesting approach.

Lea:

I do you know, I think that's I think the idea is good. I think that execution is practically problematic. And the reason I say that is because if you have a somebody who, I don't know, lives in New Zealand and doesn't know, like, anybody, like, how do they contribute? And and will that be a barrier? They think, well, like, I just I just wanna add this.

Lea:

I want I'm happy to give my time to to add this feature to this this project I love. Now I'm kind of blocked. I'm I'm gatekeeped by other people who I need to vouch for me. And how do I do that? So I don't know how Mitchell's got around that.

Lea:

Like, how like, how do you get people to vouch for you? Is it based on like, is it some sort of, like, Internet karma? Like, you've you've raised you've answered some stuff in the discussions. You know? I don't know.

Lea:

How does that work?

Morten:

I think it's around the I haven't looked deep into it, but I believe it's around if you yeah. I think everyone can create an issue and then if that is vouched for by someone to be of value, I think they get the approval to be able to create the PR and that's the way they get in. But they also raise to the point if you have thousands of issues being raised, you're probably still waiting for someone, right, to actually take the time and look at it. So I think he is also this is the best I can do with the current situation. But it's true, you probably discourage a lot of open source contribution, which is is said with the given the state of the world where there's a lot of pipe coders that just churn out stuff and you never really get hurt in that noise.

Lea:

Yeah. So No.

Dominic:

Yeah. I was going to say, yeah, it's kind of crazy to say that to contribute to, to an open source project in the future. You you will you will need you will need an audience. You will need to be extremely popular, and and now you have more chance of your PR to be, at least to resurface. It's it's kind yeah.

Dominic:

It's kind of anti, you know, open source in a in a sense. It's it's yeah. It's, but but on the other end, there there's there's still there's still a problem in a in a lot of projects. I mean, receiving receiving that amount of noise is sometime problematic, and that that is that is a hard problem to fix, I think.

Lea:

Yeah. I think with like, looking at a slightly higher level, like, for me, it doesn't really matter about whether an LLM has authored some code or not. The bigger problem for me is if you say yes to an idea or an enhancement which is something you're gonna have to live with because as soon as you say yes you have to keep it there until you maybe bump a major version and annoy people that you've dropped support for that feature. So I think maybe this could be stemmed more on a kind of workflow where you've got people voting on a proposal rather than an issue. Yeah.

Lea:

Maybe it's this maybe it's the same thing. I don't know. Maybe that's maybe it is the same thing. I don't know. It's something that I've kind of drafted for version three of Wales, which is it's the Wales enhancement proposal.

Lea:

And the idea behind that is that you essentially have a template that you you fill out and you say what it is you'd like to enhance, why you'd like it there, and how you would go approach implementing it. And the idea is that you'd you basically socialize that. You open that as a as a draft PR, and you socialize it. You bring it to Discord. You put on the discussions.

Lea:

And if you can get people to to vote on it, which is basically, you know, up thumbing on the on the emoji, then it's likely to move forward. It's likely you know, I'm likely to say, okay. This is this is cool. Like, I agree with this. I think this is great.

Lea:

It looks like there's a good lot of support. You've had some feedback for for changes. I agree with those two. Like, let's iterate on this. And as soon as you get to a point where you fundamentally have the idea and you have an approach and you have, you know, a way of implementing it that that people think will be net benefit for the project, then the actual code bit is, like, I don't really mind who writes the code.

Lea:

You know? I don't really mind how that happens. Because so long as it works as it it's advertised and was designed and has good tests, it has good coverage, then I think you're gonna stave off a lot of that issues, right, where people are just opening up PRs with one line changes. Yeah. Like, if you if it's bug fixes, then sure.

Lea:

Like, you if can find that many bugs and and you're you're fixing them at that rate, then that's perfect. If you're adding enhancements and there's no enhancement proposal, then you can automate closing that, and you can say, open up the enhancement proposal. And so I think it can it can kind of look after itself to a degree. Honestly, it's just mainly a it it's it's mainly an idea that I've got floating, and I do have some things in place. But I'm thinking that that approach might be might have might have some legs.

Dominic:

I like that. I like that a lot. It's it's yeah. It should be definitely the way to go for for a lot of projects, I think, because at at the end of the day, the the maintainers want to want to receive something that they HIDR will will help the the community, you know, give them something very important that they want or like you were saying, you know, important bug fixes and whatnot. So those those are always interesting.

Dominic:

But but, yeah, I like that, and it it should should probably be like that. But, yeah, we will see. Let's return a little bit to Wails. So I'm I'm very curious to to know how a Go function can be exposed to a JavaScript runtime. So that that yeah.

Dominic:

That is so intriguing to me. I'm wondering if there's anything that you you you are doing with the WebView. Is is there is there a hidden, you know, comment or something like that that that you that you're using? Are are you patching something? I'm I'm very, very intrigued to know how a JavaScript can can call a Go function.

Lea:

It's a great question, Dom. It was something that I thought about when I first started the project, and it was over eight years ago now that I started the project. That was one of the first things, obviously, that I had to tackle. So looking at the WebView library, I realized that there was a lot of things, like a lot of burden on the on the developer to be able to bridge that gap specifically. So that was something that put a lot of thought into.

Lea:

Now there's kind of two ways. If you think about a browser, a browser kinda calls, like, external resources. Right? Like, it it it's gonna it's gonna ask for a web page from a server. So you have this kind of prompting.

Lea:

You have this two way communication, right, which is initiated from from the browser side. So WebViews obviously have that capability. So that's one way of communicating to a bucket. The other way in a WebView is that you can actually use something called post message, and all of the WebViews have this. So you essentially set up a hook on your host side, on your native side, and you say to the WebView, expose this hook, expose this pathway through to be able to send a string.

Lea:

And that's that's pretty much all it does. I think WebView two, which is the Windows WebView, added the cape added the capability of sending a a JavaScript object, but I don't really see how that's any different to a string, really. At end of the day, you're just dealing with information that's coming in as a string, and then you parse that on the the server side. When I say server, I mean the Go side, not It's not running over the network, it's in process. And then you essentially parse that.

Lea:

So for version one and two, we used that method where you you send the string over. And what it would do is on the client side, it would set up essentially a unique ID, and it would pass a unique ID through with the request, through with the string. The Go side would read that up. It would pass the the information. So in there, you would have, here is the function I'm calling.

Lea:

Here is an array of arguments that is gonna be passed through. And, obviously, if there's any mismatches, then it would essentially send an async message back to the front end with the ID and the fact that it had errored and, you know, an error message. And so the front end would resolve would essentially it does is it links that ID to a promise. And so when you when you make the call to the back end, it's it essentially gives you a promise back, and then that if that errors, then it it essentially rejects it. And then if the call resolves sorry.

Lea:

If the call is is complete successfully, then the message gets sent back saying, yep. It was good. Here's the ID, and then it picks up the promise and then resolves the promise with the results that it had passed back. So it's this kind of it's two way async, essentially, which brings its own little problems. You can get things out of whack a little bit.

Lea:

Like, some things may not come back.

Dominic:

Yeah. So

Lea:

for yeah. So for v three, I decided to move over to using the HTTP protocol, but not over the network stack. So that's still in process. There's pros and cons to both approaches. HTTP obviously has more overhead in terms of what it sends and and how it processes.

Lea:

However, the guarantees you get with it is kind of what we wanted to use it for anyway. So it was it was a pretty good option for us. The sort of string method was really bad. If you go fetch an image, then go first of all, Go converts those bytes to I think it's base 64, and then sends those back as a, you know, base 64 string, which sometimes would get truncated because it was too big. Whereas, at least with an HTTP protocol, you have all of that sort of chunking and and, you know, that sort of the codec's already there to convert between the the different formats.

Lea:

And so the front end, obviously, is very much designed for dealing with HTTP traffic. So that's gotten around a lot of our issues. So we have for v three, we use the HTTP protocol, but in memory. And so you can just receive the call and then process it and then just respond as you normally would. This has also meant that we've able to attach things like, like, let's say you've got a JIN program, like a server program.

Lea:

So you can actually attach those same methods, and it kinda expose those to the front end. So now you're actually calling methods on the front end rather than endpoints. Does if that makes sense.

Dominic:

Yeah. Yeah. Yeah. Yeah. A little bit.

Dominic:

I I have so many question now. Time? Yeah. Sure. Sure.

Dominic:

Well, the the post message is very interesting. But now now I'm pretty interested into the v three ways of doing thing because when you well, first of all, when you say in in memory for the HTTP protocol, what what what are we talking about here? So are you spawning any kind of real HTTP server on the Go side and this kind of dispatch the call to a function to the real the real Go function? And what what does it mean to be in memory exactly from from the WebView side of thing?

Lea:

Yes. So what the Go side does is it does essentially two things. It, first of all, creates in memory HTTP server. So not on the network stack. It's it's something that can receive HTTP messages and can process them like a server.

Lea:

The second thing that happens is that the protocol so we have a we we essentially have a custom protocol. So, you know, at the start of a URL, have got HTTP or you might have HTTPS or you might have mail to. So we have a Wails one. And and you can register that with the with the WebView. And so you can say intercept all traffic that uses this this protocol.

Lea:

And so that's what happens. So you essentially make all of those calls using that protocol. It gets picked up by the host, and then the host will just decode that message as normal and and can respond Wow. In the normal way.

Dominic:

That is that is exciting. Fantastic. Very nice. That this this sounds this sounds great. So I guess that now you can pass the argument in in the, you know, the request body and whatnot and format that properly in in a sense.

Lea:

Absolutely. Mhmm. Absolutely. And it also unlocked the whole new thing in in v three as well, which was, you know, people asked about kind of plug ins, like, like like, one of my visions when I first had v one was how can I sort of package Go and and JavaScript code together? Like, how can I how can I do that?

Lea:

That would be awesome because imagine having essentially go back components that, you know, works natively in your native app. And one of the things that's kinda going down this HTTP route was was essentially that we could provide a function call functionality called services. And so what a service is is something you can register at the start, and it takes it takes over from the the concept of bindings. And what a service is is it it's more plug in like. It has it has an interface.

Lea:

So if you conform to the interface, then then it's a service, and you can register it in your application. And it does a number of things for you. So not only will it generate the bindings for you, but it also gives you the ability to mount that service on a URL path from the front end. So you can now go to slash service slash whatever it is that you mounted it as, and that service will have a you know, the standard Go function, the serve HTTP? Yep.

Lea:

So if your service has that, you can mount it on the front end, and any request to that service will then turn up within that function body. So now you have a way of using Go's modules to to create these bundles of functionality that you can expose to the front end. Does that make sense?

Dominic:

So the front end is calling URL now. It's it's not calling a go function per se. Exactly. Yeah. Okay.

Lea:

A good example of that is we have we have a tutorial on the on the v three website, which is a QR code generator. And so that happens on the server side. Server side. The go side. Yeah.

Lea:

But it's but as a as a module, you can you can distribute it. You know? You can like, anybody can just just just import it and then attach it, and then your front end can now generate QR codes. You know? And you can even put it in, like, an s r s r c, like, an image tag within the s r c, and it will it will just appear at the front end.

Dominic:

So you can call the the service function directly in the the HTML attributes, and it will since it's returning any an image, it will it will all all be good. So from from the JavaScript point of view, what am I calling? Am I calling something like, I I I guess I should import the the service binding network created, and now I'm able to just call the function?

Lea:

So you have the option of doing both. So if you if you mount the service onto onto your, you know, application, then you can do the you can go down the URL route. If you but that that actually goes to a serve HTTP function. So that's more designed for, you know, getting dynamic information from wherever you're calling URL to do a particular function. The QR code is a good example of that.

Lea:

You don't wanna necessarily, like I mean, you could set up a function, right, saying create QR and then call that and then get the image back and then use JavaScript to to pump it into the right place. Like, you can still do that if you wanted to. But the idea behind mounting on a URL is that, you know, other third party libraries that maybe you could use that would, you know, call that URL to go and get information.

Dominic:

But it's a linear level. Well, when when you say mount so so so let let's let's keep the the QR code example. So what am I putting exactly in in the SRC attribute? Am I putting, like, Wells column slash slash in now the the service URL?

Lea:

You actually yeah. You actually just don't need the protocol because the WebView will go for, you know, whales colon slash slash index dot HTML, and so it remembers the the protocol. Like, it it remembers the

Dominic:

Oh. Way Yeah. Yeah. Yeah. Right.

Dominic:

Yeah. Yeah. Okay.

Lea:

And so you're actually just using, like, just just just just paths. That's it.

Dominic:

Okay. You have to do. Oh, that's great. Okay. So now it's it's it's it's way more similar to a real, you know, typical web application now in a sense.

Lea:

Yeah. Yeah. So much so that's that's a good segue actually, that you can actually compile that application into a server application. So now you can deploy it headless and you can go there and it will function exactly the same.

Dominic:

That's interesting. Okay. Yeah. That's a pretty big change if I if I understand correctly. So now, okay.

Dominic:

So we have multiple window. We we have this, this this new way of defining services, the the tree icon. So the tree icon, is it is it working similarly in in all OSs, like, you know, on Linux, Windows, and and Mac? Is it is it like I'm defining some kind of, I guess, three items or or whatever, and I can react to clicks on those things?

Lea:

Yeah. That's correct. Yeah. Yeah. Yeah.

Lea:

It works it works on all it works on all losses. It works pretty well at all losses. It works perfectly on Windows and Mac, but, you know, Linux is the gift that keeps on giving. And I'm sure you know what I mean by that. There's no one way to do it.

Lea:

I had somebody post the I think it was probably on Discord saying, oh, I'm on this, like, version of Linux that I've never heard of. And when I do this, like, I get the in the in the notification, I get, like, a a package ID in the notification. And and is there a way to change that? I'm like, I don't even know that we do that. I don't even know that we send that.

Lea:

Like, I don't even know where that's coming from.

Dominic:

Yeah. Yeah.

Lea:

So, yeah, Linux is a just an absolute minefield. But in general, yeah, like, it it works pretty well, and you don't it doesn't rely on third party libraries either. So that's handy.

Dominic:

Yeah. Yeah. Totally. Yeah. I I was try I was starting to build a Wells application.

Dominic:

I I I have this project that I want to build since 2002, if you can imagine. I I will build it at some point in my life. I'm nearly there. Nearly there. And I I want to use Wails.

Dominic:

More than I was was curious to to hear. Have you have you built any kind of, you know, GUI application in in your career?

Morten:

No. No. I haven't. But I have considered it for when we talked about processing and and and dealing with, like, the podcast and the video podcast. So I was actually thinking this could be a nice little project, side project, when I also get some more time to use Wails for for this part, like a with, like, audio processing and stuff like that.

Morten:

I think that could be cool. But I've never done it before. Mainly mainly done web stuff.

Dominic:

Yeah. Yeah. But but that that's the that's the strong suit of of of Wails, I think, is is that it's still web stuff at the end of the day when when you think about that. This and, you know, Lee, I I was I was saying that to you last time, but for me because I I was playing I was starting to play with with TK the other day. I I don't know why.

Dominic:

I mean, if I I just like to I just like to play with things, but it's not accessible. Can you imagine that? A a twenty twenty ish years old UI framework that that isn't accessible. I I was very, very surprised to to find out. I tried to to help Andy and and the fine project to to make the fine project, you know, be accessible, but it's a little bit out of my league if I can say that.

Dominic:

I I'm I don't know. I'm I'm not a system programmer. Right? I I I screen readers and accessibility is is is just like the static analyzing that you were talking about. It's it's yeah.

Dominic:

Those those are those are complex things where I was going with that. Yeah. So so returning to my my my project that I want to build, I wanted to build that from, you know, from WSL, and I wanted to trust compile to to Windows. But, yeah, it was it was it was not working for me. So I I I think you are you are still depending on some and I might might be wrong there, but some graphic library that that needs to exist on on on the on the OS OS to build?

Lea:

So for Linux, that is true. But for Windows and Mac, it uses what's natively installed in the operating system.

Dominic:

But I cannot really easily cross compile from Linux, my Windows binary. Right?

Lea:

No. You totally can. Yeah. So that's another thing that that v three's introduced. We've got a Docker container.

Lea:

Like, if you're willing to download, I think it's about eight eight hundred eight hundred megs. But

Dominic:

Yeah. I don't I don't mind. I don't mind. Exactly.

Lea:

But, yeah, we so one of the I've just yeah. Quickly go over a couple of things maybe a lot on on this line. So one of the things we did in v three was shift away shift away from kind of an opaque build system. I think we spoke about it last time that that was gonna happen. And we landed on using a project called Task File for for doing that.

Lea:

And, essentially, the idea was was to take all of the internal steps that need to be taken to to generate a application like this. And there's more than people think, you know. It's like generating the bindings, making sure the icons are in the right size and the right format, putting them together, you know, on Mackie Crate directory structures and put things in the right places. And so it was kind of like exposing all of that into what were essentially YAML files that that that task can run. And I worked with the guys on TaskFile as well to make task work as a library.

Lea:

So that means that the Wails three CLI can run those things without an external dependency. And the reason I'm bringing that up is because when you wanna cross compile or when you wanna compile on your own native platform, you would run, say, like, Wails three build. But if you wanna cross compile, then you can just tell it, like, I wanna do this on Mac or I wanna do this on on Windows, and it will do that for you. And to kinda set that up, make that a bit easier for people because you still have to kinda fiddle around with Docker a little bit and download an image from here, there, and everywhere, you can now run Wails three setup. So you install the binary using go install.

Lea:

You're in Wails three setup, and it will launch a program that will essentially open a browser and guide you through, like, the setup steps, like a like a wizard, I think we used to call them, which will go through, and it will ask you, you know, what platforms you're interested in developing for. Do wanna you know, you need to install Docker. Click here to go to the Docker site and install it, and it'll just kind of gently guide you through and download that in the background as well. So the idea being that by the time you get to the end, if you're on a reasonably good connection, it'll all be set up for you.

Dominic:

Nice. Nice. Okay. Okay. So and and and what?

Dominic:

Are you I are you saying that from my Linux box, I should be able to create a Mac, you know, legit binary?

Lea:

Correct.

Dominic:

Oh. Cool. Wow. That that is that is great. That is exciting.

Dominic:

Okay. And and and with with the the proper p list and then like you were saying, the icons and what whatnot, what whatever the Mac wants.

Lea:

Absolutely.

Dominic:

Okay. Yep. And I don't need I don't need an Xcode license or I don't know what and things like that.

Lea:

You you do To publish.

Dominic:

To publish. I I will

Lea:

Oh, no. To to publish. The only thing the only thing about publishing Mac apps is Apple have gotten more and more gatekeeper y with with their application deployments. So if you create an application that hasn't been signed with a developer certificate, then it's getting harder and harder to to run that. It'll run fine on your machine, but as soon as somebody else gets it, it'll say things like, this is from an untrusted source.

Lea:

You know? And normally, can click a button in the security section in in the settings to say, yeah. Yeah. That's fine. That's cool.

Lea:

I know this. He's alright. He's not he's not trying to own my machine.

Dominic:

For now.

Lea:

And for now. Or ever. Just kinda make that clear. But, yeah, they're getting more and more funny about that. So they're they're making it tire and tire.

Lea:

And I think it's, you know, it's just they're just trying to get more money out of people. Right? Like, they just wanna sell more developer licenses. Yeah. So yeah.

Lea:

Like but to make to make that for sure, like, it'll work, and it'll work on your your local machines just fine.

Dominic:

That is that is great. Okay. Okay. I I that that is nice. Because I yeah.

Dominic:

Personally, I I just I just like to build everything and and be on on Linux. For for accessibility reason, I I needed to switch to Windows, but I'm I'm doing nothing on Windows.

Lea:

It's Mhmm.

Dominic:

So so, yeah, now now now that you're saying I might be able to to start that project after all after after twenty four years. So v v three sounds pretty wow. Yeah. That was that was a major update. This this sounds this sounds pretty amazing amazing.

Dominic:

So can you can you quickly tell maybe a a small use case about the the multi window? I I I have a little bit difficulties to you know, what what kind of application need, like, multi windows? Because, you know, the GIMP could could be an example of of of things that, you know, image processing and things like that. So why why user wanted multi windows?

Lea:

It's a great point. A lot of people don't, and a lot of people just just use one window. But, obviously, there is a great need for it. People really, really, really that was that was the highest, like, upvoted issue on the on the project.

Dominic:

Okay.

Lea:

I mean, that yeah. There's there's there's multiple things. I I you know, like, I was thinking earlier, like, I've got a I've got a quick program, like, a small program that will, like, render markdown files because I I was getting fed up of, like, the Markdown render I had. And I was like, no. I want this.

Lea:

I want the ability to change themes and stuff. So I completely, like, vibe coded this this Markdown viewer in in Wales. And if I double click the like, if I've got a really long file, say, and I'd wanna see that like, I want it all lined up in front of me. So I wanna see each, like, page, let's say, you know, like a whole bunch of notes for a podcast, for instance, then it would be cool if you could open that multiple times, but it would be cool if you could do that without having the overhead of the the main process multiple times. So that would be a good example of multiple windows.

Lea:

Right?

Dominic:

Okay. Okay. Wait. Wait. Wait.

Dominic:

Wait. I I think I I am under I understand what you're saying. Okay. So because let's face it. We we we kind of add the the ability to create multiple windows.

Dominic:

We we are we are in a web page. Right? Mhmm. So that was not the problem. The problem was because, like you were saying, the the main thread being blocked by all all the, you know, the system events and whatnot.

Dominic:

So you the fact of having a a totally different window, which is separated from that, could be beneficial. Is that is that what I'm hearing?

Lea:

It's more that you you have let's say you've got a bit of overhead for each program. So, like, let's say the Go runtime. Right? So you've got the Go runtime. That's gonna be in memory.

Lea:

You've got, you know, a bunch of other stuff that's gonna be in memory, taking up space. And then you have the front end, which you wanna just use for rendering. Like, if you wanna have maybe two two Markdown files up on your screen at once, and you might want them in two separate windows, and you may wanna be able to copy and paste between them, you may wanna be able to interact between them in for whatever reason. You know, you might wanna sync the status of some external resource across all of the windows whilst you're working. Yeah.

Lea:

So if you add them all as, like, individual programs, that becomes a lot harder. Right? But if you've got an application that is much more integrated, like like, you could integrate multiple markdown files, like, you know, you could display multiple markdown files in a markdown file viewer. You wouldn't have to have that overhead per process. Does that make sense?

Lea:

Yeah. You'd only have, like, the one overhead and the calls for, you know, rendering the markdown, they're gonna be shared across all of those windows.

Morten:

Nice. So you could essentially so you you if you can turn it into if I'm saying correctly, you turn it into a server, so you can you can essentially enable multi multi editing if you take if you go with the markdown examples, so multiple people could work on the same markdown file in multiple windows and it will all be synced across devices if they have the the server running?

Lea:

That's one way that's one way you could do it. Yeah. But it would work that way on the desktop app as well. Nice. Something I probably should have told you earlier, I'm supporting mobile for v three.

Dominic:

What?

Lea:

Yeah. Okay.

Dominic:

Wait a minute. We we have six minutes left, and you you dropped that? That that that is crazy.

Lea:

Oh, well, you know yeah. One of the one of the big that was one of the big asks was, can we get this on mobile? So can we get it on server? Can we it on mobile? So I decided, yeah.

Lea:

Okay. I'll hold off the release and just, like, get it all done. So the mobile version works. It's for iOS and Android. And the killer feature is you don't change anything about your program.

Lea:

Nothing. Like, you can just compile your desktop app, and it will run on your mobile.

Dominic:

That is crazy. Okay. So you're you're probably using the the the native web view of of those platforms, and and it just works?

Lea:

Absolutely.

Dominic:

Wow. Do we have access to, I don't know, a couple of small, you know, mobile device feature? I I I don't know what. I'm I'm not a mobile developer, but, you know, is is the the camera accessible or things like that? Since it's web, I guess I guess it's it's it's probably there.

Lea:

You know, most of what's on the on the devices that I'm just gonna bring up a side by side.

Dominic:

That is crazy.

Lea:

Yeah. So bind bindings works, events works, dialogues work. You've got all of the system stuff, so, like, clipboard, device info, screen metrics. You'll have keep awake, torch, brightness, biometrics, local notifications, secure storage, haptics, geolocation, accelerometer, proximity, text to speech. Yeah.

Lea:

Wow. So I've got a kitchen sink example in in the repository right now. And, yeah, you can just you can just run that. I've got it installed on my on my iPhone, and it's wild. Yeah.

Lea:

It's absolutely wild.

Dominic:

Okay. Well, the yeah. This this is exciting. Okay. Just just before we we close, what what do I need to put that into my into my phone while I'm developing?

Dominic:

Is is there a quick way for me to, I don't know, to to just without the full package, I I I would hope. Is is there a way for me to test my application?

Lea:

So you can remember the task files I mentioned? Yep. So part of the default task files, you know, you can just do I think it's like Wails three iOS build will just build you the app. If you do ios run, it will run-in the simulator. So you need to install x code to run that.

Lea:

And if you do package, then it will install it on your connected iPhone. So part of that setup wizard that I mentioned earlier is to, like, get your certificates and everything in place, and it will tell you what you need to install and the commands to install it as well. So yeah. And yeah. That's that's that's how I got my test up on my phone.

Lea:

Wow. Nice. It was gonna be experimental, but I kinda went a bit mad with it and decided, you know what? Let's just release it. Like, if there's bugs, there's bugs.

Lea:

But

Morten:

yeah. How how how everything goes. We're just gonna create an MVP and then Yeah. Stop. Yeah.

Morten:

Nice.

Dominic:

I'm I'm I'm I'm a little bit excited now. Maybe maybe maybe that will be bad for my SaaS because, wow, I I I I kind of want to build now this this this thing. And now that it's mobile as well, it's it's crazy. Wow.

Lea:

Yeah. Well, let me know what issue you had with your older computer. Just contact me offline, and I'll see if I can help you with that.

Dominic:

Yeah. I will will I will do that because I'm I'm using an old Ubuntu via WSL, so I think the library are are not supported or or things like that. But now now that you're saying about the Docker, I I was I was not I was not going the Docker way. So I I don't know what I was what I was doing, to be frank.

Lea:

So Do do any of do any of us, Dom?

Dominic:

Well, it's it's because sometimes sometimes I just want to test something and I I you know, frankly, I I did not really properly read the documentation. So yeah. You know how it is.

Lea:

Yeah. I know. That means it's a documentation fail. That's what I always say to people. Tell me tell me how to make the docs better.

Dominic:

No. It's good. Oh, Lydia, that was that was so interesting. Now I I I I just want to to to go to go test all all of this. So by the time that this episode is released, probably the v three will will be live from what you were saying.

Dominic:

So if if people want to test but but, you know, it's already possible to test the v three anyway.

Lea:

It is. Yep. Absolutely. You can just install the the latest actually, just go to v3.wails.io, and from there, you'll have all of the instructions. Nice.

Lea:

Perfect. Perfect. All right.

Morten:

And this should probably be out when we release this episode. So

Lea:

I hope so. No pressure. But yes. No pressure.

Dominic:

It's a promise. You heard. No. No. But alright.

Dominic:

So any any closing closing comment before we wrap up?

Lea:

No. Not really. Just, you know, it's it's such a big project. It's, you know, it's managed to get to, what, 35,000 stars, which I never ever thought would happen. The the support of people has just been phenomenal.

Lea:

I mean, 35,000 sounds like really a lot, but there's a there's a claud. Md file that has, like, a 180,000 stars on GitHub. So I think these days, you know, we live in wild times. Right? But, yeah, like, I just really appreciate all of the support that that everybody's shown.

Lea:

And and we do have some major sponsors as well, which is cool. Yeah. It's used in Hightail, like, the the game is the launcher, which is pretty wild. It's, like, got a million installs. So, yeah, I think if anybody out there is listening and has this idea for for a project, don't, you know, don't let anything hold you back, and just read up on how to be an open source maintainer involuntarily.

Dominic:

Yeah. Yeah. It's pretty nice. Well, you know, other other than than the stars, I think I'm I'm seeing whales being recommended all of the time, especially on on Reddit and whatnot. So, I mean, it's it's you you you built you built some something very great, you you and the the community.

Dominic:

Thank you thank you for that. It's a it's a great project.

Lea:

No. Thank you. Thank you. Yeah. Even Claude knows how to build Wails apps now, so that's wild.

Dominic:

Alright. Alright. So thank thanks for for joining us today, and we we we will try. Let let's all try the v three, and we will we will send you the comment the gentle comment in in the GitHub issues if anything happened.

Lea:

Brilliant. It's been it's been so much fun. I think it's I think it's time I go to bed.

Dominic:

Alright. Thank you.

Morten:

Thank you, man. Yeah.

Lea:

Cheers, guys. Bye. Bye.

Creators and Guests

Dominic St-Pierre
Host
Dominic St-Pierre
Go system builder - entrepreneur. I've been writing software systems since 2001. I love SaaS, building since 2008.
Morten Vistisen
Host
Morten Vistisen
Contract Full-Stack Developer at mbv labs.
Lea Anthony
Guest
Lea Anthony
Creator of Wails: https://wails.io. Co-creator of xbar: https://getxbar.com. Hardcore Gopher.
092: Your Wails app... on mobile? With Lea Anthony
Broadcast by