Daniel: "Hey, welcome to Waiting for Review, a show about the majestic indie developer life. Join our scintillating hosts, Dave and Daniel, and let's hear about a tiny slice of their thrilling lives. Dave, hi, nice to hear you." Dave: "Hello Daniel, I can never quite get over that intro. That's great stuff." Daniel: "Hahaha" Dave: "Ah." Daniel: "I have done the sports and there's a German word for everything, right? And there's a German word that translates roughly to muscle hangover. So I have a muscle hangover today." ara Dave: "Okay. Right, what is that in German?" Daniel: "Muscle kata. And kata means male cat. But in this context, context is actually another root that's katar. And that is hangover, but also just general malaise basically." Dave: "Ah. Mm-hmm. Hehe. Yep, yep, fair. So I think that sounds like what you've got the delayed onset muscle something, doms. Is it about a day or two afterwards? Yeah, yeah, I know it well. Ah, well, no heavy lifting to do on this show, we can just sit here and talk. So hopefully that's all good for you. I..." Daniel: "It is, it is." Dave: "I can't say that I've been doing the sports, unfortunately. But I'm kind of getting back to it after a little while of not really being able to exercise and stuff, so, you know, maybe I will have... How did you say it? What's the phrase? Yeah, muscular kata. Yeah, maybe that. Cool. I'll, no doubt. Yeah, I'll message you and I'll just go, I've got it. It's happened." colour Daniel: "A muscle hangover? Muscle canter? Yeah, that's pretty good. Keep us posted. Hehehehehehe" Dave: "Or rather I'll be going, I've got it. I ache. Um, yeah, but, uh, ah, Daniel, I want to talk to you about a approach to building my apps that has kind of been bubbling away in the back of my brain for the last month or two, and I'm starting to do it." Daniel: "Mm. Is it that you're switching your keyboard to like weird layouts like Dvorak or whatever?" Dave: "No, no, not yet. Always leave that option on the table. Okay. So I had no idea that this already existed as a concept as I started laying it out. I mean, I've kind of realised that there would be something similar out there, but let me walk you through it. I sat down and thought, Hmm, okay. I've got this laundry list of small utility apps and ideas that I've been wanting to build for ages." Daniel: "Okay, then what is it?" Dave: "I think a lot of indie devs end up with this sort of back catalog of ideas and failed experiments and that sort of thing. And I noticed that within all of these, there's a lot of commonalities, right? So if I think about the design for each of these app ideas, they've usually got a setting screen. They've usually got a paywall somewhere in there. an intro screen, a welcome to the app. And I'm also doing a lot of things where I'm sort of setting up colour schemes and that sort of thing as well, so that people can change the colours that the app uses and theme it nicely. So there's a lot of shared stuff. And what happens when I make a new project is I tend to, you know, clone the last one, strip everything out, take what I need." Daniel: "Yeah, I get that." Dave: "And you end up with iterations of things, right? So I've got the version of, um, of colour theming that I came up with a year ago, um, in one app, and then I've got the slightly updated version with better this stat and the other for Swift UI, um, in a more recent app. And that annoys me, right? It sort of feels like I've got this kind of, uh, evolution of things that isn't very controlled." Daniel: "Right. I mean, we have computers. Why can't we just like clone stuff instead of like having this very messy way of, of moving stuff around." Dave: "Yeah. And I think it's ideal to do that when you're not really sure what the thing needs to be, right? You know, copying the thing from the last project that worked and make it work in the new context. But I was sort of staring down this list of ideas and it's probably good for me to mind back just slightly and explain why I'm even looking at this list of ideas and what's going on. And so I've had a bit of a realization in the last month or so that I am at my best as an indie developer when I am working with video. Okay, that's where I started with Govj. I kind of worked with video a little bit with the video to audio converter. I've had various things over the years where I've sort of played in that area and it's always where I have the most fun. So as much as I enjoyed making my Fettyverse app and working on to SDK and that side of stuff, actually, I have more fun when I am working with video. OK, so that sort of led me down this path. And I started going, OK, well, there was this idea for this, this type of video editor, this idea for this effects app, blah, blah. And then suddenly I'm looking at a 10, 12 app list and going, really love to build them. So commonalities, lots of apps sharing lots of ideas and lots of similar bits. And that led me to an idea of, OK, so I should put these things into Swift packages. And then I can share them between the apps. And the concept I dubbed for this was Lego apps, right? It sort of becomes like I'm making my own Lego blocks that I can just go, boom, you've got a setting screen and you've got a setting screen. And, you know, yeah." Daniel: "Hehehe Awesome." Dave: "And so that's what I've been up to here and there over the last few weeks. When I've had some time, I've been building out these packages and it's going to be that I've got a few things going on in non-dev life outside of work as it were that are going to derail me. We're about to be moving house, I think over the next over the next month. But that's one side. I am pulling all of this together so that I can then make a new app. Um, and it will probably be later this year that then gets released. Um, but what it will also then be is a case for me to, um, rip out the old versions of these components in the existing apps and bring everything to the same standard. Um, but the concept here is yeah, Lego apps has been the concept I landed on and that each thing that I abstract. has to be relatively self-contained in what it does. And that I don't get too caught up with all the different permutations that may come up to vary it between apps. So they're all going to get a lot of very similar things. You know, like I'll settle on one version of the paywall to begin with that every app has, for example. And it's just, you know, it'll be a bit with a description and then the options listed below and blah, all the bits it needs. for a paywall, but I'm not going to try and make them too bespoke. Yep, it will just be fairly simple, just does what it needs to do. And then I'll get them to a standard and we'll see how that goes. And, you know, I can iterate from there. So in theory, I think it's useful. In practice, it is a road towards yak shaving, as it were. Yeah." Daniel: "Mm-hmm. Oh yeah." Dave: "And I've got to be very careful about tying that line because you can feel really productive while not really getting anywhere with doing this sort of stuff." Daniel: "Yeah, because you can optimize prematurely and just optimize and optimize and never really go anywhere with your main project." Dave: "Exactly. So I'm trying to sort of toe that line and bring in things that I've already written and then get them to a standard where it's like, yep, this is this is my view for this for all the apps and to move on rather than going, oh, but this app wants it like that. This app wants it like this. Right. And then I discovered a blog post on Swift with Majeed.com. Um, where in on the 12th of January last year, he talks about micro apps architecture in Swift. Um, and I'll link this in the show notes, but basically he lays out exactly what I've just been talking about in a sense. Um, and it's a, um, and I, yeah, there's a whole bunch of articles. He also links, um, somebody else's posts that's over on increment.com. And again, I'll pull all that together on the show notes, people can go and have a look. Um, and I'm doing something very similar to what they're laying out here, right? And it's about, you know, trying to set boundaries around the modules that you're building so that they make sense. Um, but also not driving yourself mad in the process and sort of making sure that you're, you know, you're being sensible with it. So yeah. Um, It's like I said, not a new idea, but for me, the idea of like, oh, I should do this and then reapply this to, to all of my apps. That is new. Um, so yeah." Daniel: "Yeah, so what I, sorry, what I really like about this idea is you're not just pulling random components from GitHub and just assembling them into a Frankenstein style app. You're building your own components so all of them will have your style and especially because you're indie. Even if you have five apps and they have the same or a very similar pay screen or paywall, it will be your kind of style in those. Look at, I don't know, tab bots." Dave: "Mm-hmm. Yes." Daniel: "They have a certain style in all of their apps and that evolved over time, of course, but still, it's still their style. And with that method, you can kind of do that yourself. And I have a few thoughts about organizing and principles that you probably need to adhere to because I kind of do a similar thing. Like I use a lot of Swift packages in my development and I love them even though I hate them, but mostly I love them. But what I hate is like, hate is too strong a word." Dave: "They do. Yep. Hehehe" Daniel: "Anyway, so in software engineering with uppercase S and uppercase E world, this is the principle of low coupling, which is like your components should have as little surface area and interconnectedness as possible so you can reuse them. So this is really important because then you can reuse them. And this is true for Swift packages with, for example, a pay screen. but also for example for classes in let's say the API for a medium sized analytics provider that for example has a class that is a job runner and a separate class that is like the database query, querier." Dave: "Yes." Daniel: "So yeah, so one of the principles that I found is that, like really, like don't think too much about, I have to make everything a Swift package. Because you like, ideally everything is a Swift package and I have like, they have a lot of advantages and we can totally talk about those because I love Swift packages. But like sometimes maybe just like, encapsulating stuff in a class, especially if it's not user interface or stuff." Dave: "Yes. Mm-hmm." Daniel: "is maybe the better way. Just as, like, I think the way to approach all of these LEGO apps is think about, oh, how can I reuse this later? But don't prematurely optimize for it. Don't be like, oh, yeah, later I will be able to add this, so I will edit right now. Don't edit right now. Just don't block that avenue for yourself." Dave: "Yep. Yes. I agree. And there's some other principles with that as well. I remember coming across the idea of like, to avoid early optimization, you set a principle like a class or an area of functionality has to be copied three times before you turn it into a package, for example. And I think there's some truth to that because then that lets you avoid getting too caught up in the permutations that it needs to have. different contexts and then you can take a look at those two or three and go ah this is the shared area not that and you can slice along those boundaries yeah" Daniel: "Right. Yeah, that's pretty good. And I think you also kind of learn as you go along, like, oh yeah, this is probably a good component to kind of extract into its own package or whatever." Dave: "Mm-hmm. Yeah. And I can tell you actually, I kind of gave it this thought as I was pulling everything together to, I've literally written like a Lego app manifesto for myself that sort of lays out the direction, right? And if I look at the key packages that I sort of identified up front that I want to build that will help enable these apps, I've got one about themes. So about setting the colours for the app. and setting up an observable object that then is linked to modifiers and all the rest of it to set colours. So that's one. There's the settings. So the settings screen is relatively generic between each app. You know, I'm going to want something where you can link the paywall, something where you can say what the app is about or link any help, the website and all of that. That's generic enough. And I've done that enough in enough apps now to know what the generic bits are. Um, and then I've got one for a paywall. Um, I've got a really nice little video trimmer object in my video to audio app that shows the, um, it shows the, the. Waveform effectively for the audio and it shows the, um, thumbnails. for the video together. So you can get a view of the audio and the video at the same time as you edit. And it's got sliders on either side. So I wanna box that into its own component because some of these video apps I've got ideas for, they all have that. They all need to trim video. Yeah, so that's another one. And then finally, all of my apps have a more apps screen in the settings screen. And I wanna abstract that. Um, because I've got some ideas there just in terms of I want to be able to hit a button from this, this little panel that shows other apps that are, that are mine. Um, and I want it to boot up like not quite an app store style, um, screen, but something similar to that to show them off a bit better." Daniel: "Yeah, that sounds very cool actually. Like just some cross promotion basically." Dave: "Yeah. Mm-hmm. And this is all about me leaning into the idea of my domain and the name that I run under for my indie apps now, Lightbeam apps. And bringing this all together, it means I'm thinking about a look and feel for a Lightbeam app, as it were. Like if you have one and use another, this similarity will mean you'll feel pretty at home with them. And... I'm hoping it then becomes a marker of like, oh cool, I like that app. I'm going to like this app when I check it out. Um, so we'll see, but that, that's the, that's the thought process, if you like, behind this sort of Lego apps, uh, micro app, uh, architecture is to try and just sort of bring it all together." Daniel: "Yeah, some more thoughts on this. I think you can slice things too thinly and I think you should avoid that. And I'm not saying this to criticize you, I'm just saying it's like thinking out loud what are my principles for those things, of course. Like if things are too tiny, then they're hard to control and they're hard to work with, but if they're just the right amount of tiny, then they're" Dave: "Yes. Yep. Yes." Daniel: "then they're good because they're easy to move around and easy to use. And yeah, if you have too many of these, too many Swift packages, for example, it gets kind of frustrating because either you have them locally in your file system, but then it's like hard to work with them with Git, or you have them just as Swift packages referenced, but then every time you need to, you wanna change the code, you kind of gotta switch it to a different project and stuff like that." Dave: "Mm-hmm. Yes. Yeah." Daniel: "So how do you work with those, by the way? Do we have a preferred method here?" Dave: "Yeah, that's a good question. So I learned a bunch of this with, with the two SDK development last year and kind of what I preferred, but yeah. My plan for this is that each app will bring the Swift package in directly out of the repo using the versioning there. And then whichever one is in development, I can override that while I'm working on it by just pulling in the local package instead and make changes there. So that will let me edit it with the app. And that will probably make the most sense. I'm not typically developing two apps at the same time. Yeah, I'm usually focused on one for a day. And so it's not really that hard for me to set the packages from the local package and override the one from Git. And then by doing that, I can do that, get the dev done and then push a version. And then it's up to me as to when I want to pull the other ones up to date with it. Um, but that that's, that's kind of the base. Another thing that I'm probably going to do, and in fact, I've already been laying it out as I make these packages is I've got a test step that links them all locally. And then from there." Daniel: "Mm-hmm. That's good work on them there." Dave: "Yeah, exactly. So if I don't want to bother overriding the local, overriding the Git version with a local version of the package, I can just use the test app that is using only local versions of the packages. Um, and that again, lets me then, you know, dev to the side on that, push up the version, and then I can pull it back down, um, into the other projects. So yeah. Yeah." Daniel: "Yeah, that makes a lot of sense actually. For me, I usually like most of the Swift packages I work with are not Swift UI and they're not UI at all. So what, so I can usually, and like I can, like I used to do it the way you just described, where I would temporarily link the local version in my package.swift and then work on the code inside the," Dave: "Yeah. Yep." Daniel: "context of my project. And then at the end, I would make a release and then tag it on Git and whatever. Turns out there was too much friction for me and it kind of got messy. So what I do now is these packages, because they're usually not UI, I can really, really unit test them. So what I usually do is I write a unit test or I write the minimum amount of code that I need for the thing to be even failing a test. just like the API basically. And then I write a unit test, like describing everything that I expect the thing to do once I integrate it into the main project. And then I can just work on that. And because the package is kind of small, it runs the unit test really, really quickly. And that's just a huge, huge boon. Only thing I'm missing really is, I've been in Python world for a bit now, and there you have automatic test runners, where like for..." Dave: "Yes." Daniel: "The like reasonably large in just API, for example, might all tests run in 0.21 seconds. So basically every time a file gets saved, it just runs all the tests immediately. And that is really cool. I wish I wish something like that for Swift existed." Dave: "Ah, that instant feedback at that point, that's great. And I'm just having on that note, a lot of my indie projects don't have a unit test or don't have very many. And I've never been very happy with that, right? And it's a trade off, you know, you don't want to spend all day writing tests before you even know whether the app's got a market is kind of been the vibe I've had, but. Also, what I have done now, for example, if I look at my theme package, there's a bunch of things that is supposed to do. And I have got a few tests against that now and actually setting it as a package and isolating it has then made it easier to think about what the tests need to be." Daniel: "Oh yeah, that really helps." Dave: "Hmm. So, you know, I don't think I'm going to be, um, a born again, TDD developer overnight with this. Um, but I do think I will get more test coverage out of myself on an indie basis. I mean, there's a very different, big difference between indie dev Dave and, uh, day job dev Dave in terms of testing actually. Um, but I think that's, um," Daniel: "I'm sorry. Mm-hmm. Yeah." Dave: "and that's just because of my approach right I want to I want to just I've got limited time when I'm doing indie projects and I just want to have a bit of fun and tests have never felt like fun." Daniel: "Yeah, also, also if your stuff breaks, it's not as important most of the time and people will be more forgiving because you're small. And I feel like for me, it's kind of the same way. And it turns out like my unwritten test policy seems to be like, I've never really thought about this before, but it seems to be do not test UI ever because it is usually" Dave: "Exactly. Exactly. Mm-hmm." Daniel: "because usually in our kinds of projects, the UI changes a lot and UI testing is just more work. But do test a lot of the underlying building blocks and we're back at the Lego metaphor at that point, especially APIs and stuff like that. And APIs, I don't mean like web APIs, I just meant like the interfaces that our building blocks are using to talk with each other. Those are really good targets for testing, whether that's..." Dave: "Yes. Yes. Yeah." Daniel: "some like even if you use a UI framework at that point, that's totally fair. But like I won't test if a button actually buttons. Like I'm just gonna assume I will know if the button stops buttoning." Dave: "Exactly. Yes, yes. And you know, if that happens as well, you've got good routes for your user feedback to come straight back to you and that side of stuff as well. Like, I mean, that's the worst case scenario is the user catches it before you do. But as long as you've got that route back, that is also another, another backstop in all of this, right? It's like, yeah. And a lot of what we build, you know, if the button doesn't button, well, you're going to notice that as you're trying to play with the thing you've just built." Daniel: "Right. And I'm not saying this is the correct approach for everyone. I'm just saying this is the approach that I use because I am like my balance between wanting to get out new features and making everything very stable. That dial is very much towards new features except on the lower building blocks where I want way more stability." Dave: "So... No. Yes. That makes a lot of sense. And I think we just got to caveat this because there's a variety of different listeners to this show. And I wouldn't want anybody to go, ah, Dave and then you'll say, don't bother with tests that that's, that's not the message. The message is. But you know, when, when that season developer turns around and looks and goes, it depends, this is one of those. It depends scenarios, right? You want to make sure you're." Daniel: "No, that's exactly the message. No one should ever test anything." Dave: "your testing standard matches what you're trying to achieve and the time that you've got available to you to do so. But I want to come back just quickly to this whole thing. And what I'm seeing here with all of this, because one of the other things is, is that I'm planning to automate the build of the apps eventually as well. and to use probably GitHub actions to kick a bunch of stuff off and that side of things. And we'll see how it goes. I'll do this with the first app that uses these components and give it a good go." Daniel: "I'm such a big fan of GitHub actions. Like I'm, yeah, I use it so, so much." Dave: "But the plan here, if you like, is that I want to have it so automated that if I push a new version of one of these packages up, something builds, something tests, and something gives me early feedback if it's broken one of the other apps. And I want to automate that away so that I don't create this sort of stack for myself where it's like I make this change, I realize that it's then, you know, absolutely broken. Um, something that's already out there and I don't realize until the next time I go and try and dev the project. Like I actually want to know as soon as the, the package has been updated, that all of the things that depend on it are building. Okay. Yeah. And what I figure with that, what I'd like to do is get to a stage where, um, I am then pushing builds up to the app store off the back of that. Like if everything's all good, I've got to build an aversion. Um," Daniel: "Totally." Dave: "ready to go if I want to over there." Daniel: "You might even be able to use DependerBot for that. Do you know what DependerBot?" Dave: "No I do not." Daniel: "I think this is from the JavaScript world, especially where your project will have thousands of dependencies. And it is a GitHub add-on. And I think it's been bought by GitHub, but I'm not 100% sure. It's a GitHub add-on that you add to your GitHub and it gets like a configuration file and it reads your package file and it supports various languages and then just tries to find the newest version for every package in there. and then runs your GitHub actions to see if your tests run. And if everything comes back green, it will just merge the thing in. And then if the merge in might also trigger, of course, a push to the app store or whatever, or in my case, for example, a deployment to the server." Dave: "Ah, yes, yes. That's perfect. And actually, I am using this in day job. I think we've got this set up for the security warnings that I think it can do. If I remember rightly, set up alerts. Yeah." Daniel: "Yeah, that's pretty cool. Yeah, especially for the web front and like you get like five, six pull requests that are automatically like opened, tested, and then closed and merged every day because like just things are moving fast and this is really helpful to stay abreast of any security vulnerabilities." Dave: "Yep. So yeah, that looks like something I should use when this is all set up. So this is all a work in progress. And I don't want to get too caught up in the idea of making this perfect automated stack before I'm actually releasing an app. But I figure that taking a little bit of time now so that instead of just copy pasting from the last project, I've actually made something solid for this. I figured by investing that time that I will see the dividends pay back over the next year." Daniel: "Yeah, I can totally see that. Especially if you do the thing where, like don't do all the work around the actual work right now. Like just do a little bit of, like see if you can package the rise, but don't build, yeah, as you said, like don't build the whole push to, like everything gets tested and then push to the app store and everything. Like don't do that now. Just do that in bursts kinda. When you work on something, then also do some infrastructure work, but not all the time." Dave: "and uh Exactly. And my approach for this sort of thing generally is this, right, is a sense of do it the hard way or the fiddly way or the manual way first and feel that pain a few times so then you know exactly what you want to do to relieve that pain." Daniel: "Mm-hmm. Exactly. And by then you also like find the worst, like the worst problems and can try to fix them or work around them and whatever." Dave: "Mm hmm. Exactly, exactly. So, yeah, don't worry, I'm not. This is it. I'm trying not to go off the deep end and just start working on my dev tooling rather than on my apps. But my hope here is for a few things. And what I've got with Govj is I've got a regular user base of visual artists. I've got people subscribed. I'm now doing really quite well with the app in terms of a small project. Um, uh, just to put a bit of a view on that, it's making $150 recurring revenue each month, um, which for something I do occasionally on weekends and evenings and stuff feels like a good, a good trade. Um, and I want to be doing more and making more in that sense. And some of the apps I've got definitely will appeal to that audience. So one of the things I want to make over the next six months or so, um, is a generative video synth basically. Uh, so to give a bit of context, if you've ever played with shader toy, um, and, and the, the visuals that can be live coded in the browser on there, um," Daniel: "Hehehehe" Dave: "I want to bring that sort of stuff into Go VJ. And what has occurred to me is it's actually potentially an app in its own right. And so with that comes a bit of a dilemma. OK, if I make it an app in its own right, how do my Go VJ users get the benefits of it? How does how do they get to bring that into the video mixing app that I've got there? Right now we've got two separate apps. And what I figure is, because I wanna make the Generative Effects part of one of these packages, so they can then be shared between the two. And it occurred to me that what I could do with this feature set in Go VJ is if you've got the other app installed, then you are able to use the Generative Effects in Go VJ." Daniel: "Mm-hmm." Dave: "Okay. And the mechanism for this will be when you go to load a piece of media into one of the video channels, you've got the demo content the app comes with, you've got your own content you've loaded, and there's another tab ready and waiting to sort of put the generative stuff in there. So when you go to that screen, there'll be probably four or five different ones that come with GoVJ. And then a button that sort of goes, do you want to load more? Yep. And that will be a call to action to then go and install the other app. And then when you, yeah. And then you go to the other app, you, um, import shaders and set things up and make it work as you want to work it. And you save these things as specific presets. And I will use a shared app container between the two to share those presets so that go VJ can then read them." Daniel: "Oh yeah, that's all you need." Dave: "and you can load them and use them from there. So it then becomes a thing of. If you've got both, it's better is what I'm trying to create." Daniel: "Yeah, and you have like those, I mean, those are pretty big Lego pieces, but still you have the two apps that are like slightly different target audiences and they enhance each other. So that's awesome." Dave: "Yes, exactly. And that's the idea there. And then that lets me do other things as well. Like I can make very specific features on the generator side in terms of how you edit them, or play with them, or set them up. And then on the Govj side, you're working with them finished. And you can just control them as a thing with parameters that then does nice motion graphic stuff. So that's some of the idea in this, as well as that this will provide a bit of a vehicle for doing that. Because Govj's video engine is already a Swift package, actually. It's actually an Xcode project that I've brought in via a workspace for Govj. That will take me all of probably an hour to just pull things out and turn it into a Swift package. So, you know, some of this is sort of it's already ready and waiting in terms of how I bring it together. Yeah, so that's that that's the idea with generators." Daniel: "Fantastic, I love it." Dave: "but I have talked loads about Govj and Lego apps and I am curious about a few things on your side, Daniel. So how is your, I'll go on." Daniel: "Oh, yeah, sorry. I have actually a good example of the LEGO strategy at work. But I kind of talked about TelemetryDex web SDK last time already. So it turns out that if I just give our users a separate way or our customers a separate way of gathering usage data with the new web SDK." Dave: "Mm-hmm." Daniel: "And you put that in and what I know added is just a separate overview screen that just shows you instead of your app versions that don't make sense for a website. If you have a website, you can switch it to showing the URLs and the sources and the referrals and the countries and stuff like that. And it turns out because we have that and but we already have like a charting engine that is that can auto update. We already have the query editor and the inside editor and stuff like that. We already have the dashboards, we already have the funnels and the EB testing, and suddenly you can all do this all for your website data. And so with a comparably minimal amount of work, we or I kind of stumbled into suddenly being able to offer a pretty decent web analytics tool. So I'm really happy about that, actually. I was meeting a customer, and they kind of misunderstood what we do. And they said apps, they were making apps, but they were making websites. They had one specific large website. And during that meeting, I kind of just shared them. It was a Zoom meeting. And I just shared with them the." Dave: "Ha ha ha! Mm-hmm." Daniel: "the overview screen for the telemetry deck website that is now also powered by the Web SDK. And I was like, yeah, is this what you need? Like here we have the sources and where people are coming into the site and where people are leaving the site and stuff like that. And they're like, yeah, this is exactly what we need. They're like, nice. Oh, this is good." Dave: "Yeah. Hehehehe Oh, so that's where it then becomes an enabler because you've got all these, these things ready to go just in a different combination." Daniel: "Right. Right. You just recombine all the existing parts, add one more, and then it's a new thing that is still very stylistically connected to the old thing." Dave: "That's awesome. That's really awesome. So what if you stood up there, then you've got a whole web analytics experience building with all of this." Daniel: "So yeah, that's really nice. Yeah, basically. I mean, of course, there's advanced features and stuff like that. For example, this doesn't have integration with the Google Search Console. But I mean, who needs the Google? OK, you kind of do. You kind of do need the Google Search Console. But you can have that open in a separate tab. But for example, if I look at various other privacy-focused analytics tools, which are awesome and I love," Dave: "Mm-hmm. Hehehehe" Daniel: "What many of them don't have is just like, oh yeah, just make a new dashboard, add a few insights, and then just 3D query, like 3D write your queries with a visual editor. I haven't seen that, and that's actually really, really helpful. We've run a few ads. Like the ad campaign for the Swift package index is still running, and the ad campaign that we're running on hacking with Swift has now ended. And so I just added a dashboard for both of those." Dave: "Yep." Daniel: "And just have a few things where I just see data about these campaigns because I'm like, okay, how did this actually go? Uh, spoiler, mediocre, which is, which, um, is not the fault of either hacking with Swift or the Swift package index. Both of these are amazing people whom I love. Um, the, the just turns out that they are bringing visitors to our website, but then" Dave: "Okay. Mm-hmm." Daniel: "they're not really registering, which is a bummer. So hacking with Swift, we have, as count of today, at 524 unique visitors have visited the website from the hacking with Swift link. So that's pretty cool, that's pretty decent. Out of those, four have actually signed up for the product. So that's less than 1%. And..." Dave: "Yeah. Okay. Yep. Oof. Okay. Yes." Daniel: "I'd like to reach ideally like 2% to 3% at least. So I don't know yet why that is. But this is now my next step. The next step is just figuring that out. Obviously, the landing page needs some work. I think it looks pretty cool. But maybe one of two things that I really want to do is talk a bit more about the features that we've added. Because I've wrote all those." Dave: "Mm-hmm." Daniel: "all that copy, I wrote that a year ago, maybe. And in the meantime, we've had, we now have web analytics, of course. We have funnels, we have A-B testing, we have various other stuff. So mentioning that would be cool, I guess. And I also think maybe I wanna have some sub landing pages, especially for Swift developers, and maybe now also for web developers. And the third thing is I wanna like even bigger," Dave: "Yes, definitely." Daniel: "call to action button that's just on the front page, like a huge throbbing orange button that's just like, says like, now, now here, click this. And I think that the main hero image is also a bit boring. And so maybe if we, if we have like a bit more going on in that main hero image, that will also be a nice thing. So I'm actually gonna, I think I'm gonna run some Google ads." Dave: "Mm-hmm. Yep. Yeah." Daniel: "If that is possible right now, that is not possible because Google says we're malware. Well, not telemetry. Dag is malware, but Google is saying the telemetry website is malware. Um, I've appealed. Let's see what the appeal brings. Um, I think I have an idea why that is. Uh, anyway, I'm, I'm getting ahead of myself. So, um, so yeah, I want to run, um, like tiny, tiny amount of ads just enough to, to send P to, to have the same ad." Dave: "Oh dear. Oh dear. Okay, that's interesting. Yep." Daniel: "send people to either version A of a landing page or version B. And so I can actually use our A-B testing tools to find out which is better and then just incrementally improve that over time." Dave: "Yeah. That's awesome. And I think what you're, like you say, you're much further along now than when you first wrote some of this copy. It's definitely a good idea to go back and revisit that. I also think that you've probably collected with new customers over the last year, you've perhaps got the opportunity to bring in some more testimonials and kind of social proof from people as well. So." Daniel: "Oh yeah. Wait, do you think we should have more on the front page?" Dave: "Um, I think it's just a case of just checking that stuff calls out some of the new features more than anything else. Yeah. Um, so then it links, you know, it's not just like, Oh, this feature is shiny and it's cool, but it's also. I use this feature. My name is Dave or whatever. Right. I'm happy to personally give a testimonial, but, um, you know, you probably want to find, find people who, um," Daniel: "All right. Oh yeah, that's a good point actually. Mm-hmm. Haha" Dave: "representing your target customer base as much as possible as well. But yeah, and get their testimonials saying, I use feature Y and it's, it's brilliant, you know, that's, that sort of stuff to just really hammer it home. Like this is not just a cool set of features and a cool product, but it's being used by real people, which it is, you know, and this is the value they're getting out of that. So that will tie it all together. Um, and I've not been by your page for a little while, so excuse me if you're like Dave, I've got all this, what are you on about? Um, but" Daniel: "No, no, that's like super helpful feedback, I think. No, the only thing I was asking, because we do have like, lots of more, lots, lots more testimonials, they're just not on the front page because I don't want to have like 50 testimonials there. But if you scroll all the way down to the footer menu, that actually has a link to more testimonials because I've been collecting those because every time someone says something really nice about telemetry deck, I ask them, Hey, can I put that on the website?" Dave: "Mm-hmm. Yeah. And that's the thing, right? So you can make. Sorry. Brilliant. And what I was going to say there is that just as you're tweaking potentially the page to A, B, test it and make it more suitable for certain audiences, those testimonials should also be reflective of those audiences. If you've got a Swift dev version of it, I want to see a Swift developer there, potentially somebody I know from the community, who then validates that this is a cool product and is useful for me. Yeah. I mean, this is." Daniel: "Oh yeah, that's a good idea." Dave: "We're getting into the weeds on this, but you've got all the components." Daniel: "Yeah. Like we have like there's a few apps that use telemetry deck where I'm like, oh, I'm so super proud that these people use telemetry deck. Like I'm like, wow, you are my idol, or you made an app that is like so cool. And then I use very much daily and then like, oh yeah, and they are using telemetry deck. How cool is that?" Dave: "Yep. That's awesome. And if you can call that out, if they're OK with you doing so, then that's fantastic, right? Again, and it's not all about this sort of stuff, but it is about when somebody comes to you brand new and they know nothing about what you're doing or very, very little, if they can see bits of themselves in what you're showing them, then again, it gives them that indication of, I want to give this a go." Daniel: "Oh yeah." Dave: "to hasten to add just in terms of people listening to us talking about this. I think this is a actually it's marketing. Um, but it is not too creepy, right? You're talking about, you want people to be able to see the value of the thing for them. Um, and then what does it cost? It costs them just in time to go and install it, to, to set it up and try, try your, your free tier before they get going, right." Daniel: "Yeah, pretty much. Like I'm very much convinced that telemetry deck is good. And so it's just about like people need to get to know it. Like people need to be shown the right things so they can accurately assess its goodness. Like because once people sign up for it, I only hear good things." Dave: "Yeah. Mm-hmm. Yes. Yep. Yeah, and I get the impression you hear good things or you hear feature requests, which again is positive, right? It's like, I like this, but I want it to do this other thing as well. Again, to a stage where that's happening with the VJ app now, which is super cool. When I added the MIDI support earlier in the year, I got a lot of really positive feedback on that. Shortly followed with, can you now add recording, please, Dave?" Daniel: "Oh yeah. O.M. That's a separate app and it will cost you $4.99 a month." Dave: "Yeah, $1 million. No. But anyway, I think we've, we've taught all around a whole load of concepts that I find really interesting, right? Modulization of an app. I've been talking about essentially cross selling is my idea for having an app that links up with it. You're talking about" Daniel: "Hehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehe" Dave: "A B testing and tweaking landing pages to suit people better. These are all, and obviously with your own modularization that's enabled this web analytics, which I think is brilliant. But Daniel, it's been really, really great just talking about all of this today. Don't say this enough, but I really enjoy talking with you on the pod. That's, yeah." Daniel: "Yes. Aw, me too Dave." Dave: "And it's just nice to be able to have a conversation like this. And obviously people listen in and I hope that people who've listened in get as much out of it as I do. So on that note, this is a very crowbarred segue now that I think about it. And it wasn't intended that way. But on that note, dear listener, if you have enjoyed listening to this show, we would actually love it if you gave us a review." Daniel: "Hehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehehe" Dave: "over on the iTunes podcast index, Apple's index of everything. I will link that in the show notes and make it very easy for you to just go and click a button and go and click the link in your podcast, uh, podcast app. Go and have a look." Daniel: "Awesome. Why should you do this? Because this pushes us up in the discovery and that means more listeners and more listeners means we are even more motivated to talk about these things with you. And it makes us really, really happy." Dave: "Exactly. Yeah. And we're, we're trying as well to refocus the show and make sure we're, we're putting out episodes every fortnight and stay pretty regular on that. It's been great to have everybody along for the ride with this as well with, with the podcast itself. And just to say, we have a Slack channel. If people are interested in joining that Slack, again, check the show notes, there'll be the means to contact us there, either through the Fediverse or through email and I can get you added to that. Once I've got this house moved out the way I will be revisiting all of this and trying to see if I can make it a bit easier for people to just click a button and end up in the Slack. But yeah, we're trying to build the community around the podcast. There's a lot of good people in there already. and we would love to have you join as well." Daniel: "Fantastic, and I very much agree. All right, that's it for today, I think. So Dave, where can people find you?" Dave: "Yeah. Ah, well, things have changed since the last episode. I have got a new Fediverse account. So you can. Excuse me. So, yeah. Yeah, a couple of weeks ago, I registered with Masto.host and set up social.lightbeamapps.com so you can find me there social.lightbeamapps.com slash at Dave." Daniel: "Okay. I hadn't even noticed, oh my god." Dave: "And that is my new account. It's actually my old account. I redirected everybody over there, which is why you never noticed Daniel. But again, I'm trying to make everything all about my app. So lightbeamapps.com as well to find those. Daniel, how about yourself, mate?" Daniel: "awesome. All right. I'm on social.telemetrydeck.com slash at Daniel. And also you can like skip the social and go to telemetrydeck.com if you want to try out telemetry deck, register for a free account, please." Dave: "Hey, and you should, dear listener, because, yeah, if you've got an app and you want to know more about what your users are doing, it's a really easy way to just get started. And it's a shameless plug, but I really enjoy the product. I've seen it develop and we've talked about its development over the last, how long have we been talking together now, Daniel? 18 months on this show." Daniel: "God, we're at episode 33. So yeah, wow, that's been a while. Maybe we need to start a new season at some point just for like, so that this one doesn't get too big." Dave: "Yeah. Yeah, yeah, I reckon I reckon we may be due for that. Let's, let's see how the next month or two goes and then we'll reboot." Daniel: "Oh, I forgot like this is way too late in the show, but I would just want to say thank you so much to Sven from the aka fine structure from the Swift package index for the awesome shout out and to our podcast." Dave: "Brilliant. On that note, catch you again next time, Daniel." Daniel: "Yeah. Bye." Dave: "Excellent."