VueJS Amsterdam 2026

Guillaume Chau - rstore: journey into the data layer

25:52 · 12 Mar 2026 – 13 Mar 2026 · YouTube

About this talk

In this talk, the speaker, Guillaume, presents a new state management library called Astro, which addresses the complexities of managing data in growing applications. He discusses his background with Meteor and GraphQL before diving into Astro's architecture, which centralizes data management to prevent synchronization issues across components. Leveraging Vue and 3.js, Guillaume demonstrates features of Astro, including a simple API for CRUD operations and the use of a normalized cache to keep data in sync. He emphasizes the flexibility of the library, allowing integration with different transport methods like REST, GraphQL, and WebSockets. Additionally, he shares plans for collaborative features and demonstrates real-time capabilities and offline syncing, showcasing how Astro simplifies the data layer for developers.

Full transcript

[music] >> Good. Hello everyone. Um yeah, so um I hope you're going to enjoy this 2 days of amazing talks and presentations. Uh it's been a long time coming to Amsterdam and I really enjoy being here in this like really beautiful um like room with this giant screen always intimidating a little bit. I'm not going to lie. >> [laughter] >> Um So um today I'm going to

talk about project I've been working on for the past year. Um And it's actually coming from the fact that I'm being interested in this uh like data layer space for quite a long time. Um I started working uh with Meteor back in the days um with MiniMongo and that kind of stuff they had going there. And uh I also quickly got interested in GraphQL for uh all

of the like nice things it brought to the table and like um and especially Apollo client with its normalized cache. And at some point I I decided to create uh something else um a little bit different. So I'm going to talk about that today. Um so my name is Guillaume. Um I have I'm working on Directus and I was part of the Vue.js core team as Alex

said. So um in this talk I'm the first time I'm doing this. So bear with. Uh let's pray internet works. So I prepared a little demo for today that you can like open on your phone. if it works [laughter] you should be able to log in uh with your GitHub account. everybody should appear on this uh little cute solar system here. So let's let's see if it

works. I'll give I'll give you like a few seconds. Does it Does it work? Yeah? Oh yeah. Nice. We're seeing people coming in. That's cool. So it's actually done with um the help of uh 3.js which is a very nice library made by Alvaro. Is Alvaro here? Yeah. Thanks, man. It's amazing. So it's basically a wrapper on uh 3.js for Vue. So that's pretty nice. Looking pretty

good. That's nice. So I'm going to keep this in the background and we go go back to to it later to see how many of you made it to the solar system. Um So So today talk as I said earlier is about state management and data layer. And um like in the early days when I started working on this uh I quickly found out that um especially

when the app is growing it's becoming harder and harder to like keep track of everything each component is doing. And you quickly like bump into bugs uh because of state management. So the problems you can usually find um in this space is that um like if you have a lot of components handling the same data uh scattered around your application um you quickly run into out of

synchronizations problems. So for example if you have a form updating the user avatar um it should like for good user experience also update the avatar in the app header, right? Um and then you are you like write a lot of plumbing plumbing and that's why we in the front end community quickly uh came up with uh state management solutions like Flux or Vuex and Pinia which is

also very nice. So Astro is part of those kind of tools. the big benefits of using a management uh data management tool is that you centralize all of the data management a a single source of truth um that then all of the components derive from um so that you don't have um like com- components getting out of sync and stuff like that. Um So in a nutshell

Astro is there um to like handle all the all of this for you in your application so it can be an actual part of your app and then um you have a plugging system and going to talk about a little bit later but basically it's the base layer of everything data related in your what I focused on uh building this library was having a very very flexible

um like data solution it's a little bit different from uh what you usually find in the Vue libraries um because I wanted it to be uh first uh local first um sort of uh library which means that most of it is um like skewed a little bit towards this use case. Um So I'm going to go back to this a little bit later but I also wanted

it to be very flexible and a very like extensive plugging based system. Uh so it doesn't make any assumption about transport, data processing and the shape of your data in your application. And also wanted to have nice things like the optimistic updates and things like Um So it looks like this. So you you declare collections in your application and then uh you get you can also have

types of course. And then in your app you use a very simple API to like manipulate your data in all components. So for example here doing some queries creating an object updating it and you can see you can also create uh form object and deleting it again. So here's an example of a form to create it like to-dos and also list of to-dos. So I really wanted

to have an API that is really simple to use. Um So here's a list of features um that it currently has um which is like I guess nice to have in a data layer. Um I'm going to go back to this also in more details. So how does it work? Um Basically you have collections as I said that it the directly interacts with the plugins you you

can have um in your application and you have a the cache which is quite important because the cache is what um keeps everything in sync and all of your components uh playing nice with each other. And Astro doesn't make any assumption about transport so you can use anything like REST APIs, web sockets, GraphQL, you name it. You name it. Um So basically what the plugging is doing

is that uh it receives like hooks from Astro and then you can decide what request you want to do or if you want to open a web socket connection or things And then you can write back into the the cache so that components get updated automatically. When you do query it's actually doing two different things. F- uh it's it parallelly looking in the cache what's already there

and also fe- like fetching new information if needed. So everything is um when you're using queries everything is done for you So here's a more detailed view of that. And you can see in orange there are plugging hooks so you can really uh add custom logic everywhere in the whole data fetching stack. And here's a little schema of what is the cache in Astro so it's a

normalized cache meaning every item is top level in the cache and then you the cache can quickly find them based on their key. And you have like three different collections here. So that's how everything is consistent And what I meant earlier by local first is that everything in your component is being computed client side. So for example in your query if you say I want uh to

do that are completed um the filter is going to like be sent to the server so the server responds with the only the filtered items for example but it's also computed on the client side. So the the client side also knows you want to filter only by the completed to-dos for example. So the nice thing about that is that then the code it becomes be simple uh

to handle updates. For example, if you have another component that creates a new or updates a to-do to be completed, your query will automatically be up-to-date in the rest of the application because because like the compilation also happens client-side. Also, recently introduced some um automatic indexes in this. So, the idea is that you create collections, you can add relations between when you access So, for example, to-do

that author, it's going to resolve in the normalized cache, which is the corresponding user in your user based for example on the user ID field on the to-do item. And this is now done using indexes that are automatically populated when you write to the cache and then automatically used when you need to read them from the cache. So, this gave a nice nice speed boost. do a

little bit of live coding, shall we? So, I have a little little app here which is a Pokémon Island. And I I have a database actually here. It's a SQLite database. I have a Next app with some drizzle configuration there. And I actually am using um module you can use which is called um a store Next drizzle. So, it's here. So, this one. And it's it's a

Next module that is going to be to to like be doing all of the plugging for you to like set up a store, like routes to interact with your And then in the client, you can just query things. So, for example, here instead of this array, I'm going to write a query. So, store that Pokémons many. And now I have Pokémons here. Let's see here. I have

some filters here. I'm not sure why I don't have Okay. Um I'm not sure why I have those. Don't worry. Oh, yeah, sorry. That's the entire object. My bad. Yay. So, now we have some Pokémons. So, it's you can see that it's very easy to like the queries there, and I added a little bit of additional parameters. So, I can search search for it in the list.

And let's also create some new Pokémons. So, it's actually going to use um the form object. So, I think it's called create Pokémon equal store Pokémons create form. Oh, sorry. And we're going to put some default values here. in the form in the submit here, uh so, yeah, good. Remove this, remove this, and use the the form object directly, so you can do create Pokémon that submit.

And here you can do create Pokémon that loading. And then you can like v v-model directly on the fields of create Pokémon which are typed because it's coming from my collection Pokémon collection. I have an error somewhere. Oh, yeah. Can delete that. And now should be able to add a Pokémon. Oh, I need to close auto close this. So, we have a Pikachu here. So, let's say

I want to auto close this. So, I can say Basically, what is saying there. Thanks, goodbye. So, let's add another one. It's closing now. And we can also reset the form if you want. So, create Pokémon that reset. Oh, sorry. It's a little bit chilly, so hard to type. Here, we have a create Pokémon form. So, if you see how quick it was to implement. >> [snorts]

I also have like way to add a random Pokémon here. So, let's implement that as well. So, here we can directly create new Pokémons using store that Pokémons create. and await would be nice. And that's it. And now I can have a random Pokémon. And we can also edit Pokémons. here I'm in a Pokémon item. So, let's type this a little bit better. So, in in my

app, I'm listing the Pokémons Here. So, I'm passing the Pokémons object coming from a store directly. So, those objects are a little bit special because they have additional information. So, um if you type Pokémon here, so you can you can see the Pokémon fields in the bottom here. So, those are the types of my collection, but you also have a special properties that can be useful. So,

for example, um we can get the a store um no, the wrapped which is Pokémons. So, that's the name of the collection. So, it's going to automatically get all of the type information needed for this. And now in my Pokémon, I can do for await. Did I get the prop No, okay. It's just Pokémon. And then I can do dollar update with the new information. Within a

sync. All good. And I should be able to update this So, let's say Charmander. So, now we see a Charmander here. And we can also delete them. So, let's say I want to delete the Pokémon. So, I sync and then Pokémon that delete. With an await. Let's add a Totodile. We have Totodile. Let's delete him. Sorry, bye. So, yeah. pretty easy, I would say. Oh, I didn't

import the toast. Now, let's forget about that. What do you say? It's nice. >> [applause] >> So, I really wanted the API to be like really simple to use so that you can hide away all of the complexity of using your data layer. as you saw in each of those components, I never touch any API request or web socket or anything. It's just like abstracting the way

into the plugins. The nice thing about this is that you can if you have a very like stable API. So for example, you're you're using in your like company, you're using a very specific like set of API that is structured. You can quickly write a plugin and then it works the same for every collection and then you can use all of the in the app. You can

also have like multiple different plugins and target different kind of backends and have like a sort of federation of data. So even if you have like a CRM or a very special analytics database going or service going there, you can write plugins for each of those and then scope some collection to those plugins and they will like automatically in the application use the correct plugin and the

front end developer and the all the element can just not worry about that, right? In the view components. >> Um soon I'm working on like more collaborative features around the form objects like I just showed so I show you a little demo hopefully works. Um still work in progress. So here I have um which is also like using a form object just like I showed you with

the create And we can see that I have like some collaborative features going on here. Let's scroll a little bit or resize. So we can see the cursors and we can see that I can like update in real time and write text. So I didn't save yet so it's like doing some conflict resolution in the background. But it's using the same form object and since it's now

using an app plug, you can see all of the operations going on in the form and you can go back and undo some changes or redo changes. So that's something I'm working on as And it worked. Um and you can also do some real-time and offline things. Oh, sorry about >> Why? How did I zoom? Oh. Better. Yeah, that's better. you can replace the query I just

made with live query and that's going to basically add a subscribe action to it that can be handled by a plugin to open a web socket connection for example. Um so let's go back here and enable this in our next our store So I'm going to back to go back to the next configuration and add WS true. I'm going to oh So now we should have real

time. Let's restart. Well. Demo Demo got wasn't happy today. Let's use the live version. >> And you can also enable offline mode here. So it's going to be difficult to you because I don't want to plug the back out the the internet, but it's basically syncing the data automatically using the next module. And when you go back online yeah, you can play with it if you want.

Um and when you you go you go back online, it's going to like update and send the mutations. So it's storing the mutations in a indexed DB and then sending them when you come back online. A lot of Pokemons. Um yeah, basically what I just said. So when you go back online, replace everything. Let's see what we're doing here. Oh, quite a lot of people actually. So

yeah. can I go to the next slide? Sorry. So thank you for my sponsors and that's what it is. You can find more information about our at our store that dev and I'm just in time.

From event

VueJS Amsterdam 2026

12 Mar 2026 – 13 Mar 2026

All event videos
Back to Watch