# Technologies Used in the Development of CommonGrants: A Deep Dive into the Simpler Grants Protocol Stack

> Discover the technologies behind CommonGrants. Explore TypeSpec, TypeScript, Python SDKs, Astro, React, and GitHub Actions in this deep dive into the Simpler Grants Protocol stack.

- Repository: [U.S. Department of Health & Human Services/simpler-grants-protocol](https://github.com/hhs/simpler-grants-protocol)
- Tags: deep-dive
- Published: 2026-03-03

---

**CommonGrants is built on a TypeSpec-first architecture using pnpm workspaces, TypeScript and Python SDKs with Zod and Pydantic validation, an Astro/React documentation site, and GitHub Actions with Changesets for automated releases.**

The `hhs/simpler-grants-protocol` repository implements CommonGrants as a modern, multi-language ecosystem. The technologies used in the development of CommonGrants reflect an API-first approach, leveraging declarative specification tools and polyglot SDK generation to ensure type safety across TypeScript and Python implementations.

## Core API Definition and Versioning Technologies

### TypeSpec for API-First Design

At the heart of the stack lies **TypeSpec** (formerly Cadl), a declarative language for defining APIs that generates OpenAPI specifications, JSON-Schema, and client libraries. In `lib/core/lib/main.tsp`, the CommonGrants API is defined as a versioned namespace that imports core models from `core/index.tsp` and `api.tsp`. This single source of truth ensures that TypeScript and Python SDKs, along with documentation, remain synchronized as the API evolves.

The TypeSpec compiler (`tsp` CLI) processes these definitions through scripts defined in the workspace configuration, outputting artifacts to `tsp-output/@typespec/openapi3/` for downstream consumption by the documentation site and client generators.

### Semantic Versioning with @typespec/versioning

The protocol implements **semantic versioning** via the `@typespec/versioning` library. The `main.tsp` file decorates the `CommonGrants` namespace with three distinct versions (`v0_1`, `v0_2`, `v0_3`), allowing SDK clients to pin to specific API versions while the specification evolves. This ensures backward compatibility and predictable deprecation cycles across the TypeScript and Python implementations.

## SDK Development Technologies

### TypeScript SDK Stack

The **TypeScript SDK** (`lib/ts-sdk/`) provides an idiomatic client for Node.js and browser environments. Key technologies include:

- **Zod**: Runtime schema validation for request/response data, ensuring type safety beyond compile-time checks.
- **Ajv + ajv-formats**: JSON-Schema validation for generated models, providing an alternative validation path.
- **Native fetch API**: Core HTTP transport implemented in [`lib/ts-sdk/src/client/client.ts`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/ts-sdk/src/client/client.ts), handling timeouts, retries, and automatic pagination via the `fetchMany` method.

The `Client` class in [`lib/ts-sdk/src/client/client.ts`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/ts-sdk/src/client/client.ts) abstracts HTTP requests, automatically appending authentication headers via `Auth` helpers and implementing `fetchMany` for auto-pagination across large result sets.

```typescript
import { Client, Auth } from "@common-grants/sdk";

const client = new Client({
  baseUrl: process.env.CG_BASE_URL ?? "http://localhost:8000",
  auth: Auth.apiKey(process.env.CG_API_KEY ?? "<your-api-key>"),
  timeout: 5000,
  pageSize: 10,
});

async function listAll() {
  // `fetchMany` handles pagination automatically.
  const result = await client.fetchMany("/common-grants/opportunities", {
    maxItems: 50,
    schema: client.opportunities.opportunitySchema, // optional Zod validation
  });

  console.log(`Fetched ${result.items.length} opportunities`);
  result.items.forEach(o => console.log(o.title));
}
listAll();

```

### Python SDK Stack

The **Python SDK** (`lib/python-sdk/`) mirrors the TypeScript implementation using **Python 3.11+** and modern async patterns:

- **Pydantic v2**: Typed data models with validation and (de)serialization, generated from the same TypeSpec source as the TypeScript SDK.
- **marshmallow**: Alternate schema library used in some generated models for flexibility.
- **httpx**: Async-compatible HTTP client used by the Python `Client` class in [`common_grants_sdk/client/client.py`](https://github.com/hhs/simpler-grants-protocol/blob/main/common_grants_sdk/client/client.py), supporting both synchronous and asynchronous request patterns.

```python
import os
from common_grants_sdk.client import Client, Auth

client = Client(
    base_url=os.getenv("CG_BASE_URL", "http://localhost:8000"),
    auth=Auth.api_key(os.getenv("CG_API_KEY", "<your-api-key>")),
)

opp = client.opportunities.get("opp-123")
print(opp.title)   # Pydantic model with type‑checked fields

```

## Developer Tooling and Monorepo Management

### pnpm Workspaces

The repository uses **pnpm workspaces** to manage multiple packages (`core`, `cli`, `ts-sdk`, `python-sdk`, `website`) under a single lockfile. This enables fast, disk-space-efficient installs and consistent dependency management across the TypeScript portions of the codebase. The workspace configuration is defined in [`pnpm-workspace.yaml`](https://github.com/hhs/simpler-grants-protocol/blob/main/pnpm-workspace.yaml) and the root [`package.json`](https://github.com/hhs/simpler-grants-protocol/blob/main/package.json).

### CLI and Build Tools

The **CLI** package (`lib/cli/`) provides developer tooling built with Node.js and TypeScript. It exposes commands to run TypeSpec compilation, generate OpenAPI specifications, and manage package publishing. This tool abstracts the `tsp` compiler invocations, providing a unified interface for code generation tasks across the monorepo.

Build quality is enforced through **ESLint**, **Prettier**, **Vitest** (for unit testing), **cspell** (for spell checking), and the **tsp** CLI for TypeSpec compilation. These tools are configured as `devDependencies` across the various [`package.json`](https://github.com/hhs/simpler-grants-protocol/blob/main/package.json) files in the workspace.

## Documentation Website Architecture

### Astro and React Foundation

The documentation site (`website/`) is built with **Astro v5**, a static-site generator optimized for content-driven sites. Astro handles the build process, producing optimized static assets while allowing selective hydration of interactive components. It incorporates **React v18** via `@astrojs/react` to render dynamic UI elements.

### Interactive API Components

The documentation site features several specialized libraries for API exploration:

- **JSONForms**: Renders JSON-Schema-driven forms for custom fields and the API Playground, allowing users to interact with data models directly.
- **Swagger-UI-React**: Embeds live API exploration interfaces, rendering the generated OpenAPI specifications for interactive testing.
- **OpenAPI-Sampler**: Generates example request/response bodies for the API documentation, providing concrete data samples alongside schema definitions.

The website runs scripts that compile TypeSpec to OpenAPI and serve it through Swagger UI, as defined in [`website/package.json`](https://github.com/hhs/simpler-grants-protocol/blob/main/website/package.json):

```json
{
  "scripts": {
    "typespec:openapi": "tsp compile src/specs/main.tsp && cp tsp-output/@typespec/openapi3/** public/openapi"
  }
}

```

## CI/CD and Release Automation

### GitHub Actions Pipelines

Continuous integration and deployment are handled via **GitHub Actions**, with workflow definitions in `.github/workflows/*.yml`. These pipelines automate testing (Vitest for TypeScript, pytest for Python), linting (ESLint, Prettier), TypeSpec compilation, and deployment previews for the documentation site. Specific workflows like [`ci-lib-ts-sdk.yml`](https://github.com/hhs/simpler-grants-protocol/blob/main/ci-lib-ts-sdk.yml) target individual packages for targeted testing.

### Changesets for Version Management

**Changesets** manages changelog generation and version bumping across the pnpm workspaces. Configuration in [`.changeset/config.json`](https://github.com/hhs/simpler-grants-protocol/blob/main/.changeset/config.json) ensures consistent semantic versioning across all packages (`core`, `cli`, `ts-sdk`, etc.), automating the release process and maintaining accurate release notes without manual version synchronization.

## Summary

- **TypeSpec** serves as the single source of truth for API definitions in `lib/core/lib/main.tsp`, generating OpenAPI and JSON-Schema artifacts used across all consumers.
- **pnpm workspaces** unify the monorepo structure, while **Node.js** and **Python 3.11+** power the respective SDK implementations.
- **TypeScript SDK** leverages **Zod**, **Ajv**, and native **fetch** for runtime validation and HTTP transport in [`lib/ts-sdk/src/client/client.ts`](https://github.com/hhs/simpler-grants-protocol/blob/main/lib/ts-sdk/src/client/client.ts).
- **Python SDK** utilizes **Pydantic v2**, **marshmallow**, and **httpx** for type-safe async operations in [`common_grants_sdk/client/client.py`](https://github.com/hhs/simpler-grants-protocol/blob/main/common_grants_sdk/client/client.py).
- **Astro** and **React** drive the documentation site, enhanced with **JSONForms** and **Swagger UI** for interactive API exploration.
- **GitHub Actions** and **Changesets** automate testing, publishing, and version management across the entire ecosystem.

## Frequently Asked Questions

### What is TypeSpec and why does CommonGrants use it?

**TypeSpec** is a declarative language for defining APIs that generates OpenAPI specifications, JSON-Schema, and client libraries from a single source of truth. CommonGrants uses TypeSpec in `lib/core/lib/main.tsp` to ensure that TypeScript and Python SDKs, along with documentation, remain synchronized and type-safe as the API evolves through semantic versions.

### How does CommonGrants handle API versioning?

The protocol implements **semantic versioning** via the `@typespec/versioning` library, defining three distinct versions (`v0_1`, `v0_2`, `v0_3`) in the `main.tsp` namespace. This allows SDK clients to pin to specific API versions while the specification evolves, ensuring backward compatibility and predictable deprecation cycles across the TypeScript and Python implementations.

### What validation libraries are used in the CommonGrants SDKs?

The **TypeScript SDK** uses **Zod** for runtime schema validation and **Ajv** with **ajv-formats** for JSON-Schema validation, ensuring type safety beyond compile-time checks. The **Python SDK** leverages **Pydantic v2** for typed data models and validation, with **marshmallow** used as an alternate schema library in some generated models, providing comprehensive data integrity across both language implementations.

### How is the CommonGrants documentation website built?

The documentation site utilizes **Astro v5** as the static-site generator, providing optimized static asset builds with selective hydration of interactive components. It incorporates **React v18** via `@astrojs/react` to render **JSONForms** for schema-driven forms, **Swagger-UI-React** for live API exploration, and **OpenAPI-Sampler** for generating example request/response bodies, creating a comprehensive interactive documentation experience.