Loading
Interviews with Experts Bonus 25 exercises
interview

Simplifying Web Form Management with Edmund Hung

Edmund Hung, steward of the Conform library and web developer at Delivery Heros, shares insights into Conform, a crucial part of the Epic tech stack specializing in form handling.

Conform is a library that is designed to handle the challenges of form management on the web. Edmund was influenced by Remix and various web APIs, which led him to study web specifications. He found that studying web specifications was invaluable, but also complex without a targeted use case.

There are several technical challenges with form management that are discussed, including the performance implications of using Redux, form validation, and the role of progressive enhancement in form management. Conform is spotlighted for its unique approach: it bypasses native browser validation systems in favor of its own.

Edmund outlines his future plans for Conform, focusing on enhancements in state management through potential use of React context. He aims to centralize states to better synchronize forms and hooks and to enable server-side processing.

Resources

Loading interview

Transcript

00:00:00 Kent: Hey everybody, I'm excited to be joined by Edmund Hung and say hi Edmund.

00:00:07 Edmund: Hello

00:00:08 Kent: Edmund is the creator of Conform the library that we're using in the Epic stack and through all the workshop exercises and everything. Conform touches pretty much everything that we do as part of the Epic stack, whether you're doing the login form or a file upload or like just

00:00:28 there's the forms are on pretty much every route, honestly. Or like even the theme toggle, that is also powered by Conform. So just a lot of cool stuff that Edmund is helping, or Edmund's library is helping us with. Integration with Zod as

00:00:48 well. We talked to Colin about Zod as well. So yeah, I met Edmund through Remix. I think my first clue into Edmund was the Remix.guide website that he put together a while back. And so, yeah, and

00:01:08 then Edmund built a form library and I decided, or I was trying like every single 1 and finally Edmund responded to all my requests and I said, hey, I don't like this, I don't like that. I would like it if it did this. And Edmund didn't do everything exactly the way that I said which I think is good. Edmund

00:01:28 is extremely thoughtful about his APIs and what he's building, which I love. So anyway, that is how I know Edmund. Edmund, I think it'd be good for you to give yourself an intro to yourself or give us an intro to yourself.

00:01:42 Edmund: Yeah, sure. So hi everyone, I'm Edmund. I am a senior front-end developer for about 10 years, roughly 10 years, and I come from Hong Kong. And I'm currently working actually in Berlin in a company called Different Hero, which is a parent company for many

00:02:02 different, for different platform like DoorDash or Uber that you might heard of in US. Yeah, I, yeah, as Kent mentioned, I've been actually a kind of early adopter of Remix. I, I built RemixGuy and I have been maintaining Conform, I think

00:02:22 since, well, I think March last year. So it's like 1 and a half years now already, yeah.

00:02:32 Kent: Well, Yeah, awesome. It has been a wild ride with Remix and it's been cool to have you along for the ride the whole time. So with the company that you work at, are you using Remix there or is Remix just like a for fun thing for you?

00:02:48 Edmund: I wish, actually the first, I actually just joined this company early last year and the first thing I do is actually the pushing for Remix. And yeah, unfortunately I didn't make it, but still I think it was a very good ride because I kind of explained Remix to many people, talked to many people, and at least tried to get more people

00:03:09 knowing about Remix. And at the same time, the good thing is even without Remix, I can still use many of the cool ideas from Remix through web browsers, right? So yeah.

00:03:21 Kent: No, that's good. Yeah. That's 1 of the beautiful things about Remix and the focus on the platform is that the ideas are so transferable. So with the Epic Web, a lot of people are asking me about like, okay, so why did you choose Remix for the framework and why didn't you go with

00:03:41 something more popular like Next.js? For 1, that is temporary. I'm pretty confident that Remix will be the most popular web framework in the world in the future. But secondly, the question that they're asking or what they're trying to get at is,

00:04:03 how is this going to apply to me if I'm not using Remix? And just like you said, the ideas of Remix are what are really powerful and can apply whether you're using Remix or not. So Yeah, that's cool. Okay, so you worked on Conform, like before I

00:04:23 started needing a form library solution. Well, I shouldn't say that. I've needed a form library solution the entire time I've been doing forms on the web. Like the forms are a challenging thing if you're doing more than just like 2 fields for your whole app. And so what motivated you to build

00:04:43 Conform?

00:04:45 Edmund: So I have to be honest, I didn't really plan to actually make a form library at first. I was just toying around with Remix a lot, I think early last year. And I was kind of inspired by how Remix can utilize the web APIs, those platform, to introduce

00:05:05 kind of a model that is simple to understand, at the same time has a pretty good mechanism to handle what we need. So I kind of just like, hey, there might be something I can find out about validation. Then I basically just spend a weekend looking at the MDN, just and I realized, oh, there's an API

00:05:25 about the valid state, there's API about the invalid event. And that's kind of get me into the rabbit hole. Like, oh, maybe this, I just keep looking of the MDN docs and maybe sometimes even like, hey, maybe it's not enough. Let's go to check the XML spec and see if there's anything interesting.

00:05:46 And yeah, and that's just how things happen. And I just kind of like, yeah, try paying around different ideas. And then now it becomes what you see now.

00:05:58 Kent: Cool, yeah. Yeah, you know, the HTML spec or the, just the web spec documents, I find that they're difficult to read unless you have a specific use case in mind. And so if you're thinking about, oh, well I want to understand how validation works and what order do these things happen, whatever.

00:06:20 If you have a use case in mind, then going through the spec documents is actually pretty interesting. And it definitely has a language of its own, like there's annotations and different things that you have to understand, but yeah, don't be afraid of the spec. That's a good thing, good call out. Okay, so you talked about the validity API in

00:06:40 the browser. Is Conform using that?

00:06:45 Edmund: I would say yes and no. So there's a lot of interest. I think whenever we talk about because enhancement in form validation, I think the first thing people would think of is those validation attributes, like required, the meaning, all sorts of stuff. And so you do it then when we talk about this in terms of web APIs, it will become

00:07:05 the valid state. And which is pretty cool. It's definitely pretty cool because it gives you a quick idea to like, hey, all kinds of validation being done by browsers. But at the same time, it's really hard to, it's not enough for most of the, well, it's not enough for like all sort of requirements that you might come up with

00:07:25 because form validation is a really hard topic. And so I Actually, when I start looking into this part, I think I spent 1 month trying to create kind of a SAP-like API on top

00:07:40 Kent: of this.

00:07:41 Edmund: And it's just, to me, it's just too much to take care of. And the different experience we saw, it's just so good that I end up thinking like, maybe I should not go for that route for now. I will come back to this later. And that's why right now, Confirm doesn't really have a direct

00:08:01 support on this part. But 1 interesting thing that we do right now is that we're utilizing the invalid event. So what happened is that Confirm is trying to disable the native browser validation and re-implement it. So that, and use the invalid event as a way to propagate errors to different places so that you

00:08:21 can, your component will be re-rendered only when necessary.

00:08:27 Kent: Yeah, that is definitely a concern that probably some people listening have experienced when they hook up all of the state of their application into Redux and now all of a sudden every key press is triggering a re-render of the whole app and lots of pain associated with that for sure. So yeah, that is cool. So you mentioned

00:08:47 progressive enhancement. I had a timer for how long it took us to bring progressive enhancement up. I'm just kidding. But yeah, that's definitely a huge thing for you personally. And I would like to, if you could, kind of explain what progressive enhancement is and why you think it's so important.

00:09:09 Edmund: Wow, that's a really good question. So, first of all, I think progressive enhancement, the idea of progressive Enhancement is so cool. That's actually maybe the first reason why I look into it. I think I actually heard about Progress Enhancement, the first time I heard about it, is not about JavaScript,

00:09:29 but actually about the idea of having HTML, CSS, and JavaScript separated, right? And Pugliese Hansman, when I first heard about it, is like, hey, you should have a semantics HTML so that when your CSS doesn't know, you still have something that is easy, it can be readable by the users.

00:09:50 And yeah, I just find it actually very cool. And then, yeah, but maybe, yeah, back to your question, sorry. So, ProcureHandsman to me is basically a way that you utilize the platform to think about what the users, what the platform can provide the users by just utilize HTML

00:10:11 and then incrementally add the layers of complexity by based on like whatever is available to the users or the browsers. And so that it has a very, it has an experience that is, yeah, I'm a bit out of things.

00:10:30 Kent: Yeah, I like to say that progressive enhancement is about giving a baseline functional experience and then layering on, as you were saying, layers of improved experience based on the capabilities of the device. Yeah, so what is it about progressive enhancement that

00:10:50 you think is so important and why do you focus so much time and attention on it?

00:10:57 Edmund: So Well, maybe a little story. So as I mentioned earlier, I grew up from an international city, Hong Kong, which is a small city with many people. And we generally have pretty good internet. So we...

00:11:17 But we... So many people in the city actually spend a lot of time commuting basically to the office. And, but still, with such a good city, with such a good infrastructure, it's actually very common to me to have struggle with like sometimes when I'm on a metro,

00:11:38 on a subway, whenever you pass through maybe certain tunnels, you suddenly can't do anything. And I think this is where like Progress Enhancement is 1 of the things that is kind of important because it seems everyone, when they talk about Progress Enhancement, they just think about, hey, I don't think my users will disable

00:11:59 JavaScript. But I think, yeah, a lot of people also mention, what really matters here is your website before the JavaScript node has no JavaScript and you cannot do anything. And if we are not trying to think in terms of progress enhancement, then it's very hard for, then users basically has nothing to do but

00:12:19 has to wait. And what they end up is they just keep refreshing, trying to hope that, okay, you get back to what they want. And I think if with, For example, with a good progress enhancement support on the farm, then your users will be able to continue to do what they do.

00:12:39 For sure, there's still a chance that you fail, but it still gives them a more smooth experience, hopefully, that they can complete what they're doing. Yeah.

00:12:50 Kent: Yeah, I agree with that. And I've experienced that myself. It's definitely more pleasant to have the UI work than to like press the button and nothing happens. And so I'm like, oh, okay, I guess I'll refresh like that just seems like a really bad user experience. And

00:13:10 what people will sometimes say is that like, well, but this only affects, you know, point 1% of users, right, that this is going to be a thing we shouldn't dedicate so much of our time to it. But Ryan Florence says sometimes that this doesn't only affect 0.1%

00:13:31 of users, this affects 100% of users 0.1% of the time. And I think that kind of changes the calculus for me, at least a little bit to say, hey, every 1 of my users is at some point going to have some kind of failure in loading the JavaScript. And so let's give them as positive

00:13:51 an experience as possible in that world. The other thing that I love about progressive enhancement is that the mental model is a lot simpler as a developer, that development experience. Like it's been years now that we've been using Remix and I'm starting to forget how painful it was to manage

00:14:11 application state. And because I don't have to do that with Remix and that's because of progressive enhancement. And so yeah, I'm definitely bullish on progressive enhancement. What are some of the challenges with, so I guess I should say, Conform and just forms in general have a

00:14:31 huge role to play in progressive enhancement and making forms work when the user is using the app and the JavaScript fails or something like that, or is slow to load or something. And So there's a lot to say about progressive enhancement with forms. What would you say are the things that are

00:14:52 like the most challenging for you when you're trying to make sure that things are progressively enhanced?

00:14:59 Edmund: Well, The most challenging 1 is definitely how we enable people to be able to manage a list in a kind of friendly way with their, because my take sometimes with Procrastinant enhancement is like, yeah, as you mentioned, like it's, it will happen like

00:15:19 sometimes, It's not like, you don't expect that it happens all the time but whenever you need it, it should be supported. And, what was I saying?

00:15:30 Kent: Yeah, you were talking about lists being really challenging to implement.

00:15:34 Edmund: Yeah, so, in order to make this work, it actually has need to have some very special way. So actually, this is, I've been, so how's that? So when I was first working on the list, I actually have been like trying to, really trying to look out, hey, how can I make this

00:15:54 work from the server? Because there's no way I can, because usually when you think of it, it's just like, oh, I have a use day. And then I click this, I append an object. That's how you would think of it in most of the cases. But when you want the server to be included, the first question is how do you tell the users that

00:16:14 this happened? And I think this actually has a very huge impact on the Confirm architecture later on because this is actually the first thing I realized. The intent, kind of the intent pattern that would have been kind of quite popular in Vue Mix

00:16:34 form is that so that you basically include, I think it's basically you include a name and value in your button so that when you click it, you can include some additional information to your server. And Conform has been kind of expanding this idea to more stuff. So, and for example, in the case of this, we basically include the information of, hey, what the users, when the user,

00:16:54 I said this is an add button, then when you click it, then Confirm will basically include this extra information to say, hey, this user's wanna add maybe a new role to the item on this path, kind of the path. So yeah, and this path, and then I would need, I need confirm

00:17:15 to have a special handling to say, whenever he saw this, then it kind of processed the data that you sent out and then send back to the client so that the client can use it to be in his eyes.

00:17:27 Kent: Yeah, and then we pipe it through use form with the last submission. Is that how we get that populated? Yeah. So in the workshops, we have the file upload on a note, and you can add as many images as you like. And I show people,

00:17:47 I turn off JavaScript, and like, look, I can add that. That's like, that is 100% a client-side operation for people, when they build it themselves. Like, there's no way that they would build a server round trip for that. And of course, when JavaScript is in the client, it's not a server round trip, it is all happening in the client, but it just

00:18:08 is so, so cool that you put that much effort into making even that experience work. And what's cool about this is, let's say that you do go through a tunnel, you've got the HTML, but the JavaScript didn't load in time. And so then you choose your image, you set the alt text and all that stuff, and then you come out of the tunnel, and you say, oh,

00:18:28 I want another image. It's gonna, you're gonna add that image, it's gonna do a full page refresh. You will lose the image, that 1 is, yeah, good luck with that. That would be a tough 1, I think. But at least like the, whatever else that you entered into that form is going to be there.

00:18:48 I just think that is so cool. And you'll have the same number of images there. So there are limitations to progressive enhancement and the level that you can take it. But I do think that it's just phenomenal how good you can make that.

00:19:08 Edmund: Yeah, and 1 thing I want to add is, so this is just 1 part. So as I mentioned, like Conform has been utilized as intent patterns for actually a lot of the parts. So, and this is actually 1 of the reason why I think Progress Enhancement, we proved that Progress Enhancement can simplify a model because the way that the conform handle form

00:19:28 is everything is about submission. And it's just that every time based on the intention, you have a slightly different message being encoded together. So for example, if you're thinking about a kind validation, and let's say where you're typing something, you won't expect the Confirm to validate. And for sure you will update some options on the use

00:19:48 form to make it work. But what actually would happen is that Conform basically just helping you to check as a form submission with the corresponding valid intent. They say, hey, this user want to do that. And this actually enables some very cool additional features is that Confirm can work

00:20:08 with server validation without kind because everything is, imagine, everything is on submission. So, And if you don't have any kind of validation, what happens in Confirm, we just simply say, I don't know, just let the server handle it. And the server capture it, and server validate it, and then send it back. So that Confirm would

00:20:28 basically allow you to be just utilized fully on the server without, especially like sometimes you don't really need kind of validation, like if you are building a form, maybe a login form, and you don't really have some very complex validation logic, Why do

00:20:49 we borders? And you can just let the server do it. And server is a source of truth for everything, right?

00:20:53 Kent: Mm-hmm. Yeah, that's very true. And I try to iterate that in the workshop, but I'm just gonna reiterate it. The server side is where you get your security and validation. The client side, the only reason you do client-side validation is for an enhanced user experience.

00:21:14 That's all that it gives you. It does not give you any level of security. But yeah, so what's really cool about this though is that you can share that validation logic on the client and the server. So anything that can go into the client will go in or you can put it in the client.

00:21:35 And this was the big promise of Node.js when it first, well, not when it first came out, but when people first started writing JavaScript that could be shared between the 2, is they're like, oh, we can run the exact same code on both sides, it'll be amazing. And Meteor tried to do something with that and that to varying levels

00:21:55 of success. But I feel like I never really experienced the reality of that promise until I started using Remix and Conform plus Zod has really given that to me. And like I not only get the server side validation and client side validation with Zod, but you

00:22:15 also are able to give me the progressive enhancement attributes, like the HTML5 attributes on these inputs based on my Zod schema. So if I say dot optional on this thing, then required isn't gonna be on there. And I just think that is so legit. Like that, when I was looking for a good form library, that was a requirement is being

00:22:35 able to have a schema and then generate HTML attributes and ARIA attributes as well automatically. So yeah, I'm thrilled that Conform can do that.

00:22:46 Edmund: Nice.

00:22:47 Kent: Yeah. So, another thing I wanted to ask you about was about working with that Zod schema. And sometimes there are things that, like validation that can run on the client like this, has a min length of 3

00:23:07 and a max length of 20. But there are some validations that can't happen on the client by themselves, like this username is unique. So what we do in the workshop is we have a, just add a dot super refine or a dot refine or a dot transform on the server side in

00:23:27 the action. And that works really well. But is there a way to do that, like those async validations on the client?

00:23:39 Edmund: Yep, definitely. So I think this is another use case of proofing like the model that Confirm has is actually very interesting because as I mentioned earlier, the way they confirm validate is when, it's basically a checker form submission with maybe a valid intent. And what happened,

00:24:00 So imagine like when you have, let's say, a sound form and you wanna have a username field that you wanna check for uniqueness, as you said. And you still, when you have kind of that in place, for sure you still want to kind of to just check whether let's say the users

00:24:20 has profile, a name, has something. And at the same time, maybe it has to follow a certain basic requirement. Let me put that meaning, there's some special characters that users cannot be using. And you want all this in client, but you only want, but whenever everything else is passed, you want the server to

00:24:40 do it. And the way that Conform actually make it work is that Conform actually think about itself as a middleware. That's the way I think about it. It's actually like a middleware in your sub-mean handlers. And because of the fact that Conform can work with both server validation and client validation,

00:25:01 it will be able to switch. So the way is that whenever the kind validation say, hey, I'm happy with the current username, but the kind validation doesn't know, this is for sure, it doesn't know how to check the uniqueness so you tell conform, like, hey, I'm happy, but there's something

00:25:22 additional I want to check. I don't know. So let's, how about let the server do it? And Confirm will, Confirm do is, oh, I just don't call event.pmnd default, and let we mix, capture it, and then it's being forwarded to the action and then The server for sure you will have to where there's an object that check the uniqueness already and

00:25:43 In that case it well you pass it you get a sub you get a submission you send back client The kind get a submission with errors is populated and done

00:25:53 Kent: Yeah, yeah, I just love that. I think that the model itself just really speaks to how thoughtful you have been about the API and the way that it works. I think it's pretty constraining for you to have to live inside of this

00:26:13 box that you've kind of made for yourself. Like, these are my requirements, But as a user of Conform, it just drastically simplifies things. Because I can still, even with complex validation logic like that, I'm still not using useState or useEffect or any of that nonsense. It's amazing. So I mean, I'm sure that there's probably,

00:26:34 well, I guess I'm not sure. Are you using useState inside of Conform? I'm guessing you are somewhere.

00:26:40 Edmund: Yes, this is, yeah, we have been, well, we have been kind of managing the errors in each of the conform hooks for sure. But actually this is 1 thing that's gonna be changed in the future because I am, so well, I mean, Formalization

00:27:01 has, to me has several areas, Formalization 1 part, but the other part is the management because a lot of people, error is just 1 part of the whole thing. There's a lot of information that people want. And at the moment, I think Conform has been not very good on this part. And 1 thing I want to change and I want to improve is

00:27:23 to centralize the state. And there's also some extra benefit actually on this part is that, so the idea is that you, I will have the form handling, there's a, okay, so maybe let me just explain

00:27:43 how Conform works right now. I think that would be easier to follow up. So the way that Confirm works right now is that, whenever there's a validation happen, it's maybe elastic kind of validation, say no problem, then let's go to servers, and then the server try to validate, and server maybe say, oh, there's something went wrong.

00:28:04 It's returned the submission result back to the client and the client pick it up. And then when confirm see, oh, there's some errors, it triggers the invalid event. And each host that you're calling like use form, the use fields that this kind of folks who basically has a

00:28:24 invalid event, this 1 is trying to capture this date. And what happened is that we are actually using the DOM as a source of truth right now. So that every time whenever there's some updates, each of the hooks is just kind of, okay, let me just read the DOM, read the message on the DOM,

00:28:44 and then update the internal state and populate the users. Which works fine, works really fine for a while, but it becomes a bit limited in terms of how, when the users want to capture some information in some non-common cases.

00:29:05 So imagine like maybe you want to display the error message not next to your form, but in some place different. And it would become very hard for you to get this information because the information is on the DOM, but

00:29:25 in a sense, in the world of focus enhancement, you don't have access to the DOM.

00:29:31 Kent: You have to do it

00:29:32 Edmund: in the useEffect. And this makes the things become very challenging. And so what happened, what I'm imagining right now is that basically I have to utilize ReactContext, unfortunately. And so basically I have to-

00:29:50 Kent: React context is for libraries. That's good. You're good.

00:29:53 Edmund: Yeah. So yeah, basically we centralize all this. So instead of picking the DOM as the source of truth, it would become, we use, we basically have a very simple store as the, where we keep all the state and have each host subscribe to it. And the good thing with this approach is basically like, yeah, now we can allow

00:30:15 any component inside a tree to subscribe to it and reflect it in a progressive enhancement way. Yeah, 1 additional thing I want to share is that in the next version, in the future version, I'm also planning to utilize

00:30:35 useId so that we can always generate a unique id for the form. And what it means is that, because right now the way that Confirm works is it always has to know the form element so that you can know that, okay, this change has been related to me. And, but now with a unique

00:30:55 ID, we always have a unique ID, we can totally make it flexible by, So imagine if you always wanted things from the same tree and you don't need to even pass ID. Everything you can pass down will have the ID included. But if you, let's say, if you want to access this information in somewhere, then all

00:31:15 you need to do is just give an ID and then that will become the key in the store that which you can catch access directly outside in any way.

00:31:25 Kent: Yeah, yeah, okay. So this would just be like It sounds to me like this isn't necessarily required to have that provider. Like people wouldn't have to have that by default. It's only necessary if you want to display error messages in a different place from where the use form hook is called.

00:31:45 Is that right?

00:31:48 Edmund: Yes and no. I guess there's some API I'm still experimenting and trying to get a good experience. So this is something I don't know yet.

00:31:58 Kent: Okay, okay, okay. Well, if you can make it opt-in, then that's how I would prefer it personally. But I understand if you need to require the provider. That's what Context is for. It's for libraries, React Router uses Context as well. And in fact, in the workshops, I

00:32:18 have an exercise on honeypot fields and 1 on authenticity token inputs for cross-site request forgery protection. And both of those come from Remix Utils and they both require providers because that's just how we do that, how

00:32:38 we make those values available throughout the app. So, yeah, that sounds interesting. Okay, yeah, go ahead.

00:32:47 Edmund: Do you want, I just want to share a little bit more because I, so this, the idea of this centralizing state is not only about making more things feasible, but actually it's also enabling some very, I think potentially some interesting use case in the future because I would right now I think it's already pretty good like we can support

00:33:09 some of these operations in the progressive enhancement way but I don't want Conform to stop at this level and because there are all sort of requirements that people can come up with, and there's always cases like people might try to say, hey, can I do it in a progressive way? But it's just so hard, usually,

00:33:29 in most of the solutions, because there's so many things you need to manage. And 1 thing that this, by sending the states, what I want to enable is that we, I want to actually move the state also to the server. So what happened right now is that whenever you do submission,

00:33:50 I am actually also sending some basic additional state of the current form to the server. So the server can utilize it to do additional processing and send back. And at the same time, because it's centralized, we now have 1 single place that you can add additional logic on how things should be

00:34:10 processed. Because, as an example, 1 of the things that I don't like with the current implementation is that it has been actually pretty challenging to implement the list action in terms of the hooks because there's quite a fair amount of states within the,

00:34:30 still in the useFieldList API which is trying to manage the keys and all sorts of stuff. And when I try to, because I want to support both cases, like, hey, there's a Node.js cases, I want to support the cases when there's no, there's a kind.js, but you only want the server to validate. And at the same time, I want to

00:34:50 support kind. And this is quite a bit of messy logic to trying to make the state in sync whenever a validation happens between the form and the hook itself. And what happened with the changes that I'm thinking is that by centralizing state, it just subscribes.

00:35:11 So what happens is it's always a subscribe to centralize state. And in the future, I would love to have an API that people can create their own intent and have a kind of like a reducer, like you can think of it like a Redux store, like you can, you can, you get, you get a current state I have, you can tell how

00:35:31 it's changed it. And what happens is that you just tell the, how to parse it, so parse it on both client and server. And if the client doesn't know how to do it, again, let the server do it. And then it gives a full cycle on how things work.

00:35:50 Kent: So I love Conform in its current form. I think it's fabulous and amazing. And I think it's awesome that you are not satisfied. That there are areas where you're like, this definitely could be improved and I want to make that happen. So thank you for being so meticulous

00:36:11 about this library and for working on it. It's just been phenomenal. We're coming down to the end of our time. Is there anything that you wanted to talk about that we didn't really get to chat about yet?

00:36:27 Edmund: I think no, I pretty much, yeah, I think.

00:36:30 Kent: Cool, okay, good, good. Well, Edwin, what's the best way for people to support you and get in touch with you and keep up with stuff that you're working on?

00:36:42 Edmund: Yeah, I think the major way is really on... Yeah, I would actually love to have more people writing some tutorials, articles about how to use Conform because I think 1 of the bad ideas with Conform's

00:37:02 naming is that it doesn't have remix in it. And I sort of realized it's become very challenging to get users because people when they're working with React, for sure they were looking for some common React libraries. But when they're working with Remix, they've searched for Remix and they didn't realize that Conform is actually working with Remix.

00:37:23 Kent: Yeah, yeah, that makes sense.

00:37:24 Edmund: Yeah, so I think it would be actually really helpful if people, if they enjoy working with Conform, or even if they don't like it, I'm actually happy to get some feedback on sharing how they feel and this way, just a good way for me to improve.

00:37:42 Kent: Well, yeah, that sounds great. So get on it, folks. This is a very important thing to do for your own retention in learning, to write the things that you understand and that will solidify that understanding for you. So yeah, that sounds like a great idea. Is there a good way for people to keep it up with the stuff

00:38:02 that you're working on?

00:38:06 Edmund: Yeah, so I think, as I mentioned a lot of times, like there's some changes upcoming, and I probably, so what happened with the coming changes, it'll probably be V1, hopefully. So I think this is also a way for me to show that I am finally confident with my work. And I think it's

00:38:26 time to give it a actual major version. And, but before that happened, I'll probably go for a time of like half of release and beta release. So I'll probably do some announcement on the GitHub and sharing all the changes and trying to get some early feedback so that we can get a really good

00:38:47 shape before we release the first major version.

00:38:50 Kent: Awesome. Okay, so watch the releases on GitHub for Conform. Cool, well, thank you so much Edmund. I appreciate you giving us some of your time and everything else that you do. Have a wonderful day.

00:39:02 Edmund: Thank you.

00:39:03 Kent: Bye everybody.