Mastering Pinia with Eduardo San Martin Morote === [00:00:00] Hello, and welcome to PodRocket, a web development podcast brought to you by LogRocket. LogRocket helps software teams improve user experience with session replay, error tracking, and product analytics. You can try it free at logrocket. com. I'm Noel. And today we have Eduardo San Martin Morote, a Vue. js core team member and creator of Pina, here to talk about Pina and his new course, Mastering Pina. Welcome Eduardo. I know thanks for having me. Of course. I'm excited to chat today. This is probably one that\ big view. People probably know what's going on here, but maybe those that aren't using view day to day and stuff might not know what's been going on in the view store space. \ for those who don't know those kind of outside the ecosystem, or even those who do or are using view and don't know about pina. Can you just contextualize a little bit for us? Tell us what problem it solves. And its origin. So it solves the problem of global state management or state management in general because usually that's global. It's just Vuex [00:01:00] 5. If people have heard of that before, it had a different name because I came up with the idea before Vuex 5 was a thing. And then we decided to keep that name. I think that was for the best because now search results are segregated, right? So it's very easy to find information, topics, articles, videos for each one, because the API is completely different. So that would have been a mess. I think it's a bit like when you search for Angular and AngularJS. At the beginning of Angular 2, it was a bit hard to actually get the right content. And so to get a little bit deeper into the state management, because that's so vague, right? And it's what's always mentioned. I think the best way to see pina is for view developers to have a way to define composables, which will be \ any stateful logic that you can define that is using components or across your application. But instead of being Just stateful logic that you can reuse. It's a global stateful logic. So it's like a single ton [00:02:00] of stateful logics, if that makes sense for, I think that should make more sense, even for people who don't know about Vue. Yeah. I think so. I think people in the front end space, that have had to solve this problem before. Yeah, tell me more about the evolution, like the Vuex Pina kind of dichotomy. Like why was there a need for a transition to something different, even if it was just, a natural evolution? So Vuex came out a long time ago. I don't have the date to be honest, but it was at a time where TypeScript wasn't that strong there was also Flow and we had even the Vue. js. Oracle based reading flow at some point. And so, the way it was designed, even Vue itself, didn't have TypeScript in mind. So some of the things are just not type inferable and it doesn't work out of the box. Now, when you work with TypeScript, you want to have as much as possible, just infer the types so that Everything works without adding, having to create your own interfaces with your own generics. That's [00:03:00] when you know you're getting a bit complicated, right? In the working space. So with the frustration of having to deal with TypeScript, once it's become, it became more popular with Vuex, I Thought there has to be a way to make this type safe that is more appropriate And there was also the composition api that appeared at the time. So view three wasn't even out but the composition api was Out for testing in a way it was the rfc was out. There was a library that allow you to Do it for view two projects. So I thought why not try and create a library that It's state management and rethink is the whole thing. So I give myself ground to start from scratch and take new decisions in terms of architecture, defining the stores and just see where it goes. So the first version was about four years ago. I think it was the 18th of November. Is there any reason to start using VX now? Or is like Pina just the, de facto state [00:04:00] PNIA has become the de facto. There is no real. I wouldn't use UX for a new project.. Gotcha. was there any contention at all? Was there, any pushback on like, Hey, maybe we should just make this the new version of UX versus becoming, like a VX? A different name or was that , but pretty seamless transition. I think it was actually very seamless. People were very happy about the change. The frustration was real, in the ecosystem. I think some people said it would be better to rename it Vuex or were more like confused. Yeah, I think that was the thing. There were some confusion, like why not rename it Vuex, but there was no from the community. I think that once you tell them now you have the results segregated, they're like, oh yeah, that's a very good thing to have. yeah. I feel like views problem in the transition to the composition API, even like react is facing this problem now is there's no clear, especially for beginners, right? If they don't know the difference, it's it's hard to always search for things. You're finding old answers on stack overflow and [00:05:00] things that are like, Oh, this isn't even relevant to the composition API. So it doesn't matter. So there is definitely a huge bonus to this. Cut dry. Like this is the name for the new way. And you noted there that like the API is, totally different in PNU. I would say it's pretty different, but it's conceptually not like a huge departure, like if you're familiar with Vuex, it's not like you're stepping into something totally foreign or unknown. What motivated you to feel the need to write a course? To help people with the transition or help people jump in if they weren't familiar. So there are multiple things, right? At the beginning there is the financial part, of course, about writing a course, it's more about the need of uh, find myself as an open source developer that I don't have that much income, or I don't have a salary that I can rely on to get a loan if I want to buy a house. So I get to a point where having a baby and I wouldn't need that. To get a bigger space and probably buying a house. It'd be a natural. How to say checkpoint Yeah. Next [00:06:00] step. Yeah. Life checkpoint. Yeah. but I do that without a salary So I either get to work for a company which I could too But I really enjoy what I do in open source and I would like to avoid that or I try to provide a value that people are willing to pay for instead of just opensource and usually courses are a good way because I do have the knowledge. I already do workshops even remote workshops in view, and I think it's a good way for me to also. Give content that I've seen nowhere on internet, right? Because the things I talk in this course go from some of the basics, but also with the reasoning of some of the features. So you won't find that any other video, any tutorial about PNIA is not something that I can explain, or it's worth explaining that much in docs, but in a video, I can go deeper and just take the time to explain some reasoning behind some APIs. And also it goes pretty further. So it explains. A lot about the composition API and how to take advantage of that for your applications. [00:07:00] So in the end, the course is actually not just about PNIA, but I realized that a little bit later, it's a lot about Vue itself too, because given how you write how we call setup stores in PNIA which are pretty much just composables. Which is why I was saying the composable part before it also gives you lot of instructions on how to keep composables maintainable. I feel like a lot of at least well structured courses, that they're not just going over the things that are readily available in the docs, there's not much there. And it tends to be the case that they are Talking more at that like, integration into the , larger ecosystem is maybe the cleanest way I can say it. This is why these APIs exist this way. This is what I was thinking about. This is how it enables you to structure your projects more cleanly and reason over them and have fewer bugs and all those things. I guess on that note, is the course recommended for. people that are just getting started? Or would you recommend people go in and do their, hello world, get their feet wet a little bit [00:08:00] with Pina before they jump in? So it's fine if they are getting started with PNIA itself. So if they have experience building Vue. js. It's fine because we don't go through the basics of Vue. js itself. So I expect people with some Vue. js experience, so not just beginners in Vue. js, but they can be beginners in PNIA. It's just that the beginner part in PNIA, in the course is pretty small. Like you get the basics and the PNIA core itself, it's pretty simple. So we get into more complex things really quick and. Every time during the course, even during the basic course, the basic lessons, if I can go a little bit deeper into some topics, I will so maybe that part can feel alienating sometimes for some people, but I think that's fine. I think that if you put that course into combination with documentation, it should feel fine for Pina beginners Gotcha. challenging, of course, than just. [00:09:00] Another course, but going so much further, they're going to learn so much more that I think it's still worth it, . yeah, , you mentioned like composability being a pretty big, Factor here in Pina or something that you think about a lot, but I think to discuss that, and I do want to discuss it. We need to maybe just set this up a little bit for people who aren't familiar with the structure of Pina, like the pillars can talk a little bit about actions, getters, setters, just the typical interface devs are using to update and fetch data from the store. right? So the typical structure is we have three things in Pina and there were four in UX and actually they just come from UX. It's more about, having familiarities with the UX. Not only wording, but also organization. Now, the thing is, , it doesn't force you to write them like that, it's just that they are organized that way and they are used with these names in head, so in mind, sorry, like state getters and actions so that you can communicate about that too. You can talk about it. It [00:10:00] differentiates them from components. And just so for plugins as well, then you know that an action is a function of the store, a getter is a computer property of the store and state is just reps and reactive of the store. That's pretty much it. And so usually what you want to do is they should be. Anything that is reactive and the thing, then we get into the complicated part of are we doing single page application or not? Are we doing SSR , so server side rendered applications. We have to, we. Keep in mind a lot of things, because since the one of the ideas of UX or PNIA is to also serialize the state from the server to the client so that when your page renders on the client after it has been processed on the server, you have the data that was fetched or compute on server, it should render so anything that is non serializable it should ideally not go into a store, right? Unless your application has or that part [00:11:00] of the application, because you can have hybrid applications, unless you have no intention to server side render, for example, very heavy um, client side applications or,, WebSocket stuff, because it does give you a way to put the thing in a global state for example, WebSockets in a game or any collaborating application, but you Will not be able to server side render the state if it contains like class instances, for example, the furnace bay. That's completely fine. iS that to take in to keep in consideration. hOw do you cleanly just articulate this idea to developers, especially newer developers who are getting into the space that layers like there is data that we can easily serialize and transfer over the wire in a. Store, but you have to be careful because there's stuff you can put in the store. Technically, that might be a good idea to put in the store in certain instances, but we can't do SSR. And so is there a clean narrative or, way to articulate that to people? I think I don't have a short one in at [00:12:00] least I do spend some time giving examples when I talk about it in workshops, because Just the fact that you have to think about these two different cases, which I think it's fine in the current era of web development, because you do get some improvement, some benefits from doing SSR. But you also have to pay servers for that. So you don't want to do it with every page. So the easy version is, it's fetching the server, it should be serializable. serializable. Usually, that's fine, because it comes from a fetch, right? So it's already that way. And then the thing is, you don't need to return things that are not meant to be transferred from the server to a client. Now, this, in a way, you could think about it as implementation detail. So I don't like to talk about it too much, it shouldn't be. A concern right but at the same time you have to as soon as you do ssr So usually when I do the courses, I get to a point when i'm like, okay, let's talk about ssr The problems it brings and that's when I [00:13:00] introduce the complexity and explain everything because it's easier to just tell them You just not tell anything. You're not saying anything you can do anything you want in the state, and then when you go to this, you're like, okay, but wait, there's actually a problem here. And then you get into explaining the actual details of why, so non serializable versus serializable, and you just give them an example, even you can show what happens if you do, and usually that sticks into your head very easily. Yeah, that makes sense to me. So I guess pulling up a little bit here going back to the three pillars of Pina someone who hasn't been paying attention for a while or is just thinking about this, maybe like comparing this and thinking oh what about mutations? They were a UX user mutations made sense. To them because they're like, Oh, if I had things that multiple components were doing that, it was a clean place for me to put shared logic that affected the state, what kind of went into the decision to not have that be part of opinion the same way that it was. With so every[00:14:00] all the projects I consult, I consulted for any questions on discord mutations were always perceived as verbose with all these uppercase, very often region in uppercase. It wasn't necessary, but it was often that way and. At the end, it was also for the traceability you could have in DevTools at the time, but with the proxies, with Vue we do get a very, precise traceability of the prox of the objects and the mutations. By mutation, I really mean in the large sense, so mutating an object in JavaScript. Yeah. Yeah. So that allows you to really... Mutate the state anywhere and you can, for example, use a state property in a vmodel, which was one of the pain points, like very common pain point, right? Using the state property , from a UX store, you have to use a computer property with a getter that would just read the state and a setter that would commit to change the state. And it was just so verbose, you have to write. All these mutations, very often you [00:15:00] find yourself writing a mutation for each state. It was rare to have mutations that contain logic or to put it in a better way. It was rare to have both. a mutation that was just changing the state and another one that was actually doing interesting things because mutations were also sync so that's why you had the actions that could be asynchronous and had to still commit mutations so it was also verbose within the actions and then I think that you can write that in actions when it makes sense so when you have business meaning and you can see the stores are services as well. So a way to group that logic around some domain, a business domain. You can put multiple notations of state within an action and it's no trouble. You can still make a synchronous operations within the actions. So in that regard. The mutations and actions became one if you go from UX to PNIA, but we still allow you to modify the state directly outside of stores.[00:16:00] Now, there are ways to make the state read only. It's a bit more complex than it could be. And I actually talk about this in the Mastering PNIA. And I think I have some free articles online where I just show the actual code. people can just find that too. Yeah. there's probably valid arguments for it to be like much more locked down and traceable and stuff for some dev flows, but I think it is easy to justify that. And I think anyone that used Vuex. To like you said, like in any projects you were consulting on or people that had just been using it for a while felt this phenomenon where it was like, it doesn't really help me to have these two things separated all the time. Like these are one of them is basically always calling the other if we could just have these be one thing and I wouldn't have to have all this just, wiring code that's just going through the motions. um, I think that is a common observation. So I think that this segues us nicely. Let's talk about composability a little bit and how that has changed now. It has obviously changed in the greater view ecosystem, but specifically what does Pina empower on the composability front? So initially the pina [00:17:00] stores were actually just optional stores. So an object with state function that returns an object with the initial state, then an object of getters, which are just computer properties, exactly like the computed object in a view component because you get the state as the first argument. And you can use these if you want to refer to other computer properties and then the actions, which is pretty much methods, right? Like component methods, because instead of having a fixed arguments, like in Vuex, you have a context with the commit, then the payload and all this stuff. These are just functions that you define however you like. So you add the arguments that you need and you set the return type. That you need to so later on with the composition API, some people were proposing talking about and also with the UXRFC with Kia and other core team members, we were exploring other possibilities, and we were using more and more composables, like dogfooding our own APIs, right? And so[00:18:00] discovering more and more of the part we're of. So some people were saying we were multiple ones saying that, oh, we could just have a function and return the things like in components. And that will be the store. And so at some point, I implemented that to give. Myself a lot of freedom, but I think at that time I wasn't that confident on that concept, and it's only after playing a lot with it and seeing how powerful it is. I think also a few features that we introduced in view that improved that. It's only then that I realized powerful setup stores are compared to the option stores. And especially if you Unique. By to see stores, so opinion stores, not just as stores, but as composable singletons which as I said before, allows you to have global stateful logic instead of stateful logic. And it enables also, if you see them that way, you can also use the stores within. Regular composables. So you use the store as a way to [00:19:00] handle the global state is also attracting dev tools and stuff and handles SSR, but you can put within the composable logic that is specific to a component things that happens only client side uh, focusing the window, any global events that you have, but also local events that you have. And you can configure some of the things too on the composable. You can pass arguments to the composable, so you can interact with the store. You can still have the logic within the store, for example, to handle a collection of projects and then individually handle some stuff of the projects and then have a composable that. Individually handle one project. Maybe are all the things I've used it are for data fetching. For example, you can have things that are specific to the data fetching mechanism, like when to refetch adding the server on server prefetch. So it handles SSR as well. That will be a regular composable, but then you have a store that. Is storing all the information and that way it also handles this are you can call functions of the store [00:20:00] within the composable like ensuring a cache entry for example and so you have patterns that are created this way that are not possible otherwise because you don't have the global part I think to most listeners that makes sense, but like someone that had been using Vuex for a while or something, they're probably sitting there thinking like I could do most of that with Vuex or figure out a way to make it work. It might not have been \ . Totally the intent. Is there something specific, in the API or how Pina works under the hood that makes this composability is easier to think about and reason over than like state, the prior iterations of state management. The first one is a UX as a root store. So you have one composable that is used store and then you get access to the root store and then inside you can have namespace stores. And so these are extra concepts that you don't even think about when you're using PNIA because they are baked into the way you define stores. So it's not only the namespacing of stores, but also the. [00:21:00] Dynamic modules. That's what they call in UX. So basically, it's just Adds to the, code splitting better, right? Their stores can become code splitted that way with pages. So if you have a page that uses a few stores and those stores are not using any other page, and if you are using lazy imports at your router level, which you should probably Be doing. And if you're using Knux, it's already the case. Then the store code will be with that page. Chunk, and that wasn't the case for Vuex because the way you define the store and then how you associate every other module, which is just a sub store to the root store, make it always go into the main chunk. So a little bit of waste. So that part is already pretty nice, especially for bigger apps, but also. Since you have these namespace stores, you have to use the main store and get access to the different part to interact with it. Definitely not as natural [00:22:00] as just one object where you call methods on it, read state from etc. There is a lot of. From the outside, , when you use a composable that is returned by Pina, it's just an object, right? But in Vuex, you have all these layer of how to interact with the store that is not there with Pina. again, I think anyone, who has used a large UX project has probably encountered this problem and kind of knows that pain point of trying to navigate it and figure out exactly, you know, put these really long paths of Oh, it's like. This child, this complex tree maybe is a cleaner way to put it. And with composability that always feels a little bit more natural. How does this affect like testing your components and those that utilize stores or even testing stores directly? think it doesn't affect that much. Except for the fact that you write less code, right? Because you have to write less code to interact with the store itself. I did write the test you choose for Vuex. It was like Vuex mock store, I think. So that was my package too. And it was a way to mock the store within components. [00:23:00] So usually if you test your stores, you don't need to test them again in your components. Now, depending of course, at what level of testing you are in your application, because you could always just do integration tests if you wanted, if you didn't have any other tests first. Basically that allows you to just set the state and just verify that actions are called, and then your component should render something. So that way you bypass completely the store and pina now also has the testing library that goes by the same principles. If you're testing components, you can bypass the store completely. You can even override getters by just setting a variable , in a special store instance. So , the cool thing is you only need to create what we call a testing pina. So that would be like the root store, except it's not a store, but It's what connects every store. And so instead of having a regular PNIA, you have a testing PNIA and that one gives you access to spies and other kind of mocking features that are really nice in testing. \ Were there a lot of people acutely asking [00:24:00] for that or was that just something that you felt you knew would be useful? Yeah, I felt it would be useful. I think that I saw the NPM download count of the Vuex mock store. That wasn't too bad. And it's something I would just use myself actually. \ are there any other plugins out there even like not just for testing but for production at large or just To ease development or anything for Pina that you've been either working on or have been keeping an eye on. There isn't that many things. I think the plugin space itself is very niche. Now I made it flexible enough. To completely encapsulate the DevTools within a plugin. Cool. So it shows how powerful it can be. But you can augment options. You can make so many things yet. I don't think. In practice, you need them too much. It's more for bigger applications, I think. And I haven't seen a lot of very interesting plugins. It's very niche. I've seen like local storage things, but you can do it without because you can just use composable within setup stores, though it's very [00:25:00] straightforward. And I have these demo plugin, which is called debounce. So it allows you to debounce actions. Very simple. , again, , instead of stores, you don't need them because you can just rely on the way you write things in composables, but still works with set up stores to UX plugins. That's surprising an answer to me. I don't think I can't recall. I don't know if I'm too, yeah, a huge use for Vuex plugins. Most of the time I'm sure there's. Use cases I'm forgetting, but yeah, stuff like local store debouncing, but those things make sense. But yeah, it does seem pretty bespoke kind of niche. Like you said, what do you think the future looks like for opinion? Like \ , what's on the roadmap or what changes are you thinking about? How about a few ideas that are more correlated to improve the global aspect of some stuff related to SSR like, adding global on server prefetch, and that could be used within PNS stores. Some improvements on the, dev tools. That the main idea is really to keep [00:26:00] things as stable as possible, right? We really want to have things stable. Since the composition API is so flexible. There isn't that much to add, there are a few things that could be added to setup stores by having a parameter in the function, there are a few smart things that could be done that way, but I don't want to break how people write their stores. So it's mostly dev improvements that I'm thinking of, right? When it comes to what could arrive to Pina. That makes sense. I think it's a, kind of a testament to maybe how well, S link plugin. S link plugin is one of them, right? I never had the time, never find, found the time to write one of them. What's the there are a few things, Why is it, why is that just lack of time. Sure. I haven't written a plugin before, but there are a few things that are could be covered by yes, in plugins for example, readable state or rather, people like that old no state mutations outside of Yeah, So you could do that [00:27:00] with a plugin. And right now well, there are other ways of doing it. But with TypeScript, Right, , , I think that could be useful. But, , how I'm thinking about this is it may be a testament to, again, like how\ parameterized the function of these storage plugins are. It's okay, this is what we need them to do. They don't really need to do anything else. If they're doing this well, we've probably accomplished the goal. So I guess it's cool to hear that you are feeling pretty confident in it. Do you think, I know this is a, probably a tricky question to ask, but I imagine that was a similar feeling with Vuex early in its life cycle. It's okay, this feels pretty good. I don't see this changing anytime soon.. Do you think that If anything, there's any kind of fundamental decisions or ways in which, Pena's APIs work that could maybe need changed in the future for some reason, or is it too hard to say? There could be things if you ever improve imagining in view, things change. So for performance, maybe there could be things about reactivity that change. [00:28:00] And maybe, you would access in the setup stores. To the ref, like to a way to declare the state, stuff like that. I could, this is some ideas I had in the beginning, but I was like, it's just easier and natural to uh, import ref. And also the problem with that approach is more about right? If you use a composable within the store, then the ref still comes from you. So you have to have both words. unless there are , fundamentals changes in the way we make things in Vue, PNA shouldn't change, so it should come along, right? How about that, like circling way back to the SSR difficulties that we were talking about before. And do you think there's anything there that could I don't know. Just give us some different fundamental primitives in how we think about web apps that might change how we interact with stores. if you look at the ecosystem, you have React server side streaming. Now, in practice if you do, That kind of thing like server side rendering streaming people. Sometimes you see the demos. I'm like, oh, wow, this is [00:29:00] great You get the page shell right before I so far It looks so fast, but they forget that then they have to pay a bill for that, too So you probably don't want to do that for most of your pages like it's very simple to have a version that costs zero in terms of computing which is just server side generate the shell And then just client side fetches. It's a little bit slower. And I really mean little. It's less than, it depends on how long it takes to render the page, but the difference is really small. it's under, I think, 50 I tested something. So , unless something like that changes but even then I don't think it will invalidate how you write the store. So I, I struggle. The thing is. Pina composables, the way you write setup stores are so close to the way you write view composables that it shouldn't change, right? That's also one of my goals, like I want to keep these as close as possible to view way of doing things so that you're also learning how to write things in view. And that knowledge is really not never [00:30:00] wasted unless view changes, but then if you changes, then it makes sense to change Pina. I don't think we foresee that yet. It's too hard to say. I'm totally with you. I'm setting you up with tricky questions here. So no, I think It's no, it's good. It's It's a totally valid answer. Cool. Is there anything else you wanted to touch on or mention or even just point listeners to have people check out? Apart from like my course, mastering opinion. I don't think that there get a, cool. We'll get a link in the show notes to that for sure. yeah, that are interested in learning more with a lot of exercise, hands on exercises, mastering opinion. Cool. Cool. Thank you so much for chatting with me today, Eduardo. It's Thanks for having me. of course. Take it easy.