Skip to content

Add Typescript support for crossplane projects #169

Description

@stevendborrelli

What problem are you facing?

Add TypeScript Support for Composition Functions under Projects

Summary

Add first-class TypeScript support to the Crossplane CLI, enabling developers to write composition functions in TypeScript with full type safety for Crossplane resources.

Background

The TypeScript ecosystem for Crossplane composition functions is maturing and covers the Crossplane function SDK, model generation and template project:

  • function-sdk-typescript- TypeScript SDK for writing composition functions, published as @crossplane-org/function-sdk-typescript on npm
  • function-template-typescript - Typescript function template (will be updated with crossplane projects).
  • typescript-models - Generate typescript models from Crossplane providers
  • kubernetes-models - Generates TypeScript classes from CRDs with constructors, interfaces, and runtime validation via @kubernetes-models/crd-generate

Proposed Features

1. TypeScript Function Builder

Add a TypeScript function builder that:

  • Detects TypeScript functions by presence of package.json + src/ directory
  • Builds functions using a Node.js container (node:25-slim)
  • Runs npm install and npm run build (typically invoking tsgo)
  • Packages the compiled JavaScript onto a distroless Node.js runtime (gcr.io/distroless/nodejs24-debian12)

2. TypeScript Schema Generation

Generate TypeScript models from CRDs/XRDs using @kubernetes-models/crd-generate:

  • Generates proper TypeScript classes with constructors (not just interfaces)
  • Includes runtime validation via @kubernetes-models/base
  • Produces a crossplane-models npm package that functions can import
  • Supports all project dependencies (providers, XRDs, etc.)

3. Function Template

Add a TypeScript function template for crossplane function init:

  • Pre-configured package.json with SDK dependencies
  • TypeScript configuration (tsconfig.json)
  • Example function implementation
  • Integration with generated crossplane-models

Example Usage

# crossplane-project.yaml
apiVersion: dev.crossplane.io/v1alpha1
kind: Project
metadata:
  name: my-configuration
spec:
  schemas:
    languages:
    - typescript
  functions:
  - source: Directory
    directory:
      name: my-function
  dependencies:
  - type: xpkg
    xpkg:
      package: xpkg.upbound.io/upbound/provider-aws-ec2
      version: v2.6.0
// functions/my-function/src/function.ts
import { RunFunctionRequest, RunFunctionResponse } from '@crossplane-org/function-sdk-typescript';
import { VPC } from 'crossplane-models/ec2.aws.upbound.io/v1beta1';

export async function runFunction(req: RunFunctionRequest): Promise<RunFunctionResponse> {
  const vpc = new VPC({
    metadata: { name: 'my-vpc' },
    spec: {
      forProvider: {
        region: 'us-west-2',
        cidrBlock: '10.0.0.0/16',
      },
    },
  });
  // ... compose resources with full type safety
}

Implementation Details

Schema Generation

  • Use @kubernetes-models/crd-generate to generate TypeScript from CRDs
  • Merge all CRD sources (local XRDs + provider dependencies) before generation
  • Output to schemas/typescript/ as an npm package named crossplane-models
  • Functions reference schemas via file: dependency in package.json

Build Process

  • Run builds in Docker container for reproducibility
  • Install schema package dependencies before function dependencies (for symlinked file: deps)
  • Dereference symlinks when copying to runtime image (cp -rL)
  • Configure distroless runtime with Node.js entrypoint

Generated Package Structure

schemas/typescript/
├── package.json
├── index.js
├── index.d.ts
├── ec2.aws.upbound.io/
│   └── v1beta1/
│       ├── VPC.js
│       ├── VPC.d.ts
│       ├── Subnet.js
│       └── ...
└── my.custom.api/
    └── v1alpha1/
        └── ...

Related Work

Acceptance Criteria

  • crossplane project build builds TypeScript functions
  • crossplane function init --language=typescript creates a working template
  • TypeScript schemas are generated for all project dependencies
  • Generated types include classes with constructors, interfaces, and validation
  • Built functions run correctly in Kubernetes

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions