Create an NPX professional card
Tags: javascript, npx, node, npm
Published: 2024-02-21 11:26:20

While exploring github for ideas to improve my Readme.md, I came across a [repository](https://github.com/anmol098/npx_card) where an NPX card was created, so I decided to test my javascript skills and create my own.

For this I used NPN but feel free to use whatever package manager you like.

<h2> Final result </h2>

By the end of this post, you will have created a card similar to this one.
You can put it however you want.

<h2>Setting it up</h2>
<h3>First steps</h3>
To begin with, let's create a new project.
Open a terminal to start the proyect and run the next commands.
```
mkdir npxcard
cd npxcard
```
This will create a directory with the specified name and move inside this new directory.

At this point, we will install some packages that will make it a little easier to make the card. 

The packages are as follows: boxen, chalk, clear, open and inquirer.
```
npm i  boxen chalk clear open inquirer
```
Nodemon will also be installed to enable reloading on save.
```
npm i nodemon --save-dev
```
Now we will go to the package.json to enable nodemon
```json
 "scripts": {
   "dev": "nodemon index.js"
  }
```
Now we can start with the code!
```
npm run dev
```
<h3>Starting with the code</h3>
Before we start with the code, let's create the structure.
If we don't have the index.js file, we will create it in the root directory.
Now we will create a src folder and inside this new folder two javascrip files: data.js and `content.js`

The final structure will be as follows
![final structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5xxeb0gyu7x4yvd27j2v.png)

Now we can start developing the card.
In `data.js`, we will import chalk and create an object called data to be used in `content.js`.

```js
import chalk from 'chalk'

export const data = {
  name: chalk.bold.white('Mario Canales'),
  tagline: chalk.bold.grey('.NET, Azure, Angular and React developer'),
  location: chalk.bold.grey('Madrid, Spain'),
  github: chalk.hex('#0077B5')('  https://github.com/marioCSan/'),
  linkedin: chalk.white('https://linkedin.com/in/mariocanalessanchez'),
  website: chalk.white(' https://mariocanales.es/'),
  dev: chalk.hex('#0077B5')('   https://dev.to/mariocsan/'),
  labelWebsite: chalk.white.bold('Website:'),
  labelTwitter: chalk.hex('#08a0e9').bold('Twitter:'),
  labelGitHub: chalk.hex('#0077B5').bold('GitHub:'),
  labelLinkedin: chalk.hex('#F6F6F6').bold('Linkedin:'),
  labelDev: chalk.hex('#F6F6F6').bold('Dev.to:')
}
```
This object will indicate which fields will exist, their colour and the website they reference.

In our `content.js`, we will import the dependencies we have imported before.

```js
import boxen from 'boxen'
import chalk from 'chalk'
import open from 'open'
import { data } from './data.js'
```
With all the dependencies imported, we will create the block with the questions. These questions are the options we will give the user to interact with the card.

```js
export const questions = [
  {
    type: 'list',
    name: 'action',
    message: "What do you want to do?",
    choices: [
      {
        name: 'Send me an email',
        value: () => {
          open('mailto:YOUR EMAIL')
          console.log('\nLet\'s connect and explore the realm of technological possibilities!.\n')
        }
      },
      {
        name: 'Know more about my projects',
        value: ()=> {
            open('https://github.com/mariocsan')
            console.log('\nKeep up with my projects.\n')
        }
      },
      {
        name: 'Exit',
        value: () => console.log('Enjoy your day.\n')
      }
    ]
  }
]
```
Let's create another new JavaScript object with data about us.

This will show what the card itself is, you should play around with it a bit to get the right spacing to centre the fields and a more harmonious layout. 

I'll put mine here, as an example.

```js
export const me = boxen(
  [
    `${data.name}`,
    `${data.tagline}`,
    `${data.location}`,
    ``,
    `${data.labelWebsite}  ${data.website}`,
    `${data.labelTwitter}  ${data.twitter}`,
    `${data.labelGitHub}  ${data.github}`,
    `${data.labelLinkedin}  ${data.linkedin}`,
    '',
    `${chalk.bold('.NET Developer with experience turning ideas into exceptional experiences.')}`,
    `${chalk.bold('My focus revolves around technical excellence and creativity to deliver products that not only meet needs but also inspire.')}`,
    '',
    `${chalk.bold('Passionate about crafting innovative solutions that blend technology and user experience.')}`,
    `${chalk.bold('As Elon Musk says, When something is important enough, you do it even if the odds are not in your favor.')}`
  ].join('\n'),
  {
    margin: 1,
    float: 'left',
    padding: 1,
    borderStyle: 'single',
    borderColor: 'white'
  }
)
```
This uses boxen, an npm package that allows you to create a box in the terminal. 
The information is obtained from `data.js`.
At the end you add the styles.

With this, we are done with `content.js`.

Now, in `index.js`, we will create a prompt. We can do this whit [inquirer].
(https://github.com/SBoudrias/Inquirer.js#readme).

```js
console.log(me); //this will show the card

const prompt = inquirer.createPromptModule();
```

After creating the prompt, we are going to use an arrow function with recursion so that it does not leave the npx card when selecting an option.
```js
const runPrompt = () => {
  clear();
  console.log(me);
  prompt(questions).then((answer) => {
    answer.action();
    if (answer.action !== questions[0].choices[2].value) {
      prompt(questions);
      runPrompt();
    }
  });
};

runPrompt();

```

Before running the project, let's add a few changes to `package.json`
```json
{
 
  "main": "index.js",
  "bin": {
    "mariocsan": "./index.js"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/mariocsan/npxcard.git"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon index.js"
  }
}
```
This will add that the binary can be executed when it is published in npmjs.

Now we can execute our local project with `npm run dev`.

![local running](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lzajhxpsfmht5pqiredf.png)

If everything has worked correctly we will be able to publish the package on NPMJS so that anyone can see and use the card.

<h3>Publishing the package</h3>
If you don't have an account at [NPMjs](https://www.npmjs.com/), it's time to create an account.

Now, make sure you are logged in or log in if you don't have an account.

```bash
npm add user
```

Once done, patch the version. 
Remember that every time you want to change the version of the package, you will have to change the version in the `package.json`.

```bash
# Make sure your git working directory is clean!
git commit -a -m "made my npx card"

# Update the version
npm version patch 
```
Now it is time to publish the package. Do it in the following way.

```bash
npm publish
```

If everything went correctly, we can try running the package with npx.
```bash
npx your-pkg
```
And this will happen!

If you have any problems, feel free to ask me in the comments below.

![Demo](https://github.com/MarioCSan/NpxCard/assets/40211718/fd68efd5-3fdd-4392-90e7-b42caefb381b)

<h3>Next steps</h3>
Now it is up to you to improve this card.

Feel free to make any changes you want to adapt it to your needs.

In my case, I will make modifications to add more options like multi lenguage support.

<h3>Acknowledgements</h3>
I want to thank the fortune for crossing the repo of [anmol098](https://github.com/anmol098/) and, of course, anmol098 for the basic idea of making this mini-project.