{"id":1567,"date":"2026-08-19T21:59:26","date_gmt":"2026-08-19T21:59:26","guid":{"rendered":"https:\/\/www.projectimmerse.com\/blog\/?p=1567"},"modified":"2026-08-19T22:06:29","modified_gmt":"2026-08-19T22:06:29","slug":"getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup","status":"publish","type":"post","link":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/","title":{"rendered":"Getting Started with Vue 3: From npm create vue to Understanding script setup"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup-1024x1024.png\" alt=\"Getting Started with Vue 3 tutorial covering npm create vue and script setup\" class=\"wp-image-1570\" srcset=\"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup-1024x1024.png 1024w, https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup-300x300.png 300w, https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup-150x150.png 150w, https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup-768x768.png 768w, https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup-100x100.png 100w, https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup.png 1254w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><figcaption class=\"wp-element-caption\">Getting started with Vue 3, from creating a new project to understanding script setup.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If you&#8217;re brand new to Vue and just ran your first <code>npm create vue@latest<\/code> command, congratulations \u2014 you&#8217;ve officially joined the club of developers staring at a terminal wondering what half the prompts mean. Don&#8217;t worry, that&#8217;s normal. Vue&#8217;s scaffolding tool asks a lot of questions for something that&#8217;s supposed to be &#8220;quick start.&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this post, we&#8217;ll walk through two things: how to actually get a new Vue project up and running, and what&#8217;s going on inside that mysterious <code>&lt;script setup&gt;<\/code> block once you open your first component file.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Scaffolding a New Vue Project<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Vue&#8217;s official scaffolding tool is called <code>create-vue<\/code>, and you kick it off with:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nnpm create vue@latest\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This tells npm: &#8220;go fetch the latest version of the Vue project generator and run it.&#8221; If you ever need a specific version instead of whatever is newest, just swap <code>latest<\/code> for the version number:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nnpm create vue@3.17.0\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Pinning a version like this is handy if you&#8217;re following a tutorial (like this one!) and want your setup to match exactly, rather than getting surprised by a newer version that changed the prompts on you.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Project Name Prompt<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The first thing the tool asks is:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nProject name (target directory):\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This is asking where to put your new project. If you type a name, it creates a new folder with that name. If you&#8217;re already sitting inside the folder you want to use, you can just type a single period (<code>.<\/code>) to mean &#8220;right here.&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If that folder already has files in it, you&#8217;ll get a follow-up question:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nCurrent directory is not empty. Remove existing files and continue?\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Answering &#8220;Yes&#8221; wipes out whatever&#8217;s currently in that folder and starts fresh. Answer carefully here \u2014 this step is basically npm asking &#8220;are you sure?&#8221; before it deletes things, so don&#8217;t be the person who says yes without checking first.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Package Name Prompt (and Why It Rejects You)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Next up:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nPackage name:\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This one trips up a lot of beginners, mostly because the error message it throws \u2014 <code>Invalid package.json name<\/code> \u2014 doesn&#8217;t explain what actually went wrong. Here&#8217;s the deal: this value becomes the <code>name<\/code> field inside your project&#8217;s <code>package.json<\/code> file, and npm package names have some strict formatting rules. They&#8217;re picky in a way that feels oddly personal:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>All lowercase \u2014 no capital letters allowed<\/li>\n\n\n\n<li>No spaces<\/li>\n\n\n\n<li>Only letters, numbers, hyphens (<code>-<\/code>), and underscores (<code>_<\/code>)<\/li>\n\n\n\n<li>Can&#8217;t start with a dot or an underscore<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">So if you typed something like &#8220;My Vue App&#8221; or hit Enter with nothing typed at all, that&#8217;s why it rejected you. The fix is simple \u2014 just type a valid, lowercase, hyphenated name, like:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nlearn-vue\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This name is really just metadata. It doesn&#8217;t get published anywhere unless you later run <code>npm publish<\/code>, and it has zero effect on how your app actually runs. For a personal or learning project, it genuinely does not matter what you call it \u2014 just get past the prompt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Rest of the Setup Questions<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">After that, <code>create-vue<\/code> walks you through a series of yes\/no feature toggles, such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add TypeScript?<\/li>\n\n\n\n<li>Add JSX support?<\/li>\n\n\n\n<li>Add Vue Router (for multi-page navigation)?<\/li>\n\n\n\n<li>Add Pinia (for state management)?<\/li>\n\n\n\n<li>Add Vitest (for unit testing)?<\/li>\n\n\n\n<li>Add an End-to-End testing solution?<\/li>\n\n\n\n<li>Add ESLint (for catching code issues)?<\/li>\n\n\n\n<li>Add Prettier (for auto-formatting code)?<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">As a beginner, it&#8217;s completely fine to say no to most of these and add them later once you know you actually need them. There&#8217;s no prize for enabling everything on your first try.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Installing and Running Your App<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Once the scaffolding finishes, move into your project folder, install the dependencies, and start the dev server:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ncd learn-vue\nnpm install\nnpm run dev\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Vite (the tool powering Vue&#8217;s dev server) will spin up a local server and give you a URL to open in your browser, usually something like <code>http:\/\/localhost:5173\/<\/code>. If that port happens to be busy, Vite will simply try the next one \u2014 5174, 5175, and so on \u2014 until it finds one that&#8217;s free. Just use whichever URL shows up in your terminal.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Understanding &lt;script setup&gt;<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/vue-3-script-setup-ref-reactivity-example-1024x1024.png\" alt=\"Vue 3 script setup example showing ref, reactivity, createApp, and Vue Composition API concepts\" class=\"wp-image-1573\" srcset=\"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/vue-3-script-setup-ref-reactivity-example-1024x1024.png 1024w, https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/vue-3-script-setup-ref-reactivity-example-300x300.png 300w, https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/vue-3-script-setup-ref-reactivity-example-150x150.png 150w, https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/vue-3-script-setup-ref-reactivity-example-768x768.png 768w, https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/vue-3-script-setup-ref-reactivity-example-100x100.png 100w, https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/vue-3-script-setup-ref-reactivity-example.png 1254w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption class=\"wp-element-caption\">A visual introduction to Vue 3 concepts including script setup, ref(), createApp(), and reactive state.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Once your project is running, open up a component file and you&#8217;ll likely see something like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;script setup&gt;\nimport { ref } from &#039;vue&#039;\n\nconst name = ref(&#039;Mark&#039;)\n\nimport Header from &#039;@\/components\/Header.vue&#039;\nimport Footer from &#039;@\/components\/Footer.vue&#039;\n&lt;\/script&gt;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><code>&lt;script setup&gt;<\/code> is a special shorthand syntax for Vue 3&#8217;s Composition API. It exists purely to save you from typing a bunch of boilerplate. Here&#8217;s the &#8220;long way&#8221; of writing the exact same logic:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: haskell; title: ; notranslate\" title=\"\">\n&lt;script&gt;\nimport { ref } from &#039;vue&#039;\n\nexport default {\n  setup() {\n    const name = ref(&#039;Mark&#039;)\n    return { name } \/\/ manually expose it to the template\n  }\n}\n&lt;\/script&gt;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Both versions do the same thing, but <code>&lt;script setup&gt;<\/code> skips two annoying steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>You don&#8217;t need to manually <code>return<\/code> every variable you want your template to see \u2014 anything declared at the top level is automatically available.<\/li>\n\n\n\n<li>Imported components (like <code>Header<\/code> and <code>Footer<\/code> above) are automatically registered \u2014 no need for a separate <code>components: { Header, Footer }<\/code> object.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">So in the example, <code>name<\/code>, <code>Header<\/code>, and <code>Footer<\/code> are all immediately usable inside your <code>&lt;template&gt;<\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;template&gt;\n  &lt;Header \/&gt;\n  &lt;p&gt;Hello, {{ name }}&lt;\/p&gt;\n  &lt;Footer \/&gt;\n&lt;\/template&gt;\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Actually Happening Under the Hood: createApp and setup()<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you&#8217;ve seen Vue used without a build tool (say, loaded straight from a CDN), you might run into code like this instead:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nconst { createApp, ref } = Vue\n\ncreateApp({\n    setup() {\n        const emoji = ref(&quot;\ud83c\udf3c&quot;)\n        const status_code = ref(&quot;500&quot;)\n        const status_message = ref(&quot;Server is sleeping.&quot;)\n\n        return { emoji, status_code, status_message }\n    }\n}).mount(&quot;#app&quot;)\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This looks like a lot at once, so let&#8217;s pull it apart layer by layer.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Pulling tools out of Vue<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nconst { createApp, ref } = Vue\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This grabs two things out of the Vue library: <code>createApp<\/code>, which builds a Vue application, and <code>ref<\/code>, which makes a value &#8220;reactive&#8221; \u2014 meaning Vue watches it for changes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. The nesting, unpacked<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The part that confuses most beginners is this structure:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\ncreateApp({\n    setup() {\n        \/\/ code here\n    }\n}).mount(&quot;#app&quot;)\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Strip away the Vue-specific meaning, and the shape is just this generic pattern:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nsomeFunction({\n    key: function() { ... }\n}).anotherFunction()\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In other words: call <code>createApp(...)<\/code>, pass it one argument \u2014 a configuration object \u2014 and that object has a property called <code>setup<\/code> whose value is a function. <code>createApp(...)<\/code> then returns something, and you immediately call <code>.mount(\"#app\")<\/code> on whatever got returned.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>setup<\/code> isn&#8217;t some independent, floating function. It&#8217;s just a property on the config object, the same way <code>emoji<\/code> is a property on <code>{ emoji, status_code, status_message }<\/code> later in the code. Vue&#8217;s config object can hold other properties too, like <code>components<\/code> or <code>methods<\/code> \u2014 <code>setup<\/code> just happens to be where your data and logic live.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. Why .mount() comes right after<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is called <strong>chaining<\/strong>. <code>createApp({ ... })<\/code> doesn&#8217;t just run and disappear into the void \u2014 it returns an app object, and that object has its own <code>.mount()<\/code> method sitting on it. Written out separately, it looks like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nconst myApp = createApp({\n    setup() {\n        \/\/ ...\n    }\n})\n\nmyApp.mount(&quot;#app&quot;)\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><code>createApp<\/code> builds the app and hands it back to you. <code>.mount<\/code> is a separate step you then call on that result. They&#8217;re just squished onto one line for convenience.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4. Reactive variables with ref()<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nconst emoji = ref(&quot;\ud83c\udf3c&quot;)\nconst status_code = ref(&quot;500&quot;)\nconst status_message = ref(&quot;Server is sleeping.&quot;)\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><code>ref(...)<\/code> wraps a plain value in a special reactive container \u2014 think of it as a labeled box that Vue keeps a close eye on. If the value inside ever changes, Vue automatically updates every place that value is displayed on the page. No manual DOM updates, no <code>document.getElementById<\/code> nonsense.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5. Returning data to the template<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nreturn { emoji, status_code, status_message }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This is the connector between your logic and your HTML. Whatever you return from <code>setup()<\/code> becomes available in the template, which is why you can write:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;span&gt;{{ emoji }}&lt;\/span&gt;\n&lt;h1&gt;{{ status_code }}&lt;\/h1&gt;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Those double curly braces are Vue&#8217;s way of saying &#8220;put the value of this variable here.&#8221; Right now, none of these values change, so you won&#8217;t actually see the reactivity in action \u2014 but if a button later updated <code>status_code.value<\/code>, the <code>&lt;h1&gt;<\/code> on the page would update instantly, with zero additional code required.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In plain English, all of this together says: create a Vue app, give it some reactive data, hand that data to the HTML so it can be displayed, and attach the whole thing to a specific spot in the page. <code>&lt;script setup&gt;<\/code> is just Vue&#8217;s way of letting you skip the ceremony and get straight to the good part \u2014 writing logic that actually does something.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once this clicks, the rest of Vue starts to feel a lot less like memorizing magic incantations and a lot more like, well, just JavaScript with some very helpful reactivity built in.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;re brand new to Vue and just ran your first npm create vue@latest command, congratulations \u2014 you&#8217;ve officially joined the club of developers staring at a terminal wondering what half the prompts mean. Don&#8217;t worry, that&#8217;s normal. Vue&#8217;s scaffolding tool asks a lot of questions for something that&#8217;s supposed to be &#8220;quick start.&#8221; In &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Getting Started with Vue 3: From npm create vue to Understanding script setup&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[62],"tags":[],"class_list":["post-1567","post","type-post","status-publish","format-standard","hentry","category-tutorials-how-to-guides"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Getting Started with Vue 3: From npm create vue to Understanding script setup - Project Immerse<\/title>\n<meta name=\"description\" content=\"New to Vue 3? Learn how to scaffold a project with npm create vue@latest and finally understand what , createApp, and ref() actually do.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Getting Started with Vue 3: From npm create vue to Understanding script setup - Project Immerse\" \/>\n<meta property=\"og:description\" content=\"New to Vue 3? Learn how to scaffold a project with npm create vue@latest and finally understand what , createApp, and ref() actually do.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/\" \/>\n<meta property=\"og:site_name\" content=\"Project Immerse\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-19T21:59:26+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-19T22:06:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup-1024x1024.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"1024\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"projectimmerse\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"projectimmerse\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/\"},\"author\":{\"name\":\"projectimmerse\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/#\\\/schema\\\/person\\\/c53f2864be524ee6fa08a7e4800dd1e5\"},\"headline\":\"Getting Started with Vue 3: From npm create vue to Understanding script setup\",\"datePublished\":\"2026-08-19T21:59:26+00:00\",\"dateModified\":\"2026-08-19T22:06:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/\"},\"wordCount\":1278,\"image\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/getting-started-vue-3-npm-create-vue-script-setup-1024x1024.png\",\"articleSection\":[\"Tutorials &amp; How-To Guides\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/\",\"url\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/\",\"name\":\"Getting Started with Vue 3: From npm create vue to Understanding script setup - Project Immerse\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/getting-started-vue-3-npm-create-vue-script-setup-1024x1024.png\",\"datePublished\":\"2026-08-19T21:59:26+00:00\",\"dateModified\":\"2026-08-19T22:06:29+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/#\\\/schema\\\/person\\\/c53f2864be524ee6fa08a7e4800dd1e5\"},\"description\":\"New to Vue 3? Learn how to scaffold a project with npm create vue@latest and finally understand what , createApp, and ref() actually do.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/getting-started-vue-3-npm-create-vue-script-setup.png\",\"contentUrl\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/getting-started-vue-3-npm-create-vue-script-setup.png\",\"width\":1254,\"height\":1254},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Getting Started with Vue 3: From npm create vue to Understanding script setup\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/\",\"name\":\"Project Immerse\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/#\\\/schema\\\/person\\\/c53f2864be524ee6fa08a7e4800dd1e5\",\"name\":\"projectimmerse\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g\",\"caption\":\"projectimmerse\"},\"url\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/author\\\/projectimmerse\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Getting Started with Vue 3: From npm create vue to Understanding script setup - Project Immerse","description":"New to Vue 3? Learn how to scaffold a project with npm create vue@latest and finally understand what , createApp, and ref() actually do.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/","og_locale":"en_US","og_type":"article","og_title":"Getting Started with Vue 3: From npm create vue to Understanding script setup - Project Immerse","og_description":"New to Vue 3? Learn how to scaffold a project with npm create vue@latest and finally understand what , createApp, and ref() actually do.","og_url":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/","og_site_name":"Project Immerse","article_published_time":"2026-08-19T21:59:26+00:00","article_modified_time":"2026-08-19T22:06:29+00:00","og_image":[{"width":1024,"height":1024,"url":"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup-1024x1024.png","type":"image\/png"}],"author":"projectimmerse","twitter_card":"summary_large_image","twitter_misc":{"Written by":"projectimmerse","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/#article","isPartOf":{"@id":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/"},"author":{"name":"projectimmerse","@id":"https:\/\/www.projectimmerse.com\/blog\/#\/schema\/person\/c53f2864be524ee6fa08a7e4800dd1e5"},"headline":"Getting Started with Vue 3: From npm create vue to Understanding script setup","datePublished":"2026-08-19T21:59:26+00:00","dateModified":"2026-08-19T22:06:29+00:00","mainEntityOfPage":{"@id":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/"},"wordCount":1278,"image":{"@id":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/#primaryimage"},"thumbnailUrl":"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup-1024x1024.png","articleSection":["Tutorials &amp; How-To Guides"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/","url":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/","name":"Getting Started with Vue 3: From npm create vue to Understanding script setup - Project Immerse","isPartOf":{"@id":"https:\/\/www.projectimmerse.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/#primaryimage"},"image":{"@id":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/#primaryimage"},"thumbnailUrl":"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup-1024x1024.png","datePublished":"2026-08-19T21:59:26+00:00","dateModified":"2026-08-19T22:06:29+00:00","author":{"@id":"https:\/\/www.projectimmerse.com\/blog\/#\/schema\/person\/c53f2864be524ee6fa08a7e4800dd1e5"},"description":"New to Vue 3? Learn how to scaffold a project with npm create vue@latest and finally understand what , createApp, and ref() actually do.","breadcrumb":{"@id":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/#primaryimage","url":"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup.png","contentUrl":"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2026\/08\/getting-started-vue-3-npm-create-vue-script-setup.png","width":1254,"height":1254},{"@type":"BreadcrumbList","@id":"https:\/\/www.projectimmerse.com\/blog\/getting-started-with-vue-3-from-npm-create-vue-to-understanding-script-setup\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.projectimmerse.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Getting Started with Vue 3: From npm create vue to Understanding script setup"}]},{"@type":"WebSite","@id":"https:\/\/www.projectimmerse.com\/blog\/#website","url":"https:\/\/www.projectimmerse.com\/blog\/","name":"Project Immerse","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.projectimmerse.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.projectimmerse.com\/blog\/#\/schema\/person\/c53f2864be524ee6fa08a7e4800dd1e5","name":"projectimmerse","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g","caption":"projectimmerse"},"url":"https:\/\/www.projectimmerse.com\/blog\/author\/projectimmerse\/"}]}},"_links":{"self":[{"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/posts\/1567","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/comments?post=1567"}],"version-history":[{"count":5,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/posts\/1567\/revisions"}],"predecessor-version":[{"id":1575,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/posts\/1567\/revisions\/1575"}],"wp:attachment":[{"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/media?parent=1567"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/categories?post=1567"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/tags?post=1567"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}