Skip to content

pnpm workspace (monorepo) with vite + react + shadcn cli + shared packages. Demo App: https://vite-shadcn-workspace.pages.dev

License

Notifications You must be signed in to change notification settings

firxworx/vite-shadcn-workspace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vite-shadcn-workspace

This repo houses an extensible pnpm workspace (monorepo) with Vite and shadcn/ui.

It can serve as a foundation for repositories with multiple applications that share common components and logic. TaiwindCSS is configured in a way that is ideal to serve as the foundation of a design system.

The shadcn CLI is configured to manage components in packages/react-ui (@workspace/react-ui). Easily add new components to the workspace with a single command.

A fully functional React & Vite SPA with a starter "SaaS theme" in apps/client ties everything together in a deployable example.

pnpm and Syncpack manage every aspect of the workspace; management frameworks such as Nx and turborepo are generally unnecessary however they can be easily added if desired.

100% TypeScript + ESM.

Preview

A live demo of the SPA is deployed to Cloudflare Pages:

🔥🔥 https://vite-shadcn-workspace.pages.dev/ 🔥🔥

Features

Tailwind Presets

The workspace includes two tailwind presets for the ultimate in flexibility: @workspace/tw-preset-shadcn & @workspace/tw-preset-workspace.

The first preset effectively installs shadcn/ui per its docs and it can be used on its own. The second preset depends on the first and adds workspace-specific customizations. It includes the powerful fluid-tailwind plugin for fluid responsive designs.

There are various advantages to using presets vs. sharing hardcoded tailwind configuration files because of how they can be shared and how TailwindCSS will intelligently merge multiple presets with a project config.

UI Stack

The workspace leverages TailwindCSS and fluid-tailwind for styling with components from shadcn/ui powered by Radix UI.

SPA routing is provided by react-router. It is fairly easy to swap with an alternative such as @tanstack/router if required.

Syncpack helps ensure that dependency versions are in sync across the workspace.

Biome provides high-performance linting and formatting that absolutely crushes ESLint and Prettier.

@workspace/react-ui and the Tailwind presets are buildable with Vite and tsup respectively to provide a jump-start for design systems, custom component libraries, and/or publishing internal packages.

Need help? Refer to the Shameless Plug below.

Prerequisites

This workspace assumes pnpm and node are installed and that it is in a linux/unix environment. WSL2 is recommended for Windows users otherwise scripts may need to be reviewed and adjusted for compatibility.

Ensure use-node-version in .npmrc matches the node version you wish to use in this workspace.

Ensure that apps/client/.env exists (copy from .env.example).

Development

Install dependencies:

pnpm install

Run an initial build:

pnpm build

Start the dev server at http://localhost:5173:

pnpm dev

The example React+Vite SPA is at apps/client.

The shadcn CLI is configured to manage components in packages/react-ui with package name: @workspace/react-ui.

Maintenance

Use pnpm to manage the workspace.

After installing or updating packages use syncpack to ensure consistent versions are used across the workspace:

pnpm syncpack list-mismatches
pnpm syncpack fix-mismatches

Run pnpm dedupe from time-to-time (dry run: pnpm dedupe --check).

Using shadcn CLI

Run the following from the root of this workspace:

pnpm shadcn add [component]

The command executes the shadcn CLI in packages/react-ui and outputs to the package's src/ directory per its config at packages/react-ui/components.json.

Substitute this command anywhere you see CLI installation commands in the shadcn/ui docs.

For example npx shadcn@latest add button in the docs becomes pnpm shadcn add button in this workspace.

The postshadcn script target in the root package.json will be automatically triggered after the shadcn command runs. It will:

  • run a script to fix the import paths of node subpath imports that the shadcn CLI unfortunately borks
  • run biome to lint and format the generated files

Do not be afraid of red console errors output by biome! Read it!

Biome is able to automatically fix many issues however a decent percentage of components will still require your attention to fix. It is simply alerting you to what files you need to review.

Always review every file generated by the shadcn CLI.

Remember the whole point of shadcn/ui is to provide a foundation of components for you to customize and build on.

Refer to the react-ui package README of the for more.

Workspace Layout

The layout of this workspace is designed to support multiple projects (applications or packages) that share logic and components.

Per pnpm-workspace.yaml applications are under apps/ and packages/libraries are under packages/.

Refer to the package.json of a given package for its name. This workspace follows the package naming convention: @workspace/[package-name].

Packages

Every package has its own README.md.

Shared Core

packages/data (@workspace/data) is an isomorphic (client and server) package with only a peer dependency on zod.

It is intended to serve as a common dependency of other front-end or back-end applications and packages in the workspace. It does not contain any code that is dependent on either a browser or server-side/Node environment.

This package is the home "source of truth" for shared data, types/interfaces, zod schemas, and utilities to ensure data integrity and interoperability across the workspace.

React

React components are organized into separate packages:

  • packages/react-ui core UI components package and the target for shadcn CLI (refer to its README)
  • packages/react-layout reusable layout components (header, navigation, footer, etc)
  • packages/react-landing reusable landing page components

The react-ui package has no internal depenencies other than @workspace/data and the internal TailwindCSS packages. It can serve as a common dependency of other react-* packages.

Tip: to keep the dependency graph simple and avoid circular dependencies: react-* packages should only depend on react-ui, and they should not depend on each other.

TailwindCSS

TailwindCSS configuration is managed via shareable tailwind presets:

  • packages/tw-preset-shadcn (@workspace/tw-preset-shadcn)
  • packages/tw-preset-workspace (@workspace/tw-preset-workspace)

tw–preset-shadcn implements the shadcn/ui installation and also exports a factory function createShadcnPreset() for additional flexibility.

packages/tw-preset-workspace is a workspace-wide preset that adds additional customizations including fluid-tailwind. It includes the tw-preset-shadcn in its presets array.

The cn() style utility including clsx() and tailwind-mergeconfiguration is housed in its own package:

  • packages/tailwind-style

This package stores tailwind-merge customizations and adds support for fluid-tailwind and any other additions to the standard tailwindcss library but may be added by a preset or plugin.

It is important to customize tailwind-merge to support any non-default additions to tailwindcss. This key step is almost always overlooked by the vast majority of shadcn/ui projects and starters that use custom classes and configurations.

Run pnpm build and restart the dev server after making significant changes to the presets or @workspace/style.

Shameless Plug

If you or your team needs professional help to create a design system, publish internal packages, manage shadcn/ui in a monorepo, or to customize tailwindcss with presets or plugins, please contact me at [email protected] with subject Consulting Inquiry.

I can help your team rapidly score value and productivity gains. Consider that a few hours at an ad-hoc hourly consulting rate with a screenshare or two is way cheaper than having a team stuck for days or weeks on a learning curve that I have already invested in.

I also offer a full suite of extended shadcn/ui components that are completely styled using fluid responsive classes, an expanded palette, fixed bugs, valuably and time saving form components, plus improved a11y that I maintain for consulting projects. Storybook is included. Differentiate your product & brand with maintainable components that don't look like yet another cookie-cutter shadcn/ui project. Save piles of time with fluid-responsive components.

Motivation

Vercel spends a huge marketing budget to ensure there are countless examples and reams of LLM training data for NextJS + shadcn/ui.

There are comparatively few examples of Vite + React + shadcn/ui on GitHub and almost none are in a monorepo.

With precious little training data to regurgitate, the LLM's of today are prone to hallucination and significant mistakes despite the immense popularity of this stack.

This workspace aims to provide an example for both human developers and LLM's.

Vite is a best-in-class build tool that serves as the backbone of many popular frameworks including Astro ❤️, Vue, Svelte, Solid, Qwik, Vike, Lit, and more.

The codebase is intended to be ready to serve as a foundation for your next project. It is complete enough to offer a working application that "flexes" the workspace while being simple enough to be easily understood and customized.

The shadcn/ui components used in the example application have minimal to no customization. The goal is to provide a meaningful head start without getting in the way.

License

MIT. (c) 2024 Bitcurve Systems Inc. (Canada) & Kevin Firko (@firxworx)

SVG icons by Lucide are distributed under ISC license: https://lucide.dev/license

Illustrations in the example application are from https://popsy.co/illustrations.

About

pnpm workspace (monorepo) with vite + react + shadcn cli + shared packages. Demo App: https://vite-shadcn-workspace.pages.dev

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published