JavaScript Projects

Purpose and Scope

shadcn/ui is authored in TypeScript, and the project documentation recommends TypeScript for applications that can use it. JavaScript projects are still supported through the same CLI-driven component distribution model. The important switch is not a different package, registry, or component catalog; it is a project configuration choice that tells the CLI to write JavaScript component files instead of TypeScript component files. This page explains that choice, how it interacts with aliases, and how to keep the generated component layout consistent with the rest of the installation guides.

Sources: apps/v4/content/docs/(root)/javascript.mdx, apps/v4/content/docs/(root)/components-json.mdx

The JavaScript workflow is most useful when an existing app is already configured around JavaScript, when a team is intentionally avoiding TypeScript, or when a framework template produces JavaScript entrypoints. The components themselves still come from the same shadcn/ui registry and preserve the same composition style, Tailwind CSS integration, theme tokens, and component names. What changes is the emitted file extension and the alias configuration file you use in the application. A JavaScript app should therefore be treated as a normal shadcn/ui project with a JavaScript output mode, not as a separate component system.

Sources: apps/v4/content/docs/(root)/javascript.mdx

Relevant Source Files

  • apps/v4/content/docs/(root)/javascript.mdx — Defines the JavaScript guide, states the TypeScript recommendation, shows the JavaScript opt-out setting, and provides the matching jsconfig.json alias example.
  • apps/v4/content/docs/(root)/components-json.mdx — Documents the components.json fields that matter for JavaScript projects, especially tsx, aliases, tailwind, rsc, style, and iconLibrary.
  • packages/shadcn/src/commands/init.ts — Implements the init/create command surface that creates or initializes projects and exposes framework template options used by the CLI workflow.

Core Configuration

The central project file is components.json. The documentation describes this file as the way the CLI understands the application layout and generates customized components for the project. For JavaScript, the decisive field is tsx. When tsx is set to false, generated components are added as JavaScript using the .jsx file extension. Other fields still matter: style selects the component style, rsc controls React Server Component behavior, tailwind tells the CLI where the CSS entrypoint and theme choices live, iconLibrary selects the icon implementation, and aliases control where generated files and rewritten imports should point.

Sources: apps/v4/content/docs/(root)/components-json.mdx

A typical JavaScript configuration keeps the same structure as a TypeScript configuration but changes the output mode. In the example below, the project uses the new-york style, disables React Server Component assumptions, writes JavaScript components, uses Tailwind CSS with CSS variables, and maps the usual component roots. The exact CSS path should match the application framework; the example uses a source application global stylesheet. If the project was initialized by the CLI, review this file before adding many components so that generated code lands in the intended directories.

Sources: apps/v4/content/docs/(root)/javascript.mdx

components.json
{
  "style": "new-york",
  "rsc": false,
  "tsx": false,
  "tailwind": {
    "config": "",
    "css": "src/app/globals.css",
    "baseColor": "zinc",
    "cssVariables": true
  },
  "iconLibrary": "lucide",
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks"
  }
}

Import Aliases in JavaScript Apps

JavaScript projects normally use jsconfig.json rather than tsconfig.json for editor and bundler path aliases. The JavaScript guide shows a minimal compilerOptions.paths map that resolves the @ prefix to the project root. That alias must agree with the aliases in components.json, because the CLI uses the components.json aliases to place files and rewrite imports when components are added. If those two layers disagree, generated files may be written correctly but imports can fail in the editor or at runtime because the application does not know how to resolve the prefix.

Sources: apps/v4/content/docs/(root)/javascript.mdx, apps/v4/content/docs/(root)/components-json.mdx

jsconfig.json
{
  "compilerOptions": {
    "paths": {
      "@/*": ["./*"]
    }
  }
}

The components.json reference also allows aliases to be backed by package imports, but it emphasizes that CLI aliases remain required. In a JavaScript app, the simplest path is usually to use jsconfig.json paths and keep the common @ based layout. Monorepos or package-import based projects can choose another resolution model, but the same principle applies: the application resolver and the CLI configuration must describe the same roots. Treat aliases as a contract between generated component source, local utilities such as cn, and the rest of the application code.

Sources: apps/v4/content/docs/(root)/components-json.mdx

CLI Workflow

The CLI is the supported way to obtain the JavaScript version of the components. The shadcn init command is defined as a Commander command named init with create as an alias, and its description is to initialize a project and install dependencies. The source exposes options for choosing a framework template, including next, start, vite, react-router, laravel, and astro, along with other initialization options such as defaults, force, reinstall, cssVariables, rtl, pointer, base, and registry base configuration. This matters because JavaScript support is part of the normal initialization and add flow rather than a separate manual download.

Sources: packages/shadcn/src/commands/init.ts, apps/v4/content/docs/(root)/javascript.mdx

For a new project, start from the normal installation path for the framework, then make sure the generated or edited components.json contains tsx set to false before adding components. For an existing JavaScript project, run init to create the project configuration, verify the Tailwind CSS path, verify aliases, and then add components. The components.json page notes that the file is only required when using the CLI; copy-and-paste users do not need it. JavaScript users who rely on the CLI should keep it checked into source control so future component additions remain consistent.

Sources: apps/v4/content/docs/(root)/components-json.mdx, packages/shadcn/src/commands/init.ts

npx shadcn@latest init
npx shadcn@latest add button

Behavior Reference

AreaJavaScript project settingEffect
Component outputtsx falseAdds components with the .jsx extension instead of TypeScript component files.
Alias resolverjsconfig.json compilerOptions.pathsLets the app resolve imports such as @/components and @/lib.
CLI placementcomponents.json aliasesTells the CLI where components, ui, lib, hooks, and utils live.
Tailwind integrationtailwind.css, tailwind.baseColor, tailwind.cssVariablesControls the stylesheet path and generated theme token strategy.
RSC handlingrsc true or falseControls whether the CLI adds client directives for client components.

Several configuration values are effectively initialization choices rather than everyday toggles. The components.json reference states that style, tailwind base color, and CSS variable mode cannot be changed casually after initialization without reinstalling components. JavaScript projects should take those decisions just as seriously as TypeScript projects. Setting tsx false changes the language output, but it does not remove the need to decide on a style, theme token approach, alias layout, or React Server Component behavior. Make these choices before building a large local component library on top of generated files.

Sources: apps/v4/content/docs/(root)/components-json.mdx

Practical Checklist and Next Steps

Before adding components, confirm four things. First, components.json exists if the CLI will be used. Second, tsx is false so generated files are JavaScript. Third, jsconfig.json resolves the same alias prefix used in components.json. Fourth, the Tailwind CSS entry path points at the stylesheet that actually imports Tailwind and receives theme variables. After that, add a small component such as a button and inspect the generated import paths. If the file lands under the expected UI directory and the application can import it without resolver errors, the JavaScript setup is ready for normal component installation.

Sources: apps/v4/content/docs/(root)/javascript.mdx, apps/v4/content/docs/(root)/components-json.mdx

Read the components.json reference next when you need exact field behavior, especially for aliases, Tailwind CSS, React Server Components, and package import resolution. Read the CLI page when you need command-level behavior for init and add. If the project is part of a workspace, also review the monorepo guidance before changing aliases, because the same JavaScript output mode can be combined with workspace-specific import roots. The main rule is simple: JavaScript is selected with tsx false, while the rest of the shadcn/ui workflow remains the standard CLI and registry workflow.

Sources: apps/v4/content/docs/(root)/javascript.mdx, apps/v4/content/docs/(root)/components-json.mdx, packages/shadcn/src/commands/init.ts