Software Design Specification (SDS): Multi-Cloud Serverless Monorepo
1. Overview
This document defines the folder structure, workspace configuration, and conventions for a JavaScript/TypeScript monorepo that hosts serverless functions for AWS Lambda, Azure Functions, Google Cloud Functions, Cloudflare Workers, and Firebase Functions. It ensures clear separation between deployable apps and shared packages, uniform build/deploy contracts, and supports both folder-based and tag-based orchestration.
2. Folder Structure
/
├── apps/ # Deployable units by provider
│ ├── aws/
│ │ ├── users-service/
│ │ │ ├── src/
│ │ │ │ ├── handlers/
│ │ │ │ └── lib/
│ │ │ ├── function.manifest.ts # Metadata: entries, env, tags
│ │ │ ├── serverless.yml # AWS-specific config
│ │ │ ├── webpack.config.js # Bundling to dist/
│ │ │ ├── project.json # Nx/Turbo metadata (tags, targets)
│ │ │ ├── package.json # Scripts: build, deploy, dev, etc.
│ │ │ └── dist/ # Build output (gitignored)
│ │ └── billing-service/…
│ │
│ ├── azure/
│ │ ├── sales-app/
│ │ │ ├── src/functions/ # Azure Functions code
│ │ │ ├── function.manifest.ts
│ │ │ ├── host.json # Azure Functions settings
│ │ │ ├── local.settings.json.example
│ │ │ ├── webpack.config.js
│ │ │ ├── project.json
│ │ │ ├── package.json
│ │ │ └── dist/
│ │ └── ops-app/…
│ │
│ ├── gcp/
│ │ ├── analytics-fn/
│ │ │ ├── src/
│ │ │ ├── function.manifest.ts
│ │ │ ├── webpack.config.js
│ │ │ ├── project.json
│ │ │ ├── package.json
│ │ │ └── dist/
│ │ └── webhooks-fn/…
│ │
│ ├── cloudflare/
│ │ ├── edge-api/
│ │ │ ├── src/
│ │ │ ├── wrangler.toml
│ │ │ ├── function.manifest.ts
│ │ │ ├── esbuild.config.ts
│ │ │ ├── project.json
│ │ │ ├── package.json
│ │ │ └── dist/
│ │ └── image-resize/…
│ │
│ └── firebase/
│ ├── functions/
│ │ ├── src/
│ │ ├── function.manifest.ts
│ │ ├── firebase.json
│ │ ├── .firebaserc
│ │ ├── webpack.config.js
│ │ ├── project.json
│ │ ├── package.json
│ │ └── dist/
│ └── README.md
│
├── packages/ # Shared libraries
│ ├── utils/ # @org/utils
│ │ ├── src/
│ │ ├── project.json
│ │ ├── package.json
│ │ └── dist/
│ ├── auth/ # @org/auth
│ │ └── …
│ └── types/ # @org/types
│ └── …
│
├── configs/ # Reusable config files
│ ├── eslint/
│ │ └── eslint-preset.js
│ ├── prettier/
│ │ └── prettier.config.js
│ ├── ts/
│ │ ├── tsconfig.base.json
│ │ └── tsconfig.build.json
│ ├── webpack/
│ │ ├── webpack.base.js
│ │ ├── webpack.node.js
│ │ └── webpack.worker.js
│ └── env/
│ ├── .env.sample
│ └── README.md
│
├── tools/
│ ├── scripts/ # Utility scripts (zip, verify)
│ └── generators/
│ ├── function/ # Handlebars templates
│ └── plopfile.mjs
│
├── .github/workflows/ # CI/CD workflows
│ ├── ci.yml
│ ├── deploy-aws.yml
│ ├── deploy-azure.yml
│ ├── deploy-gcp.yml
│ ├── deploy-cloudflare.yml
│ └── deploy-firebase.yml
│
├── .gitignore
├── nx.json # Optional for Nx task graph
├── package.json # Root scripts orchestrator
├── pnpm-workspace.yaml # Workspaces: apps/**, packages/**
├── pnpm-lock.yaml
└── README.md
3. Workspaces and Purpose
pnpm-workspace.yaml:
packages:
- "apps/**"
- "packages/**"
- apps/: Contains deployable function-apps/services, each scoped by provider.
- packages/: Contains shared, non-deployable libraries (utils, auth, types).
This split ensures clean dependency boundaries, targeted builds/deploys, and efficient reuse.
4. Root Scripts
Key package.json scripts:
- Selective execution via
--filter enables one-by-one, provider-wide, or full-repo operations.
5. Per-App Conventions
Each app’s package.json must define:
scripts:
build → output dist/
package → bundle/zip artifact
deploy → publish to cloud
dev/start → local emulation
lint, test
function.manifest.ts: high-level metadata (entries, env, tags)
project.json: tags and dependency graph for Nx/Turbo
- Provider config:
serverless.yml, host.json, wrangler.toml, or firebase.json
6. Metadata & Tagging
Use tags in project.json (or package.json custom field) for:
{
"tags": ["provider:aws","domain:users","team:core","type:function-app"]
}
- Enables tag-based filtering:
pnpm -r --filter "tag:provider:aws" run deploy
nx run-many --target=build --tags=provider:azure
7. CI/CD Integration
- Path-based triggers: watch
apps/aws/** for AWS pipelines.
- Caching: pnpm store + dist artifact cache.
- Matrix jobs: per provider or per app using filters.
- Workflow steps:
- Checkout, setup Node & pnpm
pnpm install
pnpm :
8. Next Steps
- Provide base config files (
webpack.base.js, tsconfig.base.json, etc.).
- Implement a minimal CLI to:
- Discover apps by tags
- Scaffold new function apps
- Orchestrate filtered runs
- Optionally onboard Nx or Turborepo for advanced caching and affected calculations.
End of SDS
Software Design Specification (SDS): Multi-Cloud Serverless Monorepo
1. Overview
This document defines the folder structure, workspace configuration, and conventions for a JavaScript/TypeScript monorepo that hosts serverless functions for AWS Lambda, Azure Functions, Google Cloud Functions, Cloudflare Workers, and Firebase Functions. It ensures clear separation between deployable apps and shared packages, uniform build/deploy contracts, and supports both folder-based and tag-based orchestration.
2. Folder Structure
3. Workspaces and Purpose
pnpm-workspace.yaml:
This split ensures clean dependency boundaries, targeted builds/deploys, and efficient reuse.
4. Root Scripts
Key
package.jsonscripts:{ "scripts": { "bootstrap": "pnpm install", "clean": "git clean -fdX -e !pnpm-lock.yaml", "lint": "pnpm -r --filter \"./**\" run lint", "test": "pnpm -r --filter \"./**\" run test", "build": "pnpm -r --filter \"./packages/**\" run build && pnpm -r --filter \"./apps/**\" run build", "package": "pnpm -r --filter \"./apps/**\" run package", "deploy": "pnpm -r --filter \"./apps/**\" run deploy", "deploy:aws": "pnpm -r --filter \"./apps/aws/**\" run deploy", "deploy:azure": "pnpm -r --filter \"./apps/azure/**\" run deploy", "deploy:gcp": "pnpm -r --filter \"./apps/gcp/**\" run deploy", "deploy:cf": "pnpm -r --filter \"./apps/cloudflare/**\" run deploy", "deploy:firebase": "pnpm -r --filter \"./apps/firebase/**\" run deploy" } }--filterenables one-by-one, provider-wide, or full-repo operations.5. Per-App Conventions
Each app’s
package.jsonmust define:scripts:build→ outputdist/package→ bundle/zip artifactdeploy→ publish to clouddev/start→ local emulationlint,testfunction.manifest.ts: high-level metadata (entries, env, tags)project.json: tags and dependency graph for Nx/Turboserverless.yml,host.json,wrangler.toml, orfirebase.json6. Metadata & Tagging
Use tags in
project.json(orpackage.jsoncustom field) for:{ "tags": ["provider:aws","domain:users","team:core","type:function-app"] }pnpm -r --filter "tag:provider:aws" run deploynx run-many --target=build --tags=provider:azure7. CI/CD Integration
apps/aws/**for AWS pipelines.pnpm installpnpm :8. Next Steps
webpack.base.js,tsconfig.base.json, etc.).End of SDS