Tiny Design is a React component UI library (80+ components) published as @tiny-design/react. It's a pnpm monorepo managed with Turborepo.
packages/react/ → @tiny-design/react (main component library)
packages/tokens/ → @tiny-design/tokens (design tokens, SCSS variables)
packages/icons/ → @tiny-design/icons (SVG icon components)
apps/docs/ → documentation site (Vite + MDX)
All three publishable packages use fixed versioning — they always share the same version number.
pnpm install # Install dependencies
pnpm dev # Start docs dev server
pnpm build # Build all packages (turborepo handles dependency order: tokens → react → docs)
pnpm test # Run all tests
pnpm lint # ESLint across all packages
pnpm lint:style # Stylelint for SCSS filespnpm --filter @tiny-design/react test -- --testPathPattern=button # Test a single component
pnpm --filter @tiny-design/react test:update # Update snapshots
pnpm --filter @tiny-design/react test:coverage # Coverage reportEvery component in packages/react/src/ follows this layout:
component-name/
├── component-name.tsx # Implementation (React.forwardRef, function components)
├── types.ts # Props interfaces
├── index.tsx # Barrel export
├── index.md # English docs
├── index.zh_CN.md # Chinese docs
├── style/
│ ├── _index.scss # Styles (SCSS partial)
│ └── index.tsx # Style entry point
├── demo/
│ └── basic.tsx # Usage examples
└── __tests__/
└── component-name.test.tsx
When adding a new component:
- Create its directory under
packages/react/src/ - Export it from
packages/react/src/index.ts - Add a route in
apps/docs/src/routers.tsx
- TypeScript strict mode is enabled
- CSS class prefix:
ty-(e.g.,.ty-btn,.ty-modal), customizable viaConfigProvider - BEM-ish naming:
ty-component,ty-component__element,ty-component_modifier - Ref forwarding: all components use
React.forwardRef - Props pattern: extend
BaseProps(style, className, prefixCls) + intrinsic element props - Formatting: Prettier — single quotes, semicolons, 100 char width, 2-space indent
- Commits: Conventional Commits —
feat(button): add loading state,fix(modal): prevent scroll - Pre-commit hook: husky + lint-staged auto-fixes SCSS via stylelint
- Framework: Jest + @testing-library/react + @testing-library/jest-dom
- Config:
packages/react/jest.config.js(ts-jest, jsdom environment) - Tests live in
__tests__/within each component directory
The react package build (packages/react):
tsdown— transpiles TS → JS (ESM ines/, CJS inlib/), generates.d.tsbuild-styles.js— compiles component SCSS → CSS via Sass + PostCSSinject-style-imports.js— adds CSS imports into JS entry files
- Use
pnpm changesetto create a changeset file in.changeset/ - On merge to
master, CI creates a "Version Packages" PR - Merging that PR publishes to npm and deploys the docs site
@tiny-design/docsis excluded from npm publishing
- React 18.2+, TypeScript 5.4
- Popper.js (
@popperjs/core) for positioning (tooltips, dropdowns, popovers) react-transition-groupfor animationsclassnamesfor conditional class construction- Node.js >= 22, pnpm 10.x