This project uses a monorepo structure with Turborepo for build orchestration and pnpm workspaces for dependency management.
name-normalization-platform/
├── packages/
│ └── normalization-core/ # @normalization/core - Publishable package
│ ├── src/
│ │ ├── names/ # Name normalization (750+ credentials)
│ │ ├── phones/ # Phone normalization (coming soon)
│ │ ├── emails/ # Email normalization (coming soon)
│ │ ├── companies/ # Company normalization (coming soon)
│ │ ├── addresses/ # Address normalization (coming soon)
│ │ └── common/ # Shared utilities
│ ├── dist/ # Built output (CJS + ESM + types)
│ ├── package.json
│ ├── tsconfig.json
│ ├── tsup.config.ts
│ └── README.md
├── apps/
│ └── web/ # Main web application
│ ├── client/ # React frontend
│ ├── server/ # Express backend
│ ├── public/ # Static assets
│ ├── package.json
│ ├── tsconfig.json
│ └── vite.config.ts
├── shared/ # Legacy (being migrated)
├── turbo.json # Turborepo configuration
├── pnpm-workspace.yaml # pnpm workspace configuration
└── package.json # Root workspace config
- Apps can depend on packages using
workspace:*protocol - Automatic linking during development
- Type-safe imports with full IntelliSense
- Turborepo handles build order automatically
- Caching for faster rebuilds
- Parallel execution where possible
@normalization/coreis ready to publish to npm/GitHub Packages- Semantic versioning
- Automated releases via CI/CD
pnpm install# Run all apps in development mode
pnpm dev
# Build all packages and apps
pnpm build
# Build only packages
pnpm build:packages
# Run tests
pnpm testcd packages/normalization-core
pnpm buildOutput:
dist/*.js- CommonJS modulesdist/*.mjs- ES modulesdist/*.d.ts- TypeScript declarations
# Publish to npm
pnpm publish:core
# Or manually
cd packages/normalization-core
npm publishcd apps/web
pnpm devcd apps/web
pnpm buildnpm install @normalization/core// Import from main entry
import { isCredential, isTitle } from '@normalization/core/names';
// Import specific modules
import { validateEmail } from '@normalization/core/emails';
import { formatPhone } from '@normalization/core/phones';@normalization/core- Main entry point@normalization/core/names- Name normalization@normalization/core/phones- Phone normalization@normalization/core/emails- Email normalization@normalization/core/companies- Company normalization@normalization/core/addresses- Address normalization@normalization/core/common- Shared utilities
{
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"test": {
"dependsOn": ["^build"]
}
}Turborepo caches:
- Build outputs
- Test results
- Lint results
Cache location: .turbo/
- Create package directory:
mkdir -p packages/my-package/src- Create
package.json:
{
"name": "@normalization/my-package",
"version": "1.0.0",
"main": "./dist/index.js",
"types": "./dist/index.d.ts"
}- Add to workspace:
# pnpm-workspace.yaml already includes packages/*- Install dependencies:
pnpm install- Create app directory:
mkdir -p apps/my-app- Create
package.jsonwith dependencies:
{
"name": "@normalization/my-app",
"dependencies": {
"@normalization/core": "workspace:*"
}
}- Install:
pnpm installname: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v3
- run: pnpm install
- run: pnpm build
- run: pnpm testname: Publish
on:
push:
tags: ['v*']
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v3
- run: pnpm install
- run: pnpm build:packages
- run: cd packages/normalization-core && npm publish/client
/server
/shared/normalization
/packages/normalization-core (from /shared/normalization)
/apps/web/client (from /client)
/apps/web/server (from /server)
Before:
import { isCredential } from '../../../shared/normalization/names';After:
import { isCredential } from '@normalization/core/names';- Cold build: ~5s
- Cached build: <1s
- Watch mode: <500ms
@normalization/core: ~35KB (minified)- Tree-shakeable: Only import what you need
-
Always build packages before apps
pnpm build:packages && pnpm build -
Use workspace protocol for internal dependencies
"@normalization/core": "workspace:*"
-
Run tests before committing
pnpm test -
Keep packages focused
- One responsibility per package
- Clear public API
- Comprehensive documentation
-
Version carefully
- Use semantic versioning
- Document breaking changes
- Maintain CHANGELOG.md
# Clean and rebuild
pnpm clean
pnpm install
pnpm build# Rebuild packages
cd packages/normalization-core
pnpm build# Reinstall all dependencies
rm -rf node_modules
rm pnpm-lock.yaml
pnpm installMIT