This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
23blocks SDK is a modular, framework-agnostic TypeScript SDK for building applications with 23blocks backends. It uses JSON:API v1.0 specification and provides native bindings for Angular (RxJS) and React (hooks/context).
# Install dependencies
npm ci
# Build all packages (required before testing)
npm run build
# Build a specific package
npx nx build @23blocks/block-authentication
# Run all tests
npm run test
# Run tests for a specific package
npx nx test @23blocks/block-search
# Type checking
npm run typecheck
# Lint
npm run lint
# Clean build artifacts
npm run clean
# View dependency graph
npm run graphReleases are automated via GitHub Actions using npm Trusted Publishing (OIDC). Push to main triggers:
nx release- determines versions from conventional commits, updates changelogs, creates git tagsnpm publish --provenance- publishes each package with OIDC authentication
Important: Each package has independent versioning. Trusted Publisher is configured on npm with:
- Owner:
23blocks-OS(case-sensitive!) - Repository:
frontend-sdk - Workflow:
release.yml
Manual release: npm run release or npm run release:dry-run
Follow this exact checklist when adding a new feature to any block-* package. Do NOT skip steps. Do NOT spend time verifying the release pipeline — it works automatically.
- Create types in
types/with proper interfaces - Create mapper in
mappers/withResourceMapper<T> - Create service in
services/with CRUD methods (PUT for updates, never PATCH) - Wire into block factory (
*.block.ts) — add to interface, factory return, andresourceTypes - Update barrel exports:
types/index.ts,services/index.ts,mappers/index.ts - Update
src/index.tswith new public exports - Build & verify:
npx nx build @23blocks/block-xxx --skip-nx-cache
Meta-packages (@23blocks/sdk, @23blocks/react, @23blocks/angular) depend on each @23blocks/block-* as a regular npm package with caret ranges. Consumers receive block fixes via dep resolution on next install — block-internal patches do NOT require meta-package rebuilds.
Rebuild meta-packages only when:
- You added a new sub-service to a block (Angular needs a getter, sdk/react/angular need JSDoc reflecting the new sub-service)
- You changed a block's public TypeScript surface (new types, renamed methods, removed exports) that flows through the meta-package's namespace re-export
- You added a new block to the meta-package's deps list
For pure block-internal bug fixes (no API changes): ship just the block commit. Skip meta-packages.
When you DO touch meta-packages:
- Angular (
packages/angular/): Add getter to the relevant service (e.g.,get evaluations() { return this.ensureConfigured().evaluations; }) - SDK (
packages/sdk/src/lib/sdk.ts): Make a real file change (update JSDoc comment) —--allow-emptycommits do NOT work with nx release - React (
packages/react/src/lib/index.ts): Make a real file change (update JSDoc comment) - Build all:
npm run build
- Update
llms.txt(root) — add new sub-services to the relevant block section - Update
packages/sdk/llms.txt— same additions
Commit scope MUST match the nx project name exactly (e.g., @23blocks/block-rag, NOT block-rag):
git commit -m "feat(@23blocks/block-xxx): description"
git commit -m "feat(@23blocks/angular): add xxx getter to YyyService"
git commit -m "feat(@23blocks/sdk): rebuild with xxx feature"
git commit -m "feat(@23blocks/react): rebuild with xxx feature"
git commit -m "docs: add xxx to sub-service list in llms.txt"git push origin mainThen check: gh run list --workflow=release.yml --limit 1 — confirm status is "completed" + "success". That's it. Done. Do not dig into logs, do not download tarballs, do not inspect bundles.
packages/
├── contracts/ # Core types: Transport, BlockConfig, errors, pagination
├── jsonapi-codec/ # JSON:API v1.0 encoder/decoder
├── transport-http/ # HTTP transport implementation
├── block-*/ # Feature blocks (18 total) - Promise-based, framework-agnostic
├── angular/ # Angular services wrapping blocks with RxJS Observables
├── react/ # React context + hooks wrapping blocks
└── sdk/ # Meta-package re-exporting all blocks
Each block-* package follows this structure:
createXxxBlock(transport, config)- Factory function returning the block instanceservices/- Service classes with CRUD operationsmappers/- JSON:API response mapperstypes/- TypeScript interfaces
Example:
import { createAuthenticationBlock } from '@23blocks/block-authentication';
const auth = createAuthenticationBlock(transport, { apiKey: 'xxx' });
await auth.auth.signIn({ email, password });Angular (@23blocks/angular):
- Injectable services that expose block sub-services via typed getters (delegation pattern)
- Use
provideBlocks23({ apiKey, urls: { authentication: '...' } })in app config - Sub-services return Promises - use
from()to convert to Observables if needed - AuthenticationService is hybrid: auth-flow methods (signIn, signUp, signOut, OAuth) return Observables with token management via
tap(), all other sub-services are delegated getters - Built with ng-packagr (Ivy AOT partial compilation), strict mode enabled
React (@23blocks/react):
<Blocks23Provider>creates block instances from config- Hooks like
useAuth(),useSearch()access blocks from context - Blocks are memoized to prevent recreation on re-renders
nx.json- Nx workspace config, release settings, target defaultstsconfig.base.json- TypeScript paths for all @23blocks/* packages.npmrc- Registry config,legacy-peer-deps=truefor Angular compatibility
# Use yalc to test in a consumer project
npm run local:publish
# Then in consumer: yalc add @23blocks/block-authenticationIMPORTANT: No PATCH HTTP method allowed. The 23blocks backend does not support PATCH requests. Always use PUT for update operations. This applies to all services across all blocks.
// ✗ WRONG - PATCH is not allowed
const response = await transport.patch(`/users/${id}`, { ... });
// ✓ CORRECT - Use PUT for updates
const response = await transport.put(`/users/${id}`, { ... });Use these prefixes for automatic versioning:
feat:- Minor version bumpfix:- Patch version bumpfeat!:orBREAKING CHANGE:- Major version bump