Skip to content

Project Structure

Prerequisites: Node.js 22+, npm

Jaypie projects use npm workspaces in a monorepo structure with shared configuration for TypeScript, ESLint, Vitest, and Vite.

project/
β”œβ”€β”€ .github/
β”‚ └── workflows/ # CI/CD workflows
β”œβ”€β”€ packages/
β”‚ β”œβ”€β”€ api/ # Express API package
β”‚ β”œβ”€β”€ cdk/ # CDK infrastructure
β”‚ β”œβ”€β”€ worker/ # Lambda workers
β”‚ └── shared/ # Shared utilities
β”œβ”€β”€ eslint.config.mjs # Root ESLint config
β”œβ”€β”€ lerna.json # Lerna configuration
β”œβ”€β”€ package.json # Root package.json
β”œβ”€β”€ tsconfig.json # Root TypeScript config
└── vitest.config.ts # Root Vitest config
{
"name": "my-project",
"version": "0.0.1",
"private": true,
"type": "module",
"workspaces": [
"packages/*"
],
"scripts": {
"build": "lerna run build",
"clean": "lerna run clean",
"format": "eslint . --fix",
"format:package": "sort-package-json package.json packages/*/package.json",
"lint": "eslint .",
"test": "vitest run",
"typecheck": "lerna run typecheck"
},
"devDependencies": {
"@jaypie/eslint": "latest",
"@jaypie/repokit": "latest",
"@jaypie/testkit": "latest",
"eslint": "^10.0.0",
"lerna": "^8.0.0",
"typescript": "^5.0.0",
"vite": "^5.0.0",
"vitest": "^2.0.0"
}
}
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "independent",
"npmClient": "npm"
}
export { default as default } from "@jaypie/eslint";
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"declaration": true,
"declarationMap": true,
"outDir": "./dist",
"rootDir": "./src"
},
"exclude": ["node_modules", "dist"]
}
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
projects: [
"packages/api",
"packages/worker",
"packages/shared",
],
},
});
{
"name": "@project/api",
"version": "0.0.1",
"type": "module",
"private": true,
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"scripts": {
"build": "vite build && tsc --emitDeclarationOnly",
"clean": "rimraf dist",
"test": "vitest run",
"typecheck": "tsc --noEmit"
}
}
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"]
}
import { defineConfig } from "vite";
import { resolve } from "path";
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, "src/index.ts"),
formats: ["es"],
fileName: "index",
},
rollupOptions: {
external: [/^@aws-sdk/, /^jaypie/, /^@jaypie/],
},
outDir: "dist",
emptyOutDir: true,
},
});
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
environment: "node",
setupFiles: ["@jaypie/testkit/testSetup"],
},
});
Pattern Use Case
*.ts Source files
*.spec.ts Test files (sibling to source)
*.route.ts Express route handlers
*.router.ts Express routers
*.d.ts Type declarations
packages/api/
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ app.ts # Express app
β”‚ β”œβ”€β”€ handler.ts # Lambda entry
β”‚ β”œβ”€β”€ index.ts # Package exports
β”‚ β”œβ”€β”€ routers/
β”‚ β”‚ └── v1.router.ts
β”‚ β”œβ”€β”€ routes/
β”‚ β”‚ β”œβ”€β”€ health.route.ts
β”‚ β”‚ └── health.route.spec.ts
β”‚ └── utils/
β”‚ β”œβ”€β”€ db.ts
β”‚ └── db.spec.ts
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ vite.config.ts
└── vitest.config.ts
Terminal window
# All packages
npm run build # Build all
npm run test # Test all
npm run lint # Lint all
npm run format # Fix lint issues
# Specific package
npm run build -w packages/api
npm run test -w packages/api
Terminal window
# By path (preferred)
npm install express -w packages/api
# By name
npm install express -w @project/api
  1. Create directory:

    Terminal window
    mkdir -p packages/new-package/src
  2. Create package.json (from template)

  3. Add to vitest.config.ts projects array

  4. Install dependencies:

    Terminal window
    npm install -w packages/new-package
Script Purpose
build Compile TypeScript
clean Remove dist
dev Development mode
format Fix lint issues
format:package Sort package.json
lint Check lint
test Run tests
typecheck Check types