# shadcn-ui/ui codebase analysis: How does shadcn-ui CLI work? — Part 1.0

I wanted to find out how shadcn-ui CLI works. In this article, I discuss the code used to build the shadcn-ui/ui CLI. In part 1, we will look at a code snippet picked from [packages/cli/src/index.ts](https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/index.ts).

```javascript
// source: https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/index.ts
#!/usr/bin/env node
import { add } from "@/src/commands/add"
import { diff } from "@/src/commands/diff"
import { init } from "@/src/commands/init"
import { Command } from "commander"

import { getPackageInfo } from "./utils/get-package-info"

process.on("SIGINT", () => process.exit(0))
process.on("SIGTERM", () => process.exit(0))

async function main() {
  const packageInfo = await getPackageInfo()

  const program = new Command()
    .name("shadcn-ui")
    .description("add components and dependencies to your project")
    .version(
      packageInfo.version || "1.0.0",
      "-v, --version",
      "display the version number"
    )

  program.addCommand(init).addCommand(add).addCommand(diff)

  program.parse()
}

main()
```

There’s about 29 lines of code in index.ts

[![](https://cdn-images-1.medium.com/max/1000/1*VW-6XB0rXTGJ6gap_EK_rQ.png align="left")](https://thinkthroo.com/consultation/codebase-architecture-review)

## Imports used

```javascript
#!/usr/bin/env node
import { add } from "@/src/commands/add"
import { diff } from "@/src/commands/diff"
import { init } from "@/src/commands/init"
import { Command } from "commander"

import { getPackageInfo } from "./utils/get-package-info"
```

[Shadcn CLI docs](https://ui.shadcn.com/docs/cli) discuss three commands; add , diff , init

These commands are imported from a folder named [commands in src folder.](https://github.com/shadcn-ui/ui/tree/main/packages/cli/src)

[Commander](https://www.npmjs.com/package/commander) is an npm package used here to enable CLI interactions.

### getPackageInfo

getPackageInfo is a small utility function found in [utils/get-package-info.ts](https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/utils/get-package-info.ts#L5)

![](https://media.licdn.com/dms/image/D5612AQGKuMpgUQAOWg/article-inline_image-shrink_1500_2232/0/1719261554312?e=1724889600&v=beta&t=HcWkx30tuuWehhUq1RHkAHbTO0uD-mKAyVhQAbJKcX8 align="left")

```javascript
import path from "path"
import fs from "fs-extra"
import { type PackageJson } from "type-fest"

export function getPackageInfo() {
  const packageJsonPath = path.join("package.json")

  return fs.readJSONSync(packageJsonPath) as PackageJson
}
```

Notice how there’s an enforced PackageJson type from [type-fest](https://github.com/sindresorhus/type-fest). It is from the Legend, Sindre Sorhus. I see this guy’s name so often when I dig into open source.

[fs.readJSONSync](https://github.com/jprichardson/node-fs-extra/blob/d96f2655f181f1c6b1641711619400140a89d027/docs/readJson-sync.md) reads a JSON file and then parses it into an object. In this case, it is an object of type PackageJson.

```javascript
process.on("SIGINT", () => process.exit(0))
process.on("SIGTERM", () => process.exit(0))
```

**SIGINT:** This is a signal that is typically sent to a process when a user types Ctrl+C in the terminal. It is often used to request that a process terminate gracefully. When a process receives a SIGINT signal, it can catch it and perform any necessary cleanup operations before terminating.

**SIGTERM:** This is a signal that is typically sent to a process by the operating system to request that the process terminate. It is often used as a graceful way to ask a process to terminate, allowing it to perform any necessary cleanup operations before exiting. Processes can catch this signal and perform cleanup operations before terminating. ([Source](https://dev.to/superiqbal7/graceful-shutdown-in-nodejs-handling-stranger-danger-29jo))

## Conclusion:

I have seen Commander.js being used in Next.js create-next-app package, I see it in use here again in shadcn-ui/ui. I will continue picking small code snippets from this CLI package and discuss the code. I liked the way package.json is read using a utility function getPackageInfo. This getPackageInfo uses fs.readJSONSync. There is Type assertion applied using PackageJson provided by type-fest on the Object returned by fs.readJSONSync.

> *Want to learn how to build shadcn-ui/ui from scratch? Check out* [*build-from-scratch*](https://tthroo.com/)

## **About me:**

Hey, my name is [**Ramu Narasinga**](https://ramunarasinga.com/). I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.

***I am open to work on interesting projects. Send me an email at ramu.narasinga@gmail.com***

My Github — [**https://github.com/ramu-narasinga**](https://github.com/ramu-narasinga)

My website — [**https://ramunarasinga.com**](https://ramunarasinga.com/)

My Youtube channel — [**https://www.youtube.com/@thinkthroo**](https://www.youtube.com/@thinkthroo)

Learning platform — [**https://thinkthroo.com**](https://thinkthroo.com/)

Codebase Architecture — [**https://app.thinkthroo.com/architecture**](https://app.thinkthroo.com/architecture)

Best practices — [**https://app.thinkthroo.com/best-practices**](https://app.thinkthroo.com/best-practices)

Production-grade projects — [**https://app.thinkthroo.com/production-grade-projects**](https://app.thinkthroo.com/production-grade-projects)

## References:

1. [https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/index.ts](https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/index.ts)
    
2. [https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/utils/get-package-info.ts#L5](https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/utils/get-package-info.ts#L5)
    
3. [https://dev.to/superiqbal7/graceful-shutdown-in-nodejs-handling-stranger-danger-29jo](https://dev.to/superiqbal7/graceful-shutdown-in-nodejs-handling-stranger-danger-29jo)
