Blog
shadcn-ui/ui codebase analysis: How does shadcn-ui CLI work? — Part 2.1

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

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.0 and part 1.1, I discussed the code written in packages/cli/src/index.ts. In part 2.0, I talked about how the commander.js is used along with zod to parse the CLI argument passed. In Part 2.1, we will look at few more lines of code.

const cwd = path.resolve(options.cwd)

// Ensure target directory exists.
if (!existsSync(cwd)) {
  logger.error(`The path ${cwd} does not exist. Please try again.`)
  process.exit(1)
}

preFlight(cwd)

We will look at below concepts based on the code snippet above:

  1. path.resolve

  2. Ensure target directory exists

  3. preFlight function

  4. fg.glob

path.resolve

The path.resolve() method resolves a sequence of paths or path segments into an absolute path. (Source)

cwd is a CLI option that you pass when you run the shadcn-ui/ui init command.

The official CLI docs has the below options for the init command.

Usage: shadcn-ui init [options]

initialize your project and install dependencies

Options:
  -y, --yes        skip confirmation prompt. (default: false)
  -c, --cwd <cwd>  the working directory. defaults to the current directory.
  -h, --help       display help for command

Ensure target directory exists

// Ensure target directory exists.
if (!existsSync(cwd)) {
  logger.error(`The path ${cwd} does not exist. Please try again.`)
  process.exit(1)
}

This code snippet is self explanatory, it checks if the target directory exists; if it does not, the code logs the message and process exits.

import { existsSync, promises as fs } from "fs"

existsSync is an import function from “fs”.

preFlight function

preFlight is a function that checks that tailwind.config.* file exists, otherwise throws an error.

fg.glob

import fg from "fast-glob"

preFlight validates that tailwind.config.* file exists by using function named glob.

// We need Tailwind CSS to be configured.
const tailwindConfig = await fg.glob("tailwind.config.*", {
  cwd,
  deep: 3,
  ignore: PROJECT_SHARED_IGNORE,
})

fast-glob is a package that provides methods for traversing the file system and returning pathnames that matched a defined set of a specified pattern according to the rules used by the Unix Bash shell with some simplifications, meanwhile results are returned in arbitrary order. Quick, simple, effective. (source)

Conclusion:

We looked at few more lines of code from init.ts command related file. There a couple of safeguarding techniques here, one is if the target directory does not exist, exit the proccess and log an error and the second one is, detecing the tailwind.config.* using fast-glob package since tailwind is required for shadcn-ui to work properly.

Never forget to put your defensive mechanism in case the program fails as it is not always guaranteed to execute successfully.

Want to learn how to build shadcn-ui/ui from scratch? Check out build-from-scratch

About me:

Hey, my name is Ramu Narasinga. 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

My website — https://ramunarasinga.com

My Youtube channel — https://www.youtube.com/@thinkthroo

Learning platform — https://thinkthroo.com

Codebase Architecture — https://app.thinkthroo.com/architecture

Best practices — https://app.thinkthroo.com/best-practices

Production-grade projects — https://app.thinkthroo.com/production-grade-projects

References

  1. https://www.npmjs.com/package/fast-glob

  2. https://nodejs.org/api/path.html#pathrelativefrom-to

  3. https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/commands/init.ts

  4. https://github.com/shadcn-ui/ui/blob/main/packages/cli/src/utils/get-project-info.ts#L179