A stylish command-line business card that showcases your profile with interactive animations and colors. This tool creates a unique way to share your professional information with fellow developers directly from the terminal.
- Animated text and loading effects
- Interactive clickable links
- Color gradients and styled text
- User interaction via menu choices
- Easy to customize with your own information
You can install the CLI business card globally using npm:
npm install -g your-package-nameOr run it directly using npx:
npx your-package-name- Node.js (v16 or later recommended)
- npm or yarn
- Create a new directory and initialize a new npm package:
mkdir my-cli-card
cd my-cli-card
npm init -y- Update your package.json to include:
{
"name": "your-username",
"version": "1.0.0",
"description": "My CLI Business Card",
"main": "index.js",
"type": "module",
"bin": {
"your-username": "cli.js"
},
"files": [
"cli.js",
"index.js",
"lib"
]
}Install the required packages:
npm install chalk chalk-animation figlet gradient-string inquirer nanospinner ora terminal-link minimistOptional packages for enhanced styling:
npm install boxen cliui prettyjsonThis is the entry point for the CLI command:
#!/usr/bin/env node
import minimist from "minimist";
import pkg from "./index.js";
const options = { alias: { json: "j" } };
const argv = minimist(process.argv.slice(2), options);
pkg(argv);import displayBusinessCard from "./lib/data.js";
export default ({ json }) => {
if (json) {
return JSON.stringify({ message: "CLI Business Card" });
}
return displayBusinessCard();
};This is where all the business card functionality is implemented:
import chalk from "chalk";
import figlet from "figlet";
import gradient from "gradient-string";
import ora from "ora";
import chalkAnimation from "chalk-animation";
import { createSpinner } from "nanospinner";
import terminalLink from "terminal-link";
import inquirer from "inquirer";
// Helper functions
const sleep = (ms = 1000) => new Promise((resolve) => setTimeout(resolve, ms));
async function typeWriter(text, delay = 10) {
for (const char of text) {
process.stdout.write(char);
await sleep(delay);
}
process.stdout.write("\n");
}
async function displayBusinessCard() {
console.clear();
const spinner = createSpinner("Loading profile...").start();
await sleep(1500);
spinner.success({ text: "β
Profile loaded!" });
await sleep(500);
// Your personal information
const data = {
name: "Your Name", // Replace with your name
title: "Your Title", // Replace with your title
github: "your-github-username", // Replace with your GitHub username
linkedin: "your-linkedin-username", // Replace with your LinkedIn username
portfolio: "your-website.com", // Replace with your portfolio URL
skills: [
"JavaScript",
"React",
"Node.js",
// Add your skills here
],
urls: [
"https://github.com/your-github-username", // Replace with your GitHub URL
"https://your-website.com", // Replace with your portfolio URL
"https://www.linkedin.com/in/your-linkedin-username", // Replace with your LinkedIn URL
],
};
console.log("\n");
const nameText = figlet.textSync(data.name, {
font: "ANSI Shadow",
horizontalLayout: "fitted",
});
const rainbowTitle = chalkAnimation.rainbow(nameText);
await sleep(1500);
rainbowTitle.stop();
// Info content with typing effects
await typeWriter(
`${chalk.bold("π¨βπ» Title:")} ${chalk.hex("#FF6B6B")(data.title)}`
);
await typeWriter(
`${chalk.bold("π GitHub:")} ${terminalLink(data.github, data.urls[0])}`
);
await typeWriter(
`${chalk.bold("π Portfolio:")} ${terminalLink(
data.portfolio,
data.urls[1]
)}`
);
await typeWriter(
`${chalk.bold("π± LinkedIn:")} ${terminalLink(
data.linkedin,
data.urls[2]
)}\n`
);
await typeWriter(chalk.bold("π οΈ Skills:"));
for (const skill of data.skills) {
await typeWriter(` ${chalk.yellow("β’")} ${chalk.hex("#6BFF6B")(skill)}`);
}
const progressSpinner = ora("Loading inspiration...").start();
await sleep(1500);
progressSpinner.succeed("Inspiration loaded!");
console.log("\n");
await typeWriter(
gradient.pastel('"Add your favorite quote here."')
);
await typeWriter(gradient.cristal("- Quote Author"));
console.log("\n");
await sleep(1000);
console.log(
gradient.rainbow(
"----------------------------------------------------------"
)
);
await typeWriter(
gradient.retro("\nπ Let's build something amazing together!\n")
);
const response = await inquirer.prompt([
{
type: "list",
name: "action",
message: chalk.hex("#FF6B6B")("What would you like to do?"),
choices: [
{ name: gradient.cristal("Visit GitHub"), value: "github" },
{ name: gradient.cristal("View Portfolio"), value: "portfolio" },
{ name: gradient.cristal("Connect on LinkedIn"), value: "linkedin" },
{ name: gradient.cristal("Exit"), value: "exit" },
],
},
]);
switch (response.action) {
case "github":
console.log(chalk.hex("#6BFF6B")(`\nOpening GitHub: ${data.urls[0]}\n`));
break;
case "portfolio":
console.log(
chalk.hex("#6BFF6B")(`\nOpening Portfolio: ${data.urls[1]}\n`)
);
break;
case "linkedin":
console.log(
chalk.hex("#6BFF6B")(`\nOpening LinkedIn: ${data.urls[2]}\n`)
);
break;
case "exit":
default:
const goodbyeSpinner = createSpinner("Preparing to exit...").start();
await sleep(1000);
goodbyeSpinner.success({ text: "π Thanks for visiting!" });
console.log(gradient.rainbow("\nSee you next time!\n"));
}
}
export default displayBusinessCard;
if (import.meta.url === `file://${process.argv[1]}`) {
displayBusinessCard().catch(console.error);
}-
Open
lib/data.jsand update thedataobject with your personal information:- Name
- Title
- GitHub username
- LinkedIn username
- Portfolio URL
- Skills
- URLs for links
-
Customize the styling:
- Change color schemes by modifying hex values
- Try different figlet fonts (run
figlet -lto see available fonts) - Add or remove features based on your preferences
Run your business card to make sure it works as expected:
node cli.js- Make sure you have an npm account. If not, create one:
npm adduser- Log in to your npm account:
npm login- (optional) after making changes and publishing a new version
npm version major- Publish your package:
npm publishNote: Make sure your package name is unique and not already taken on npm.
After publishing, you can run your business card using:
npx your-usernameOr install it globally:
npm install -g your-username
your-usernameIf you want to use boxen for a boxed layout, uncomment and use the boxen code in the data.js file:
import boxen from "boxen";
// Later in your code:
const infoBox = boxen(infoContent, {
padding: 1,
margin: 1,
borderStyle: "double",
borderColor: "#FF6B6B",
backgroundColor: "#1A1A1A",
});
console.log(infoBox);You can enhance your business card with more interactive features:
- Add more menu options
- Include animated progress bars
- Add ASCII art or logos
- Include a small game or puzzle
Experiment with different animations from chalk-animation:
- rainbow
- pulse
- glitch
- radar
- neon
- karaoke
If terminal links aren't working, make sure you're using a terminal that supports links, like iTerm2, modern versions of Terminal.app, or Windows Terminal.
If colors aren't displaying correctly, check your terminal's color support. Modern terminals should support most colors, but some may have limitations.
This project is licensed under the MIT License - see the LICENSE file for details.
- Inspiration from sindresorhus/cli-boxes
- Terminal styling packages by Sindre Sorhus
