Cascadia is a modern Digital Thread application designed to replace traditional low-code PLM platforms.
27
stars
190
commits
TypeScript
primary language
Sep 6, 2026
updated
A code-first Product Lifecycle Management (PLM) system built with Hono + Vite SPA
Cascadia is a modern PLM system designed to replace traditional low-code PLM platforms like Aras Innovator. It prioritizes developer experience, type safety, and customization through code rather than UI-based configuration.
Signature Feature: ECO-as-Branch - Each Engineering Change Order gets its own isolated branch for parallel development, with Git-style versioning for all engineering data.
https://github.com/user-attachments/assets/fce1368e-19af-463f-95a5-926c3f682022
The fastest way to see Cascadia is the bundled demo stack — Postgres, RabbitMQ, the app (with embedded vault), the CAD converter, and the jobs worker, pre-seeded with a real engineering dataset (TDJ-25 6-DOF robot arm: ~88 parts, 101 BOM relationships, 79 colored GLBs + STEPs). No clone required:
curl -O https://raw.githubusercontent.com/Cascadia-PLM/Cascadia-App/main/docker-compose.demo.yml
docker compose -f docker-compose.demo.yml up -d
First run pulls ~1.2 GB of pre-built images from GitHub Container Registry (2-5 min on a typical connection) and seeds the database. When docker compose -f docker-compose.demo.yml logs app shows the server is listening, open http://localhost:3000 and log in with admin@cascadia.local / Cascadia. Navigate to Programs → ROBOT-ARM → TDJ-25 to explore the BOM tree, click any part with CAD to see the 3D viewer, and check the ECO Initial Release - TDJ-25 Robot Arm to see the signature ECO-as-Branch workflow in its released state.
Reset to a clean slate at any time:
docker compose -f docker-compose.demo.yml down -v
The demo's volumes are namespaced (cascadia_demo_*) and won't touch any local dev data.
Working from a clone instead? Use docker-compose.demo-with-build.yml to build images from your working tree.
# Install dependencies
npm install
# Set up environment
cp .env.example .env
# Edit .env with your database credentials
# Set up database (dev: diff-apply the schema directly)
npm run db:push
npm run db:seed
# Start development server
npm run dev
Visit http://localhost:3000 to see the application. The minimal seed creates a bootstrap admin account (admin@cascadia.local / Cascadia) for local development only — change this password immediately in any shared or production deployment.
For detailed setup instructions, see SETUP.md.
packages/core/src/ # The application
├── components/ # React components (forms, tables, dialogs)
├── lib/
│ ├── auth/ # Authentication & authorization services
│ ├── db/ # Drizzle schema & database utilities
│ ├── items/ # Item services (Parts, Documents, etc.)
│ ├── services/ # Core services (Branch, Checkout, Commit, etc.)
│ ├── workflows/ # Workflow engine
│ ├── jobs/ # Background job dispatch, definitions & worker
│ ├── api/ # API utilities (apiHandler, response builders)
│ ├── vault/ # File storage system
│ ├── sysml/ # SysML v2 serialization
│ ├── ai/ # AI chatbot tools, adapters, session service
│ ├── mcp/ # MCP servers, built on the AI tool registry
│ ├── query/ # TanStack Query keys, options, invalidation graph
│ └── packages/ # Package entitlement registry
├── routes/ # TanStack Router file-based routes (frontend SPA)
├── server/ # Hono API server
│ ├── index.ts # Entry: mounts every route module under /api/v1/*
│ └── routes/ # API route modules — one file per resource
└── __tests__/ # Test utilities and fixtures
apps/cascadia/ # Composition root: entry points and build config
tests/
├── e2e/ # Playwright E2E tests
│ ├── pages/ # Page object models
│ └── fixtures/ # Test fixtures
docs/ # Architecture & feature documentation
scripts/ # Database seeding, deployment scripts
Change Actions: Release (new item), Revise (new revision), Obsolete, Add to BOM, Remove from BOM
All item types extend BaseItem and register via ItemTypeRegistry:
See docs/features/item-types.md for the full reference.
/api/v1/health)Business logic is centralized in services:
// Create a new part
const part = await ItemService.create(
'Part',
{
itemNumber: 'P-1001',
name: 'Widget Assembly',
partType: 'Manufacture',
},
userId,
)
// Checkout to an ECO branch
await CheckoutService.checkout(part.id, ecoId, userId)
// Get item at a specific version context
const versionedPart = await VersionResolver.getItemAtContext(part.masterId, {
branchId,
commitId,
})
# Development
npm run dev # Start dev server on port 3000
npm run build # Build for production
npm run serve # Preview production build
# Database
npm run db:push # Diff-apply schema directly (dev/CI/demo only)
npm run db:generate # Mint migration SQL into apps/cascadia/drizzle/ (CI drift gate)
npm run db:migrate # Apply committed migrations (the upgrade path for released installs)
npm run db:studio # Open Drizzle Studio GUI
npm run db:seed # Minimal seed (admin, roles, program, standard library)
npm run db:reset # Truncate all tables only
npm run db:reset:seed # Truncate all tables + reseed
# Testing
npm run test # Run Vitest tests
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage
npm run test:e2e # Run Playwright E2E tests
npm run test:e2e:ui # Run E2E tests with UI
# Background Jobs (requires Docker)
docker compose up -d rabbitmq
docker compose --profile dev up jobs-worker-dev -d
# Code Quality
npm run lint # ESLint
npm run format # Prettier
npm run check # Format + lint fix
packages/core/src/lib/items/types/packages/core/src/lib/db/schema/items.tsItemTypeRegistrynpm run db:pushALL_TABLES in scripts/truncate-all.tsCascadia supports flexible deployment options:
| Deployment | Best For | Documentation |
|---|---|---|
| Single Server | Development, small teams | docs/orchestration/deployments/single-server/ |
| Distributed | HA, 50+ users | docs/orchestration/deployments/distributed/ |
| Cloud Database | Managed DB (RDS, Cloud SQL) | docs/orchestration/deployments/cloud-database/ |
| Kubernetes | Enterprise, auto-scaling | docs/orchestration/deployments/kubernetes/ |
# Start all services
docker compose up -d
# Start with background job worker
docker compose --profile dev up -d
Required in .env:
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/cascadia
NODE_ENV=development
Optional:
VAULT_ROOT=/path/to/vault # Default: ./vault (a DB storage setting overrides)
RABBITMQ_URL=amqp://localhost # For background jobs
There is no session secret to configure: sessions are opaque random tokens stored hashed in the database.
See .env.example for the full list.
Cascadia has comprehensive test coverage:
npm run test # Run all unit/integration tests
npm run test:e2e # Run Playwright E2E tests
npm run test:coverage # Generate coverage report
Cascadia stores and serves CAD files (STEP, IGES, SolidWorks, and more) through its file vault, with server-side conversion to STL/GLB for in-browser 3D preview. Native CAD connectors (Solid Edge, SolidWorks) that push parts and BOMs directly from CAD are on the roadmap but not yet implemented.
See CONTRIBUTING.md for guidelines. Security issues should be reported per SECURITY.md.
Cascadia is an open-core, dual-licensed project.
The core PLM — parts, BOMs, ECO-as-Branch change management, documents, workflows, vault, search, and APIs — is licensed under the GNU Affero General Public License v3.0 or later, forever, with unlimited users. The AGPL's network-use clause means that if you run a modified version of Cascadia as a service, you must make the source available to users of that service.
If the AGPL doesn't work for your organization, or you need enterprise capabilities (CAD connectors, SSO/AD, compliance pack, the AI Design Engine, support SLAs), a commercial license is available — see LICENSING.md or contact kai@cascadiaplm.com.
Contributions require signing the CLA; see CONTRIBUTING.md.
For usage questions, see the documentation in docs/. For bugs and feature requests, open a GitHub issue.
TypeScript
95.9%
JavaScript
2.3%
Python
1.5%
Cascadia is a modern Digital Thread application designed to replace traditional low-code PLM platforms.
27
stars
190
commits
TypeScript
primary language
Sep 6, 2026
updated
A code-first Product Lifecycle Management (PLM) system built with Hono + Vite SPA
Cascadia is a modern PLM system designed to replace traditional low-code PLM platforms like Aras Innovator. It prioritizes developer experience, type safety, and customization through code rather than UI-based configuration.
Signature Feature: ECO-as-Branch - Each Engineering Change Order gets its own isolated branch for parallel development, with Git-style versioning for all engineering data.
https://github.com/user-attachments/assets/fce1368e-19af-463f-95a5-926c3f682022
The fastest way to see Cascadia is the bundled demo stack — Postgres, RabbitMQ, the app (with embedded vault), the CAD converter, and the jobs worker, pre-seeded with a real engineering dataset (TDJ-25 6-DOF robot arm: ~88 parts, 101 BOM relationships, 79 colored GLBs + STEPs). No clone required:
curl -O https://raw.githubusercontent.com/Cascadia-PLM/Cascadia-App/main/docker-compose.demo.yml
docker compose -f docker-compose.demo.yml up -d
First run pulls ~1.2 GB of pre-built images from GitHub Container Registry (2-5 min on a typical connection) and seeds the database. When docker compose -f docker-compose.demo.yml logs app shows the server is listening, open http://localhost:3000 and log in with admin@cascadia.local / Cascadia. Navigate to Programs → ROBOT-ARM → TDJ-25 to explore the BOM tree, click any part with CAD to see the 3D viewer, and check the ECO Initial Release - TDJ-25 Robot Arm to see the signature ECO-as-Branch workflow in its released state.
Reset to a clean slate at any time:
docker compose -f docker-compose.demo.yml down -v
The demo's volumes are namespaced (cascadia_demo_*) and won't touch any local dev data.
Working from a clone instead? Use docker-compose.demo-with-build.yml to build images from your working tree.
# Install dependencies
npm install
# Set up environment
cp .env.example .env
# Edit .env with your database credentials
# Set up database (dev: diff-apply the schema directly)
npm run db:push
npm run db:seed
# Start development server
npm run dev
Visit http://localhost:3000 to see the application. The minimal seed creates a bootstrap admin account (admin@cascadia.local / Cascadia) for local development only — change this password immediately in any shared or production deployment.
For detailed setup instructions, see SETUP.md.
packages/core/src/ # The application
├── components/ # React components (forms, tables, dialogs)
├── lib/
│ ├── auth/ # Authentication & authorization services
│ ├── db/ # Drizzle schema & database utilities
│ ├── items/ # Item services (Parts, Documents, etc.)
│ ├── services/ # Core services (Branch, Checkout, Commit, etc.)
│ ├── workflows/ # Workflow engine
│ ├── jobs/ # Background job dispatch, definitions & worker
│ ├── api/ # API utilities (apiHandler, response builders)
│ ├── vault/ # File storage system
│ ├── sysml/ # SysML v2 serialization
│ ├── ai/ # AI chatbot tools, adapters, session service
│ ├── mcp/ # MCP servers, built on the AI tool registry
│ ├── query/ # TanStack Query keys, options, invalidation graph
│ └── packages/ # Package entitlement registry
├── routes/ # TanStack Router file-based routes (frontend SPA)
├── server/ # Hono API server
│ ├── index.ts # Entry: mounts every route module under /api/v1/*
│ └── routes/ # API route modules — one file per resource
└── __tests__/ # Test utilities and fixtures
apps/cascadia/ # Composition root: entry points and build config
tests/
├── e2e/ # Playwright E2E tests
│ ├── pages/ # Page object models
│ └── fixtures/ # Test fixtures
docs/ # Architecture & feature documentation
scripts/ # Database seeding, deployment scripts
Change Actions: Release (new item), Revise (new revision), Obsolete, Add to BOM, Remove from BOM
All item types extend BaseItem and register via ItemTypeRegistry:
See docs/features/item-types.md for the full reference.
/api/v1/health)Business logic is centralized in services:
// Create a new part
const part = await ItemService.create(
'Part',
{
itemNumber: 'P-1001',
name: 'Widget Assembly',
partType: 'Manufacture',
},
userId,
)
// Checkout to an ECO branch
await CheckoutService.checkout(part.id, ecoId, userId)
// Get item at a specific version context
const versionedPart = await VersionResolver.getItemAtContext(part.masterId, {
branchId,
commitId,
})
# Development
npm run dev # Start dev server on port 3000
npm run build # Build for production
npm run serve # Preview production build
# Database
npm run db:push # Diff-apply schema directly (dev/CI/demo only)
npm run db:generate # Mint migration SQL into apps/cascadia/drizzle/ (CI drift gate)
npm run db:migrate # Apply committed migrations (the upgrade path for released installs)
npm run db:studio # Open Drizzle Studio GUI
npm run db:seed # Minimal seed (admin, roles, program, standard library)
npm run db:reset # Truncate all tables only
npm run db:reset:seed # Truncate all tables + reseed
# Testing
npm run test # Run Vitest tests
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage
npm run test:e2e # Run Playwright E2E tests
npm run test:e2e:ui # Run E2E tests with UI
# Background Jobs (requires Docker)
docker compose up -d rabbitmq
docker compose --profile dev up jobs-worker-dev -d
# Code Quality
npm run lint # ESLint
npm run format # Prettier
npm run check # Format + lint fix
packages/core/src/lib/items/types/packages/core/src/lib/db/schema/items.tsItemTypeRegistrynpm run db:pushALL_TABLES in scripts/truncate-all.tsCascadia supports flexible deployment options:
| Deployment | Best For | Documentation |
|---|---|---|
| Single Server | Development, small teams | docs/orchestration/deployments/single-server/ |
| Distributed | HA, 50+ users | docs/orchestration/deployments/distributed/ |
| Cloud Database | Managed DB (RDS, Cloud SQL) | docs/orchestration/deployments/cloud-database/ |
| Kubernetes | Enterprise, auto-scaling | docs/orchestration/deployments/kubernetes/ |
# Start all services
docker compose up -d
# Start with background job worker
docker compose --profile dev up -d
Required in .env:
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/cascadia
NODE_ENV=development
Optional:
VAULT_ROOT=/path/to/vault # Default: ./vault (a DB storage setting overrides)
RABBITMQ_URL=amqp://localhost # For background jobs
There is no session secret to configure: sessions are opaque random tokens stored hashed in the database.
See .env.example for the full list.
Cascadia has comprehensive test coverage:
npm run test # Run all unit/integration tests
npm run test:e2e # Run Playwright E2E tests
npm run test:coverage # Generate coverage report
Cascadia stores and serves CAD files (STEP, IGES, SolidWorks, and more) through its file vault, with server-side conversion to STL/GLB for in-browser 3D preview. Native CAD connectors (Solid Edge, SolidWorks) that push parts and BOMs directly from CAD are on the roadmap but not yet implemented.
See CONTRIBUTING.md for guidelines. Security issues should be reported per SECURITY.md.
Cascadia is an open-core, dual-licensed project.
The core PLM — parts, BOMs, ECO-as-Branch change management, documents, workflows, vault, search, and APIs — is licensed under the GNU Affero General Public License v3.0 or later, forever, with unlimited users. The AGPL's network-use clause means that if you run a modified version of Cascadia as a service, you must make the source available to users of that service.
If the AGPL doesn't work for your organization, or you need enterprise capabilities (CAD connectors, SSO/AD, compliance pack, the AI Design Engine, support SLAs), a commercial license is available — see LICENSING.md or contact kai@cascadiaplm.com.
Contributions require signing the CLA; see CONTRIBUTING.md.
For usage questions, see the documentation in docs/. For bugs and feature requests, open a GitHub issue.
TypeScript
95.9%
JavaScript
2.3%
Python
1.5%