{"id":1849,"date":"2024-05-02T10:49:50","date_gmt":"2024-05-02T16:49:50","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=1849"},"modified":"2024-05-05T07:42:17","modified_gmt":"2024-05-05T13:42:17","slug":"the-vue-ecosystem-in-2024","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/the-vue-ecosystem-in-2024\/","title":{"rendered":"The Vue Ecosystem in 2024"},"content":{"rendered":"\n<p class=\"ticss-dfa54eec\">Since its inception in February 2014, <a target=\"_blank\" href=\"https:\/\/vuejs.org\/\" rel=\"noreferrer noopener\">Vue<\/a> has become one of the top JavaScript frameworks for building and maintaining web apps. It is a popular pick for many developers because of <a target=\"_blank\" href=\"https:\/\/vuejs.org\/guide\/introduction.html#the-progressive-framework\" rel=\"noreferrer noopener\">its philosophy<\/a> of creating an approachable, performant, and versatile approach to building scalable apps.<\/p>\n\n\n\n<p>Once you\u2019ve chosen Vue to build your app, it\u2019s important to consider what tools and libraries can help you ship features faster to users. While a lot has changed over the years, the addition of new features like <a href=\"https:\/\/vuejs.org\/guide\/extras\/composition-api-faq.html\">the Composition API<\/a> has introduced lots of exciting new changes to the ecosystem. &nbsp;Let\u2019s look at some of the popular tools and libraries used by the community today.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Getting Started with Vue<\/h2>\n\n\n\n<p>There are three primary approaches to scaffolding your Vue app:<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"1\">\n<li>Content Delivery Network (CDN)<\/li>\n\n\n\n<li>Build Tools<\/li>\n\n\n\n<li>Using a meta-framework like Nuxt<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">CDN<\/h3>\n\n\n\n<p>While most JavaScript frameworks require a build toolchain to work, one of the great things about Vue is that it can be added directly on a page. No build tools necessary!<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-comment\">&lt;!-- unpkg --&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/unpkg.com\/vue@3\/dist\/vue.global.js\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n\n<span class=\"hljs-comment\">&lt;!-- jsdelivr --&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/cdn.jsdelivr.net\/npm\/vue@3.4.25\/dist\/vue.global.min.js\"<\/span>&gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Or if you\u2019re already using ES modules, you can also use it as follows:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"module\"<\/span>&gt;<\/span><span class=\"javascript\">\n  <span class=\"hljs-keyword\">import<\/span> { createApp, ref } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'https:\/\/unpkg.com\/vue@3\/dist\/vue.esm-browser.js'<\/span>\n  <span class=\"hljs-comment\">\/\/ or 'https:\/\/esm.sh\/vue'<\/span>\n\n  createApp({\n    setup() {\n      <span class=\"hljs-keyword\">const<\/span> message = ref(<span class=\"hljs-string\">'Hello Vue!'<\/span>)\n      <span class=\"hljs-keyword\">return<\/span> {\n        message\n      }\n    }\n  }).mount(<span class=\"hljs-string\">'#app'<\/span>)\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To learn more, check out the <a href=\"https:\/\/vuejs.org\/guide\/quick-start#using-vue-from-cdn\" target=\"_blank\" rel=\"noreferrer noopener\">official docs<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Build Tools<\/h3>\n\n\n\n<p>When your app is ready for build tools (e.g., Vite, Rollup, webpack) and\/or you want to use <a href=\"https:\/\/vuejs.org\/guide\/scaling-up\/sfc.html\" target=\"_blank\" rel=\"noreferrer noopener\">Single-File Components<\/a> (*.vue), the best way is to use <a href=\"https:\/\/vitejs.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">Vite<\/a> for Vue 3 projects. <a href=\"https:\/\/vitejs.dev\/guide\/why\">Why Vite?<\/a> It leverages both latest advancements in the ecosystem: the availability of native ES modules in the browser, and the rise of JavaScript tools written in compile-to-native languages.<\/p>\n\n\n\n<p>Fun fact, Vite was written by <a target=\"_blank\" href=\"https:\/\/evanyou.me\/\" rel=\"noreferrer noopener\">Evan You<\/a> (founder of Vue), so naturally there&#8217;s a way to scaffold a Vue project with it!<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">npm create vue@latest<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To learn more about creating a Vue application with Vite, check out the <a target=\"_blank\" href=\"https:\/\/vuejs.org\/guide\/quick-start#creating-a-vue-application\" rel=\"noreferrer noopener\">official docs<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Meta-frameworks<\/h3>\n\n\n\n<p>For those interested in taking Vue beyond client-side rendering to other realms such as static-site generation (SSG), server-side rendering (SSR), and other rendering methods, you&#8217;ll want to start your project with scaffolding from popular meta-frameworks such as <a target=\"_blank\" href=\"https:\/\/nuxt.com\/\" rel=\"noreferrer noopener\">Nuxt<\/a>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">npx nuxi@latest init &lt;project-name&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To learn more, check out the <a target=\"_blank\" href=\"https:\/\/nuxt.com\/docs\/getting-started\/installation\" rel=\"noreferrer noopener\">official docs for getting started with Nuxt<\/a>.<\/p>\n\n\n\n<p>That said, here are two other options I wanted to give a shoutout to:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Meta Framework\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitepress-thumb.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1890\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitepress-thumb.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitepress-thumb.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitepress-thumb.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/vitepress.dev\/\">VitePress<\/a><\/h4>\n\n\n\n<p>A fantastic static site generator that uses Markdown to create beautiful docs in minutes (while powered by Vue theming for easy customization).<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Meta Framework\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/quasar-thumb.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1892\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/quasar-thumb.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/quasar-thumb.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/quasar-thumb.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/quasar.dev\/\">Quasar<\/a><\/h4>\n\n\n\n<p>A cross-platform Vue meta-framework that comes with a lot things out of the box like Material components, various build modes, and much more.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Routing<\/h2>\n\n\n\n<p>When it comes to your routing solution in Vue, it&#8217;s a straightforward choice because Vue has an official library for routing, but a meta framework can help as well.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Meta Framework\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1935\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/router.vuejs.org\/\">Vue Router<\/a><\/h4>\n\n\n\n<p>This is the official router for Vue. Expressive, configurable and convenient routing.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Meta Framework\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nuxt.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1980\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nuxt.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nuxt.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nuxt.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/nuxt.com\/\">Nuxt<\/a><\/h4>\n\n\n\n<p>For those who love file-based routing, you&#8217;ll get that automatically in conjunction with Vue Router when you use <a href=\"https:\/\/www.nuxt.com\" target=\"_blank\" rel=\"noreferrer noopener\">Nuxt<\/a> with no additional configuration needed.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n<\/div>\n\n\n\n<p>If you&#8217;re interested in following or contributing to an up-and-coming extension on Vue Router that allows you to do file-based routing with TS support, be sure to keep an eye on <a target=\"_blank\" href=\"https:\/\/github.com\/posva\/unplugin-vue-router\" rel=\"noreferrer noopener\">unplugin-vue-router<\/a>!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">State Management<\/h2>\n\n\n\n<p>Similar to routing, Vue makes it easy for you by providing an official library for state management, but since state management is more particular to the requirements of an app and how a team approaches it, here are some popular options in the community.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  State Management\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/pinia.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1933\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/pinia.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/pinia.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/pinia.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><strong><a href=\"https:\/\/pinia.vuejs.org\/\">Pinia<\/a><\/strong><\/h4>\n\n\n\n<p>Pinia, formerly known as Vuex, is the official state management library for Vue. On top of being TypeScript-friendly, it takes a huge leap forward from the traditional redux pattern by eliminating the need for explicitly defining mutations. In other words, a lot less code while still being declarative!<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  State Management\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/xstate.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1996\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/xstate.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/xstate.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/xstate.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><strong><a href=\"https:\/\/stately.ai\/docs\/\">XState<\/a><\/strong><\/h4>\n\n\n\n<p>For those familiar with state machines, you&#8217;ll want to check out <a href=\"https:\/\/stately.ai\/docs\/\" target=\"_blank\" rel=\"noreferrer noopener\">XState<\/a> as an option for managing state within your app. As a bonus, a fantastic team backs it and has been a consistent favorite within the community.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  State Management\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/tanstack.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1934\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/tanstack.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/tanstack.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/tanstack.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><strong><a href=\"https:\/\/tanstack.com\/query\/v4\">TanStack Query<\/a><\/strong><\/h4>\n\n\n\n<p>One of the major challenges that developers face with state management is around granular state management within the context of async calls. <a href=\"https:\/\/tanstack.com\/query\/v4\" target=\"_blank\" rel=\"noreferrer noopener\">TanStack Query<\/a> is a popular pick in the community for helping to manage this.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  State Management\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1935\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><strong><a href=\"https:\/\/vuejs.org\/guide\/scaling-up\/state-management.html#state-management\">Composables<\/a><\/strong><\/h4>\n\n\n\n<p>With the addition of the Composition API, Vue makes it easier than ever for developers to create their own state management solutions with <a href=\"https:\/\/vuejs.org\/guide\/scaling-up\/state-management.html#state-management\" target=\"_blank\" rel=\"noreferrer noopener\">composables<\/a>. While this can be useful in certain scenarios, it&#8217;s recommended to use a standard like Pinia to ensure consistent patterns across teams.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Component Libraries<\/h2>\n\n\n\n<p>Selecting the right component library depends on your app&#8217;s requirements. Here are some popular libraries that aim to provide accessible components and are backed by good English documentation.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Library\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/primevue.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1936\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/primevue.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/primevue.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/primevue.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/vitepress.dev\/\"><\/a><a href=\"https:\/\/primevue.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">PrimeVue<\/a><\/h4>\n\n\n\n<p>A powerful and flexible component library that contains styled and unstyled components to make it easier to cater to your app&#8217;s needs.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Library\n<\/header>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/radix-vue.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1949\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/radix-vue.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/radix-vue.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/radix-vue.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/www.radix-vue.com\/\">Radix Vue<\/a><\/h4>\n\n\n\n<p>Unstyled and accessible components for building high\u2011quality design systems and web apps in Vue<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Library\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/quasar.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1952\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/quasar.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/quasar.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/quasar.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/quasar.dev\/components\" target=\"_blank\" rel=\"noreferrer noopener\">Quasar Components<\/a><\/h4>\n\n\n\n<p>UI components that follow Material Guidelines for those using <a href=\"https:\/\/quasar.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">Quasar<\/a>.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Library\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vuetify.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1938\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vuetify.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vuetify.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vuetify.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/vuetifyjs.com\/en\/\" target=\"_blank\" rel=\"noreferrer noopener\">Vuetify<\/a><\/h4>\n\n\n\n<p>A longstanding favorite in the Vue community for Material components that has great docs.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Library\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nuxt-ui.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1951\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nuxt-ui.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nuxt-ui.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nuxt-ui.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/ui.nuxtlabs.com\/getting-started\" target=\"_blank\" rel=\"noreferrer noopener\">NuxtLabs UI<\/a><\/h4>\n\n\n\n<p>Fully styled and customizable components for those using <a href=\"https:\/\/www.nuxt.com\" target=\"_blank\" rel=\"noreferrer noopener\">Nuxt<\/a><\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Honorable Mentions<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Library\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/buefy.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1971\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/buefy.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/buefy.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/buefy.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/buefy.org\/\">Buefy<\/a><\/h4>\n\n\n\n<p>For those who love <a href=\"https:\/\/bulma.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Bulma<\/a>, this is in active development for Vue 3.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Library\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/element-plus.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1982\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/element-plus.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/element-plus.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/element-plus.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/element-plus.org\/en-US\/\" target=\"_blank\" rel=\"noreferrer noopener\">Element Plus<\/a> <\/h4>\n\n\n\n<p>A Vue 3 UI Library made by Element team with a strong Chinese and English community.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Library\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/bootstrap-vue.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1981\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/bootstrap-vue.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/bootstrap-vue.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/bootstrap-vue.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/bootstrap-vue.org\/vue3\" target=\"_blank\" rel=\"noreferrer noopener\">BootstrapVue<\/a><\/h4>\n\n\n\n<p>For those who love <a href=\"https:\/\/getbootstrap.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Bootstrap<\/a>, it&#8217;s not fully ready for Vue 3 at the time of publication, but keep an eye on this library.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Library\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vuestic.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1983\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vuestic.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vuestic.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vuestic.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/ui.vuestic.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">Vuestic UI \u2014 Vue 3 UI framework<\/a><\/h4>\n\n\n\n<p>A free and open source UI Library for Vue 3<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Testing<\/h2>\n\n\n\n<p>When it comes to testing your app, here&#8217;s a quick overview of what the community is using.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Unit<\/h3>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Unit Testing\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitest.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1984\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitest.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitest.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitest.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/vitest.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">Vitest<\/a><\/h4>\n\n\n\n<p>No contest here. With most Vue projects being <a href=\"https:\/\/www.vitejs.dev\" target=\"_blank\" rel=\"noreferrer noopener\">Vite<\/a> based, the performance gain here over previous unit testing libraries like <a href=\"https:\/\/jestjs.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Jest<\/a> is hard to ignore.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Component<\/h3>\n\n\n\n<p>There are three primary options for component testing depending on your use case:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Testing\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitest-1.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1985\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitest-1.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitest-1.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vitest-1.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/vitest.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">Vitest<\/a><\/h4>\n\n\n\n<p>Vitest is great for components or composables that render headlessly.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Testing\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/testinglibrary.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-2011\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/testinglibrary.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/testinglibrary.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/testinglibrary.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/testing-library.com\/docs\/vue-testing-library\/intro\/\">Vue Testing Library<\/a><\/h4>\n\n\n\n<p>Vue Testing Library is light-weight solution for testing Vue components that provides light utility functions on top of @vue\/test-utils.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Testing\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1935\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vue.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/test-utils.vuejs.org\/guide\/\" target=\"_blank\" rel=\"noreferrer noopener\">Vue Test Utils<\/a><\/h4>\n\n\n\n<p>Vue Test Utils is another option for testing components and DOM.<\/p>\n\n\n\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Component Testing\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/cypress-thumb.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1987\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/cypress-thumb.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/cypress-thumb.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/cypress-thumb.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/on.cypress.io\/component\" target=\"_blank\" rel=\"noreferrer noopener\">Cypress Component Testing<\/a><\/h4>\n\n\n\n<p>Cypress is great for components whose expected behavior depends on properly rendering styles or triggering native DOM events.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">E2E<\/h3>\n\n\n\n<p>While other tests are great, one of my mentors likes to say that there are only two tests that matter for any code base.&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"1\">\n<li>Can the user login?<\/li>\n\n\n\n<li>Can the user pay us?<\/li>\n<\/ol>\n\n\n\n<p>Everything else is optional. &nbsp;<\/p>\n\n\n\n<p>And that\u2019s where end-to-end (E2E) tests come into play. There are two primary candidates to choose from when selecting your E2E testing framework:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  End to End Testing\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/cypress-thumb-1.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1989\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/cypress-thumb-1.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/cypress-thumb-1.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/cypress-thumb-1.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/www.cypress.io\/\" target=\"_blank\" rel=\"noreferrer noopener\">Cypress<\/a><\/h4>\n\n\n\n<p>Cypress has been a longtime favorite of the community with its intuitive API and ability to run and debug tests directly in the browser.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  End to End Testing\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/playwright.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1990\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/playwright.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/playwright.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/playwright.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><a href=\"https:\/\/playwright.dev\/\" target=\"_blank\" rel=\"noreferrer noopener\">Playwright<\/a><\/h4>\n\n\n\n<p>Playwright has become another popular choice amongst the community as well for its ability to test across any browser or platform using a singular API.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n<\/div>\n\n\n\n<p>For additional reading about testing in Vue, check out the <a target=\"_blank\" href=\"https:\/\/vuejs.org\/guide\/scaling-up\/testing\" rel=\"noreferrer noopener\">official docs<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Mobile Development<\/h2>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Mobile Framework\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/capacitor.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-2001\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/capacitor.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/capacitor.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/capacitor.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><strong><a href=\"https:\/\/capacitorjs.com\/\">Capacitor<\/a><\/strong><\/h4>\n\n\n\n<p>You might be familiar with <a href=\"https:\/\/ionicframework.com\/docs\/\" target=\"_blank\" rel=\"noreferrer noopener\">Ionic<\/a>, a popular open-source UI toolkit for building mobile apps with web technologies. Well, <a href=\"https:\/\/capacitorjs.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">Capacitor<\/a> is the foundation that Ionic is built on top of which enables you to build the actual app.<\/p>\n\n\n\n<p>It&#8217;s also backed by a team that have been great partners to the Vue community. Definitely worth checking out if you want to build a mobile app with Vue.<\/p>\n\n\n\n<p>You can learn more at their <a href=\"https:\/\/capacitorjs.com\/solution\/vue\" target=\"_blank\" rel=\"noreferrer noopener\">official docs for Capacitor + Vue<\/a>.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Mobile Framework\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nativescript.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-2002\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nativescript.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nativescript.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/nativescript.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><strong><a href=\"https:\/\/nativescript.org\/\">NativeScript<\/a><\/strong><\/h4>\n\n\n\n<p>If you&#8217;re looking for a React Native equivalent in Vue, while there is no official support from the core team, NativeScript is a solution for building true native mobile apps with JavaScript.<\/p>\n\n\n\n<p><strong><em>Note: <\/em><\/strong>It&#8217;s currently in release candidate (RC) and not officially production ready, but it has been a past favorite for Vue 2 apps, so it&#8217;s included as an alternative to Capacitor.<\/p>\n\n\n\n<p>To learn more or follow along, check out the <a href=\"https:\/\/github.com\/nativescript-vue\/nativescript-vue\" target=\"_blank\" rel=\"noreferrer noopener\">official repo for NativeScript<\/a><\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Bonus Libraries<\/h2>\n\n\n\n<p>These libraries don&#8217;t have a distinct category of their own, but I wanted to give a special shoutout to the following libraries:<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Bonus\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vueuse.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1991\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vueuse.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vueuse.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/vueuse.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><strong><a href=\"https:\/\/vueuse.org\/\">VueUse<\/a><\/strong><\/h4>\n\n\n\n<p>When it comes to utility libraries, <a href=\"https:\/\/vueuse.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">VueUse<\/a> gets the MVP award for providing an incredible assortment of useful abstractions for common functionality such as copying to clipboard, dark \/ light mode, local storage, and more.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Bonus\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/petitevue.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1998\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/petitevue.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/petitevue.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/petitevue.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><strong><a href=\"https:\/\/github.com\/vuejs\/petite-vue\">Petite-Vue<\/a><\/strong><\/h4>\n\n\n\n<p>For those who need only a subset of Vue features and just want to sprinkle some interactivity onto a page, you definitely want to look into <a href=\"https:\/\/github.com\/vuejs\/petite-vue\" target=\"_blank\" rel=\"noreferrer noopener\">petite-vue<\/a>, which is only ~6kb!&nbsp;<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Bonus\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/formkit.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1992\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/formkit.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/formkit.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/formkit.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><strong><a href=\"https:\/\/formkit.com\/\">FormKit<\/a><\/strong><\/h4>\n\n\n\n<p>Let&#8217;s face it. Forms are a big part of most web apps, whether you like it or not. <a href=\"https:\/\/formkit.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">FormKit<\/a> is a library that aims to make the process easier by providing standards for things like form structure, generation, validation, and more.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group box\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<header>\n  Bonus\n<\/header>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"500\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/tresjs.jpg?resize=1000%2C500&#038;ssl=1\" alt=\"\" class=\"wp-image-1993\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/tresjs.jpg?w=1000&amp;ssl=1 1000w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/tresjs.jpg?resize=300%2C150&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/tresjs.jpg?resize=768%2C384&amp;ssl=1 768w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-group box-content\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<h4 class=\"wp-block-heading\"><strong><a href=\"https:\/\/docs.tresjs.org\/guide\/\">TresJS<\/a><\/strong><\/h4>\n\n\n\n<p><a href=\"https:\/\/docs.tresjs.org\/guide\/\" target=\"_blank\" rel=\"noreferrer noopener\">TresJS<\/a> is a library that aims to make building 3D experiences with <a href=\"https:\/\/threejs.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Three.js<\/a> and Vue a lot easier.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n<\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Looking Ahead<\/h2>\n\n\n\n<p>While I&#8217;ve highlighted some popular solutions in the ecosystem, I want to emphasize that <strong>at the end of the day, what matters most is choosing the right solution for your team and app<\/strong>. If the solution you and\/or your team are using didn&#8217;t make it on this list, that doesn&#8217;t make it any less valid.<\/p>\n\n\n\n<p>Finally, the reality is that the landscape for tooling and libraries is constantly changing. While it may seem like specific problems have &#8220;already been solved,&#8221; I assure you there is still much room for new ideas and improvements. The community is still ripe for contributions, and I hope to recommend something you build someday!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vue has become one of the top JavaScript frameworks for building and maintaining web apps. It is a popular pick for many developers because of its philosophy of creating an approachable, performant, and versatile approach to building scalable apps.<\/p>\n<p>Let\u2019s look at some of the popular tools and libraries used by the community today.<\/p>\n","protected":false},"author":22,"featured_media":1852,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[168],"class_list":["post-1849","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-vue"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2024\/04\/ecosystem-thumb.jpg?fit=1000%2C500&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/1849","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/users\/22"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=1849"}],"version-history":[{"count":34,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/1849\/revisions"}],"predecessor-version":[{"id":2055,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/1849\/revisions\/2055"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/1852"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=1849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=1849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=1849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}