Patterns for Large Scale Vue.js Applications

Rate this content

What is the best way to structure a Vue.js application so that it can scale to meet all your users' needs? There are multiple patterns established by the Vue community and the programming community at large that can be adopted in order to make your codebases more predictable, maintainable, and extendable.

24 min
15 May, 2023


Sign in or register to post your comment.

AI Generated Video Summary

In this Talk, Daniel Kelly discusses patterns for large-scale Vue.js app development, emphasizing the importance of following standards and using officially recommended tooling. He highlights the Vue.js style guide as a valuable resource for styling standards and suggests using TypeScript and Nuxt 3 to enhance development capabilities. He also mentions the benefits of having a naming convention for routes and the concept of wrapping third-party dependencies for flexibility. Additionally, he mentions the app-icon component for a generic icon solution and the advantages of interacting with backends via an SDK.

1. Introduction to Large-Scale Vue.js App Development

Short description:

Hello! My name is Daniel Kelly, and I am the lead instructor at the school. Today, we will discuss patterns for large-scale Vue.js app development and the importance of structuring a maintainable and extendable application. One key tip is to make your code base predictable by following standards. The Vue.js style guide is the official resource for styling standards in the Vue.js community. It provides guidelines for component naming, such as using Pascal case and prefixing base components with 'app' or 'base'. Single instance components should be prefixed with 'the', and tightly coupled child components should have prefixed names. Following these standards helps ensure clarity and prevent conflicts. This is just a sample of the guidelines available in the style guide.

Hello! My name is Daniel Kelly, and I am the lead instructor at the school. I am so very excited to be with you all here today. I have been a full-stack developer for the past 10 plus years, worked with technologies like Wearable on the back end, and of course, Vue.js on the front end. But that's enough about me. I just wanted to quickly let you know who it is you're dealing with, but now let's get on to today's topic at hand, okay?

And that is looking at some patterns for large-scale Vue.js app development, right? So, our goal during this session is to answer this question, what is the best way to structure a Vue.js application so that it can continue to be maintainable and extendable, even as it gets to a very large size, right? Why is this question important? Because we've probably all been given a task for a particular app before and had this exact feeling. We just don't know where to begin, we don't even know how to approach the issue, maybe because things are a little bit messy. So, our goal is to eliminate this feeling here as much as humanly possible. All right, we all wanna enjoy our jobs and be less frustrated.

Okay, so I'm gonna start with this key tip for making a large-scale application, that is make your code base predictable. This first tip is really not that exciting, it's really not that flashy, but to be honest, this is one of the keys, in my opinion, to building a maintainable app. Make it as predictable as possible by following standards, so that everybody knows where to look and how certain things work. So, this begs the question, where do standards for the Vue.js community exist? Place number one that comes to mind for me is the Vue.js style guide. This is the official place for styling standards for the Vue framework. Here is an example of some standards designated within the document. When it comes to naming your components, first of all, it says that all of your components should be in the Pascal case. It also mentions you should prefix your base components with the word, app, or base. So, these are all those components that you're going to be using throughout your application, and they're a lot more general use case, right? These are things like AppButton, AppTable, AppModal, things like that. Things that accept props down and events up, and probably don't rely on any global state, okay? I actually prefer to use App in this instance because it always puts my base components at the very top of my components directory. It also mentions that you should have multi-worded names for your components. This is actually even more than just a style thing, it's also to prevent conflicts between existing or future HTML elements and your new components. Another standard is to prefix all your single instance components with the word, the. These are any components that are just going to be used on the page a single time. Now, they could absolutely be used on multiple pages, but they only appear on a single instance of a page at a time. So this is usually layout type components, things like the header, the footer, the sidebar, so on and so forth. It's also mentioned that you should prefix tightly coupled child components. For example, if you had a component for an item that always existed within a to-do list, you would prefix that component name with to-do list, and then item. A real-world application of this that I used in a codebase at my previous job was I had a job form component, and then there was a special field for choosing the location where a job should be advertised called job form location map field. Okay, so this tells any other developers within the project that this component is really only meant to ever be used in the context of the job form. And they can get that just by looking at the component name. Okay, this is great, and there are some other tips on styling your component names within the style guide as well, but this is just a good sampling, and there's certainly a lot more available in the style guide besides just component naming.

2. Standards, Tooling, and IDE

Short description:

Implementing standards in your project reduces cognitive load for new team members. The Vue.js style guide provides guidelines for component naming and other styling standards. The guide is currently outdated but still valuable. The officially recommended tooling for Vue.js, such as Vite and Opinion, provides useful resources. Avoid custom solutions when there are officially recommended ones. NUX3 is a reliable source of predictability due to its conventions and popularity. Taking full advantage of your IDE, installing Volar and ESLint, helps catch errors and improve development experience. IDE formatting, whether with ESLint or Prettier, ensures consistent code style.

But this is just a good sampling to kind of show you, hey, if you implement these standards, it's one less cognitive thing that people who are onboarded to your project have to think about, because they're standards that everybody already knows, okay?

By the way, just at the time of this talk, it is important to note this warning at the top of the style guide, and that is it's currently a bit outdated. Most of the examples are in the Options API only, and there are no rules regarding Script Setup and the Composition API. However, as you just saw, a lot of the things for styling don't even necessarily have to deal with one API or another. All of the component naming things could apply to either API. So this is still a great resource, but do expect it to be updated in the future, okay?

Another really great resource for standards is the officially recommended tooling for Vue.js, all right? That's found on the tooling page of the official Vue.js docs. It provides reference to things like Vite for your development server and Opinion for global state management. This might seem like it could go without saying, but maybe I've ignored some of my own advice in the past and I want to make sure you don't do the same. What do I mean? Well, one of the projects I was working on prior to joining Vue School, of course, needed global state management. Well, I wasn't thrilled about the DX that Vuex provided, and so I came up with my own global state management solution based around the Vue.Observable API in Vue 2. Long story short is, yes, there were some DX improvements. However, there were more downsides than upsides. There were caching issues that I didn't handle that Vuex would have already handled for me under the hood. There were onboarding issues when it came to moving new people to the project who I had to explain this custom solution to that if I just used Vuex they would have already been familiar with it or at least I could have just pointed them in the direction of the Vuex docs, right? So the key takeaway here is if there is an officially recommended solution for your problem, definitely think long and hard before you use anything else, okay?

So predictability from the style guide, predictability from the officially recommended tooling, and then finally another great source, I think, of predictability is the metaframework NUX3, okay? It makes a lot of opinionated decisions and it's such a huge player in the Vue.js community a lot of people are going to be familiar with the conventions that it provides. So definitely recommend taking cues from NUX3 when it comes to structuring your application or just using NUX3 to begin with. By the way, you will see NUX3 come up a few more times in this talk because I think it's such an excellent piece of software.

Alright, so tip number two is to take full advantage of your IDE. This is after all the software that you're going to be using most in order to develop your application. Number one, that means make sure to install Volar, that's probably pretty obvious. However, number two is also make sure you have ESLint installed on all your projects. I've had projects that I've worked on before where we didn't do this. Let me tell you, it was an absolute pain because ESLint is going to help you catch items directly inside of your IDE without having to wait to find out about them at runtime. In fact, it's gonna show you errors in your IDE that you might not even get hard errors for within the browser, all right?

So, for example, in this little piece of code, we're using a V4 to loop over item in items but we have left off the key. This would not error in the browser but my IDE knows now because of ESLint I should really add this key to my V4. And then the same thing down here for this Hello World component. It's being imported and registered. However, it's not actually being used anywhere inside of my template. And so ESLint is saving my end user from having to download this extra code that's never even used. Right, I get this essentially for free just by installing ESLint, okay?

Similar to this is making sure your IDE's formatting is set up appropriately. Okay, this could be the formatting that is built in with ESLint or it could be a more opinionated formatter like Prettier.

3. IDE Setup, TypeScript, and Nuxt 3

Short description:

Make sure your IDE is set up to automatically format your code. Check out the 'Visual Studio Code for Vue.js Developers' course for more tips. Consider using TypeScript in your large-scale Vue.js projects to enhance your IDE's capabilities. Vue School offers courses on TypeScript for Vue.js projects. Nuxt 3 has TypeScript installed by default, making it a great way to get started with TypeScript. Nuxt also provides great file structure conventions and functionality, such as auto-importing components and file-based routing.

Okay, this could be the formatting that is built in with ESLint or it could be a more opinionated formatter like Prettier. But no matter what, make sure your IDE is set up to do this formatting automatically for you, be that on file save or whatever, just make sure you aren't having to take that cognitive load yourself. It's just not necessary. The tooling can do it for you, okay?

If you'd like some more tips and tricks about taking full advantage of your IDE in the context of a Vue.js project, I highly recommend you check out this highly rated course that we have at Vue School. A lot of people have given me really great feedback that this has helped them optimize their workflow. Okay, it's called Visual Studio Code for Vue.js Developers. And in it, we go over some of the things I already just talked about, but we also get into things like utilizing Vue.js snippets that are provided by the community, creating your own Vue.js snippets, optimizing your workflow for Git in terms of using your IDE, and a whole lot more. So definitely check that out if Visual Studio Code is your IDE of choice.

Lastly, I really, really, really recommend that you consider using TypeScript in your large-scale Vue.js projects. They are going to take your IDE's knowledge of the code to an absolute other level that's just not possible without TypeScript, okay? This is going to help you prevent errors as you're developing your code, it's gonna make your refactors less stressful and less risky, and it's going to help give your autocomplete superpowers. If you aren't familiar with using TypeScript in the context of a Vue.js project, at Vue School, yes, we also have a course for you there as well. We'll teach you how to type component prompts, type component events, type template refs, and a whole lot more, okay? And even if you're brand new to TypeScript and don't know just the basics, we have a TypeScript Fundamentals course for you. Okay? I just don't have the time to get into all the specifics of those things during this talk, but I wanna give you the resources. Finally, Nuxt 3, note, does have TypeScript installed by default. And if you're brand new to TypeScript, I really think using Nuxt 3 is a great way to dabble and just play and get used to using TypeScript in a new project. Why? Well, because it's just installed by default. You can use JavaScript all you want. You can use regular JavaScript components, and then just as you see necessary, implement a TypeScript component here and there and sprinkle it in your project progressively as you get used to it. Okay? Really great way to get started with TypeScript. And by the way, in the context of Nuxt project, you even get some special types generated for you on the fly by the framework. So for instance, if you've got some API endpoints set up internally within the project based on a special file convention, the Nuxt specifies, you're able to get auto-complete whenever you call fetch on any of those API endpoints because it generates these types on the fly based on the conventions of the file structure. So that's really cool. Speaking of file structure, I always get this question, how should I organize my files for my large-scale project? And my simple answer nowadays is just use the standards that Nuxt provides. And in fact, just go ahead and use the standards that are actually inside of the project. Actually start your project with Nuxt3 because not only do you get the great standards, but you get some great magic on top of those standards. For instance, any components that are created within the components directory are auto-imported for you. You don't have to manually import those throughout your project. Same thing goes for composables, okay? Plugins are also auto-registered and the pages inside of the pages directory are automatically turned into routes. This is called file-based routing. So a lot of goodies there when it comes to Nuxt's file structure, okay? Great conventions but also great functionality.

4. Naming Convention for Routes

Short description:

Come up with a naming convention for your routes, even though it's not officially specified in Vue.js. Other frameworks have route naming conventions, such as the one from Laravel. Having a convention in place ensures predictability and collaboration within the team.

Tip number four is come out with a naming convention for your routes. This is not something that's specified officially for Vue.js anywhere. However, a lot of other frameworks out there do have route naming conventions. And the one you see on the screen in front of you now is pulled directly from the Laravel docs. So I could be working on a Vue.js frontend and other developers who are on my team who are familiar with Laravel could also be working on this frontend and they could have a predictable way of working with routes if I follow the same convention for my frontend. So your team might not use Laravel. That's perfectly okay. My point is have some kind of convention in place. And if you need inspiration for one, I definitely suggest you check out the Laravel docs because this convention is a really great one. Okay?

5. Wrapping Third-Party Dependencies for Flexibility

Short description:

Josh Deltner explains the concept of wrapping third-party dependencies to decrease the chance of third-party login and increase app-specific optimizations. Wrapping dependencies allows easy replacement in one place, without affecting the entire codebase. It also enables extending functionality for app-specific use cases. This approach works for both functional libraries and components, providing a convenient way to implement and manage third-party code.

This is a concept that Josh Deltner explains very well in his article entitled Nuxt Enterprise Patterns Provider Abstractions. Okay? Why should we do this? Well, it decreases our chance of third-party login and increases the surface area for app-specific optimizations. You might not actually understand what that means. So let me show you with a little example code.

All right? So let's pretend we're using Axios in our project in order to make our AJAX requests. Now, Axios is popular enough that I wouldn't actually suggest wrapping Axios. I would suggest using it directly. However, it's a good and common library that I think helps people understand this pattern. So I wouldn't actually wrap this in your apps, but I would do it for similar third-party dependencies.

Okay, so let's say you have Axios. In order to wrap Axios, you could create a class called HTTP and then define a get method on that class. Under the hood, all you're really doing is calling the Axios get method. And then you could do the same thing for the other method types and so on and so forth. But why in the world would I want to do this, Daniel? I mean, I'm not getting paid to write per line, right? Well, the advantage here is that if, for some reason, we ever had to replace that dependency with something else, I could very easily just do that in one single place. So, here, we've changed out Axios for the browser-native fetch function. And the beauty is we've only had to change it out in one place, that is, in our HTTP class. We didn't have to search throughout the code base, do a bunch of messy finds and replaces, we only had to focus on this single file. And the other beauty about this is that all the other developers working on the project who are using this HTTP class throughout the project, they don't even have to know that I've updated dependency. They just continue using the HTTP class as usual, okay?

So, this is a really great solution when it comes to dependencies that you're maybe not so sure about, that you think might not have the longevity. You might be replaced later on with something else. So, I'm not saying wrap all of your third party code, but be choosy and do wrap some of your third-party code, okay? Another great benefit of wrapping this third-party code is that it surfaces opportunities for extending the functionality for app-specific use cases. So, for instance, let's say I wanted to handle all of my HTTP errors a particular way in my app. Well, at that point, it's as easy as adding a try-catch within my single class. Now, of course, this user experience isn't great, but you get the idea. I can have these app-specific optimizations all wrapped up in my class. And then when I go to use the class throughout the application, I don't have to worry about reporting these errors to the user or whatnot. Same kind of thing could be applied for a caching mechanism. All right, I think you get the idea. By the way, this also works for components and not just for functional helper libraries. So, for instance, this app-icon component I have here is actually made to make my icon solution from my app generic and even extend it so that I can use two different icon solutions at once, so you see here my app-icon wraps font awesome as well as material design icons, and I've provided a single interface that is the app-icon component for actually implementing the icons throughout my application.

6. App Icon Component and Backend SDKs

Short description:

The app-icon component allows for a generic and extendable icon solution in your Vue.js app. Interacting with backends via an SDK offers advantages such as preventing typos, client-side data normalization, error spotting, and type safety. Recommended Vue School courses include TypeScript with Vue JS 3, Pina the enjoyable Vue store, and wrapping rapid testing with V-test. Vue School also offers the AI Chatbot with Vue JS and GPT-4 course and the official Vue JS certification.

So, for instance, this app-icon component I have here is actually made to make my icon solution from my app generic and even extend it so that I can use two different icon solutions at once, so you see here my app-icon wraps font awesome as well as material design icons, and I've provided a single interface that is the app-icon component for actually implementing the icons throughout my application.

Awesome. All right, so tip number six is to interact with your backends via an SDK. Fine, well, take a look at these two lines here. Which one of these would you rather write? Would you rather write the full request out, something like this, or would you rather write something short and simple, like this? For me, the answer is clear. You wanna do option number two, right? Well, there's several different advantages if you do choose this option. Number one, and most simplistically, it helps you prevent typos, okay? You're not going to have to worry about typos in the path of your API endpoint. But it also provides you the opportunity to do client-side data normalization in a single place. Think turning all of your date strings coming from the backend to actual date objects in JavaScript, or any other derived data perhaps, like computed things you need to do, or something like that. Okay, that can be wrapped up in the actual SDK, and your actual client code doesn't have to think about it, okay? It's also easier with SDKs to spot errors and provide type safety. By the way, you don't have to write these SDKs for yourself. A lot of solutions out there come with JavaScript SDKs already built out for you. So things like Firebase are really great for this, which by the way, we use in the Vue.js 3 master class as a backend, and Superbase, which is a self-proclaimed open source alternative to Firebase, is a solution I really like, where they actually even provide a command for automatically generating your TypeScript types based on the structure of your database. And this makes it really, really great to work with, okay? By the way, if you're into Laravel, there's also this Laravel query library, query builder library that does much the same as some of these other two that I just talked about. So I'd suggest checking that out if you're into Laravel.

Awesome, that is my time with you today. I wanted to leave you with just a few recommendations for some Vue school courses that I think will help you build better large-scale apps. Number one is the TypeScript with Vue JS 3 course, we've already talked about a little bit. Next is our Pina the enjoyable Vue store course. This is going to help you get a great grasp on the official Pina state management solution for Vue, and lastly is wrapping rapid testing with V-test. All right, by the way, we also just finished releasing this great new course called AI Chatbot with Vue JS and GPT-4. If you're interested in implementing AI into your applications, your Vue JS apps, I definitely suggest you check this out. And the official Vue JS certification has launched and pre-orders are being accepted. So this is something that the Vue School team is doing in collaboration with the core Vue team. If you'd like to prove your Vue JS development skills to potential employers or potential clients, this is a great way of doing that. Thank you all very, very much for your time. And I hope you have gained some valuable knowledge from today's talk. You all have a wonderful day and keep coding. Thanks.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Vue.js London Live 2021Vue.js London Live 2021
34 min
Everything Beyond State Management in Stores with Pinia
When we think about Vuex, Pinia, or stores in general we often think about state management and the Flux patterns but not only do stores not always follow the Flux pattern, there is so much more about stores that make them worth using! Plugins, Devtools, server-side rendering, TypeScript integrations... Let's dive into everything beyond state management with Pinia with practical examples about plugins and Devtools to get the most out of your stores.
Vue.js London Live 2021Vue.js London Live 2021
20 min
One Year Into Vue 3
Vue 3 may still sound new to many users, but it's actually been released for over a year already. How did Vue 3 evolve during this period? Why did it take so long for the ecosystem to catch up? What did we learn from this process? What's coming next? We will discuss these questions in this talk!

Vue.js London Live 2021Vue.js London Live 2021
8 min
Utilising Rust from Vue with WebAssembly
Rust is a new language for writing high-performance code, that can be compiled to WebAssembly, and run within the browser. In this talk you will be taken through how you can integrate Rust, within a Vue application, in a way that's painless and easy. With examples on how to interact with Rust from JavaScript, and some of the gotchas to be aware of.
Vue.js London Live 2021Vue.js London Live 2021
24 min
Local State and Server Cache: Finding a Balance
How many times did you implement the same flow in your application: check, if data is already fetched from the server, if yes - render the data, if not - fetch this data and then render it? I think I've done it more than ten times myself and I've seen the question about this flow more than fifty times. Unfortunately, our go-to state management library, Vuex, doesn't provide any solution for this.
For GraphQL-based application, there was an alternative to use Apollo client that provided tools for working with the cache. But what if you use REST? Luckily, now we have a Vue alternative to a react-query library that provides a nice solution for working with server cache. In this talk, I will explain the distinction between local application state and local server cache and do some live coding to show how to work with the latter.

Workshops on related topic

Vue.js London Live 2021Vue.js London Live 2021
169 min
Vue3: Modern Frontend App Development
Featured WorkshopFree
The Vue3 has been released in mid-2020. Besides many improvements and optimizations, the main feature of Vue3 brings is the Composition API – a new way to write and reuse reactive code. Let's learn more about how to use Composition API efficiently.
Besides core Vue3 features we'll explain examples of how to use popular libraries with Vue3.
Table of contents:
- Introduction to Vue3
- Composition API
- Core libraries
- Vue3 ecosystem
IDE of choice (Inellij or VSC) installed
Nodejs + NPM

Vue.js London Live 2021Vue.js London Live 2021
117 min
Using Nitro – Building an App with the Latest Nuxt Rendering Engine
We'll build a Nuxt project together from scratch using Nitro, the new Nuxt rendering engine, and Nuxt Bridge. We'll explore some of the ways that you can use and deploy Nitro, whilst building a application together with some of the real-world constraints you'd face when deploying an app for your enterprise. Along the way, fire your questions at me and I'll do my best to answer them.

JSNation 2022JSNation 2022
141 min
Going on an adventure with Nuxt 3, Motion UI and Azure
We love easily created and deployed web applications! So, let’s see what a very current tech stack like Nuxt 3, Motion UI and Azure Static Web Apps can do for us. It could very well be a golden trio in modern day web development. Or it could be a fire pit of bugs and errors. Either way it will be a learning adventure for us all. Nuxt 3 has been released just a few months ago, and we cannot wait any longer to explore its new features like its acceptance of Vue 3 and the Nitro Engine. We add a bit of pizzazz to our application with the Sass library Motion UI, because static design is out, and animations are in again.
Our driving power of the stack will be Azure. Azure static web apps are new, close to production and a nifty and quick way for developers to deploy their websites. So of course, we must try this out.
With some sprinkled Azure Functions on top, we will explore what web development in 2022 can do.
Vue.js London Live 2021Vue.js London Live 2021
176 min
Building Vue forms with VeeValidate
In this workshop, you will learn how to use vee-validate to handle form validation, manage form values and handle submissions effectively. We will start from the basics with a simple login form all the way to using the composition API and building repeatable and multistep forms.
Table of contents:
- Introduction to vee-validate
- Building a basic form with vee-validate components
- Handling validation and form submissions
- Building validatable input components with the composition API
- Field Arrays and repeatable inputs
- Building a multistep form
VSCode setup and an empty Vite + Vue project.

Vue.js London 2023Vue.js London 2023
137 min
TresJS create 3D experiences declaratively with Vue Components
- Intro 3D 
- Intro WebGL
- ThreeJS
- Why TresJS
- Installation or Stackblitz setup 
- Core Basics
- Setting up the Canvas
- Scene
- Camera
- Adding an object
- Geometries
- Arguments
- Props
- Slots
- The Loop
- UseRenderLoop composable
- Before and After rendering callbacks
- Basic Animations
- Materials
- Basic Material
- Normal Material
- Toon Material
- Lambert Material
- Standard and Physical Material
- Metalness, roughness 
- Lights
- AmbientLight
- DirectionalLight
- PointLights
- Shadows
- Textures
- Loading textures with useTextures
- Tips and tricks
- Misc
- Orbit Controls
- Loading models with Cientos
- Debugging your scene
- Performance
Vue.js London Live 2021Vue.js London Live 2021
116 min
Building full-stack GraphQL applications with Hasura and Vue 3
The frontend ecosystem moves at a breakneck pace. This workshop is intended to equip participants with an understanding of the state of the Vue 3 + GraphQL ecosystem, exploring that ecosystem – hands on, and through the lens of full-stack application development.
Table of contents
- Participants will use Hasura to build out a realtime GraphQL API backed Postgres. Together we'll walk through consuming it from a frontend and making the front-end reactive, subscribed to data changes.
- Additionally, we will look at commonly-used tools in the Vue GraphQL stack (such as Apollo Client and Urql), discuss some lesser-known alternatives, and touch on problems frequently encountered when starting out.
- Multiple patterns for managing stateful data and their tradeoffs will be outlined during the workshop, and a basic implementation for each pattern discussed will be shown.
Workshop level
NOTE: No prior experience with GraphQL is necessary, but may be helpful to aid understanding. The fundamentals will be covered.