How 'npm create vue@latest' works
Tags: vue, webdev, javascript, learning
Published: 2024-05-28 15:04:16

## Introduction

I don't think I'm the only interested in the functionality of this command as presented in the [Vue quickstart documentation](https://vuejs.org/guide/quick-start.html#creating-a-vue-application)

```bash
npm create vue@latest
```

Once we execute this command, we encounter some 'magic' where we select preferences for our future Vue app. But how exactly does it work?

## npm create

This command works very simply. Everyone is used to working with the `npm init` command, so let's look at these logs

![A terminal screenshot depicting the command 'npm create --help.' The image shows the list of available options and their descriptions provided by the 'npm create' command for help and configuration of a new project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5nyv1lobcqlwmjb5r9d1.png)

![A terminal screenshot depicting the command 'npm init --help.' The image shows the list of available options and their descriptions provided by the 'npm init' command for help and configuration of a new project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1qvbo6xygbyscjibfto.png)

Both of them are the same. `npm create` just an alias for `npm init`.  Let's just replace `create` with `init` and we'll get

![Screenshot of a terminal window where the 'npm init vue@latest' command is executed, initiating the setup process for a new Vue.js project using the latest version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8fsiw7nfnqfmiuj3vvwj.png)

> @latest is simply a pointer to the latest version of an npm package. You can try it with any package you desire

Since we now know this, we can read the documentation about `npm init` . Run `npm help init` in your terminal

![Screenshot of a terminal window displaying the output of the 'npm help init' command, showing the documentation and usage instructions for the 'npm init' command](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qczxwdvlrfdxuqq6fef9.png)

As we see here, we can also use `npx` instead of `npm init` but with `create-` prefix:

```bash
npm init <package-spec> (same as `npx <package-spec>`)
npm init <@scope> (same as `npx <@scope>/create`)
```

Let's try `npx` for our case. And then we see

![Screenshot of a terminal window where the 'npx create-vue@latest' command is executed, initiating the setup process for a new Vue.js project using the latest version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pu1w7er5bj2sczqzjoz2.png)

Let's return to `npm init` documentation

![Screenshot of a terminal window that displays information about the 'npm init' command and its aliases without '-create' prefix](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2bdl6hj9zymt2ug5a9u2.png)

The `npx` and `npm exec` commands are very similar, but there's one difference, which you can read about [here](https://docs.npmjs.com/cli/v9/commands/npm-exec#npx-vs-npm-exec). We don't need to understand this to use  **create-vue**

Now I'll call all the known commands and demonstrate that they all produce the same result. When we use `npm create vue@latest`, it's essentially the same as `npm init create-vue@latest` - just an alias

![Screenshot of a terminal window showing the execution of the 'npx create-vue@latest', 'npm exec create-vue@latest', 'npm init vue@latest', 'npm create vue@latest' commands. They all work the same](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a3ikgm0alktrto6ux8ay.png)

Now, I hope you understand the `npm create` functionality. Then let's get to the next point

## bin

Here you can see our test project

![Screenshot of a project opened in VSCode, displaying the file structure and code editor](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ridpmqr492u1x2wamyc8.png)

Let's install prettier for example

```bash
npm i -D prettier
```

![Screenshot of a terminal window showing the installation of Prettier using the command 'npm i -D prettier'](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qr7y11tf07y64pf7kzgj.png)

Now if you open the `node_modules` directory you'll notice a `.bin` directory and a symbolic link called `prettier`. What is it for? You can execute your installed executable packages from `.bin` repository using npm scripts and commands like `npx`

For example let's run `npx prettier . --check`

![The terminal demonstrates running the command 'npx prettier . --check' to check the code formatting using Prettier](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w10l7664od56izrc38sr.png)

It works!

Let's open `node_modules/.bin/prettier` and look at the code

![A screenshot showing the file '.bin/prettier' opened, displaying the executable code inside](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nqwb5q2pxsa5chfibfsv.png)

But what is a symbolic link exactly? It comes from programming and I often liken symbolic links to basic redirects but with greater stability. However, not every package needs a place in `.bin`. Packages like [nodemon](https://www.npmjs.com/package/nodemon), [webpack](https://www.npmjs.com/package/webpack), [gulp](https://www.npmjs.com/package/gulp), [eslint](https://www.npmjs.com/package/eslint) and [create-vue](https://www.npmjs.com/package/create-vue) are found in `.bin` because they need to be executed. On the other hand, packages like [animate.css](https://www.npmjs.com/package/animate.css), [swiper](https://www.npmjs.com/package/swiper) and [express](https://www.npmjs.com/package/express) operate at the application layer, so you won't find them in `.bin` after installation. How does npm determine whether a package is executable or not? It's simple: by using the `bin` property in your `package.json` to specify the executable path. If your package is executable, you can set it accordingly. Let's take a look at prettier's `package.json` file

![A screenshot displaying the contents of the 'package.json' file for the Prettier package](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uruzz5j878s23rnfu0wk.png)

Here you see

```json
"bin": "./bin/prettier.cjs"
```

Let's follow the path `./bin/prettier.cjs` in the prettier package. **Do not** confuse this path with `node_modules/.bin`

![A screenshot depicting the path './bin/prettier.cjs' within the Prettier package, showcasing the file structure and content of the specified file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0iesx4ugbltlaiaqec29.png)

We've seen this somewhere before, haven't we? Open `.bin/prettier` in the root of `node_modules` and you'll see the same code. 

![A screenshot depicting the path './bin/prettier' within the root of 'node_modules' directory, showcasing the file structure and content of the symbolic link](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nr1a2aul6i7h25ewpwue.png)

Prettier has 

```json
"bin": "./bin/prettier.cjs"
```
So npm creates bin repository and insert a symbolic link there that refers to the Prettier package's file inside `bin/prettier.cjs`. And now you understand how symbolic links work in practice :)

> If you remove the `.bin` directory from `node_modules` and try to run `npx prettier .` It'll throw an error `sh: 1: prettier: not found`, regardless of whether you have the `prettier` package installed

## create-vue

Let's remove Prettier with `npm rm prettier` and install `npm i -D create-vue` now. Inside the `.bin` directory, we can see the symbolic link for `create-vue`

![screenshot displays the symbolic link for 'create-vue' inside the '.bin' directory](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y16ewt76uxii6ikx573s.png)

Let's move to `package.json` in `node_modules/create-vue`

![A screenshot showing the 'package.json' file located in the 'node_modules/create-vue' directory](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p1j6eeojxo80pknmk95p.png)

We see `create-vue` bin key that runs outfile.cjs. 

```json
"bin": {
   "create-vue": "outfile.cjs"
},
```

If we open it, we'll notice the same code as in `node_modules/.bin/create-vue` (symbolic link)

![screenshot displays the file 'outfile.cjs' inside the 'create-vue' package](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ie5o0bwbeoqllrsi7lxw.png)

Does that mean we can simply execute `create-vue` from the terminal? Exactly. Just like we can execute `outfile.cjs`. Let's try it

![A screenshot of the terminal with the 'npx create-vue', 'node_modules/.bin/create-vue', 'node_modules/create-vue/outfile.cjs' being executed with the same successful result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3905mkg2x9qa9pxjib4.png)

While using `npm init` or its alias `npm create` provided with the package, npm executes the binary file (bin) with the name of this package during initialization

## Conclusion
I'd like to point out another potential source of confusion. [Vue docs](https://vuejs.org/guide/quick-start.html#creating-a-vue-application) provide a link only to the [create-vue GitHub](https://github.com/vuejs/create-vue) repository. However, if you visit that repository, you won't find an `outfile.js` or any direct similarity with the `create-vue` package we just explored. This is because GitHub primarily stores open-source code for contribution and development purposes. In contrast, npm stores the actual bundled package code that you install. So, it's important not to confuse the GitHub repository with the package as installed via npm

!['create-vue' GitHub repository](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4trh4rpwl1ngo6zii7a8.png)

!['create-vue' npm package](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gqenspgflxze2h87ncz5.png)

Now I hope I've helped you, and you can now understand and explore similar packages such as `create-react-app` or `create svelte@latest` using this guide