Skip to content

Shared packages

The three @babyshop packages — shared types, the design system and config — and how the apps use them.

Three packages in packages/ hold the code that more than one app needs. The storefront and admin dashboard depend on them as workspace:*. Changing a type or a colour there updates both apps at once.

  • Directorypackages/
    • Directorytypes/ @babyshop/types — domain and API types, compiled to dist/
      • …
    • Directoryui/ @babyshop/ui — components, design tokens, BrandLogo (source only)
      • …
    • Directoryconfig/ @babyshop/config — shared constants
      • …
Package Used by Build output
@babyshop/types Storefront (about 51 files), admin (1 file) tsc → dist/index.js + .d.ts
@babyshop/ui Storefront, admin None. Apps import the TypeScript source directly
@babyshop/config Listed by the storefront only None
  1. 1Edit packages/*
  2. 2turbo build ^buildtypes → dist/
  3. 3Next transpilestranspilePackages
  4. 4Web + adminsame types, same look
How a shared change reaches the apps

These are the TypeScript shapes of everything the API returns. A Product or Order therefore means the same thing in every app.

Group Exports
Domain User, Vendor, Address, AddressInput, Category, Brand, ProductType, SocialMedia, Review, Product, OrderItem, Order, CartItem, Cart
API and auth ApiResponse, PaginatedResponse, CategoriesResponse, ProductsResponse, LoginCredentials, RegisterCredentials, AuthResponse
CMS pages SectionType, SectionLayout, AutoRule, IHeroBanner, ISectionFilters, IBannerConfig, IPageSection, IResolvedPageSection, IPage, IPageWithSections, INavMenuPage, IProductBase, IProductBaseWithProducts

The package compiles with tsc (Node16 modules, with declarations) into dist/. Apps resolve main and types from that folder, so build the packages before the first run. pnpm setup and pnpm build:packages do this, and so does any Turborepo task that depends on ^build.

packages/types/src/index.ts

This is the BabyMart design system. It has a few shadcn-style components, the colour tokens, and the logo.

  • Components: Button (with buttonVariants), Badge, Input, Label, Textarea, Separator, Skeleton, and the Card family (CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter).
  • Helpers: cn, formatCurrency, formatDate, formatDateTime.
  • Brand: BrandMark, the “Little Bear” SVG drawn with the tokens, and BrandLogo, which is the mark plus the wordmark.
  • Tokens: @babyshop/ui/styles/tokens.css, with :root and .dark CSS variables.

The package ships source only (main is ./src/index.ts, and build is just tsc --noEmit). Each app compiles it as part of its own build.

The colours come from the product photography: cream, chocolate brown and soft peach. Components use the token names (bg-primary, text-muted-foreground), never raw hex values.

Token Light Used for
--background #f9eee8 cream Page background
--foreground / --primary #381c0c chocolate Text and main buttons
--secondary #f6e3d8 peach Soft washes, hover states
--accent #8c4e32 sienna Links and highlights
--muted-foreground #7a6256 Secondary text
--border #eadfd6 Dividers and inputs
--success / --warning / --destructive #2f6b45 / #9a6b1a / #9d2c24 Status colours

.dark swaps these for a dark brown theme with background #1c1410 and foreground #f9eee8.

packages/ui/src/styles/tokens.css packages/ui/src/components/brand-logo.tsx› BrandLogo

It exports three constant objects:

  • API_CONFIG: BASE_URL (from NEXT_PUBLIC_API_URL, falling back to http://localhost:8000) and a map of the main /api/* endpoints.
  • PAYMENT_CONFIG: the Stripe publishable key and the currency USD.
  • APP_CONFIG: the name, description and version.

The storefront lists it in transpilePackages, but no app imports it today. Each app reads its own environment variables instead.

packages/config/src/index.ts
  • Storefront: next.config.mjs has transpilePackages: ["@babyshop/ui", "@babyshop/types", "@babyshop/config"]. app/globals.css imports @babyshop/ui/styles/tokens.css and adds @source "../../../packages/ui/src" so Tailwind sees the package’s classes.
  • Admin dashboard: src/index.css imports the same tokens and its own @source path. Vite compiles the TypeScript source directly.
  • Re-exports: both apps have files in components/ui/ that re-export the shared components, so app code imports from one local path.
  1. Add a type to packages/types/src/index.ts, or a component under packages/ui/src/components/.
  2. Export it. Add it to the package’s src/index.ts. For a new ui component, also add an entry to the exports map in packages/ui/package.json.
  3. Rebuild the types: pnpm build:packages (only types produces output).
  4. Import it in the apps: import type { Product } from "@babyshop/types" or import { Button } from "@babyshop/ui".