Skip to content

@relational-fabric/canonUniversal Type Primitives & Axiomatic Systems

Build robust, data-centric applications with consistent type blueprints and a curated library ecosystem

Canon solves the "empty room problem" by providing universal type primitives and axiomatic systems for building robust, data-centric applications. Instead of starting from scratch with each new project, Canon offers consistent design decisions and type blueprints that can be shared across projects and data shapes.

What is Canon? ​

Canon is a modern TypeScript package that enables lazy typing - writing type-safe code against semantic concepts while deferring specific implementations to runtime configuration. This is achieved through three complementary parts:

The Lazy Typing Triplet ​

1. Axioms - Define Semantic Concepts ​

Axioms define what semantic concepts mean, independent of any specific data shape:

  • Define the semantic concept (e.g., "unique identifier", "type classification", "temporal data")
  • Specify the type structure without implementation details
  • Enable compile-time type safety through TypeScript interfaces

2. Canons - Implement for Shapes ​

Canons provide how each axiom is implemented for specific data shapes:

  • Provide shape-specific field names and structures
  • Multiple canons can coexist for different data sources
  • Register both type-level and runtime configurations

3. Universal APIs - Work Across Shapes ​

Universal APIs provide the interface your application code uses:

  • Single API that works across all registered canons
  • Type-safe functions that adapt to different data shapes
  • No shape-specific code in your business logic

Additional Capabilities ​

Universal Type Primitives ​

  • Battle-tested types from the TypeScript ecosystem
  • Foundation for building data-centric applications
  • Type-safe operations and proven patterns

Type Testing Utilities ​

  • Zero-runtime-cost compile-time type assertions
  • Guard against type regressions with Expect<A, B>
  • Document type expectations directly in code
  • Positive and negative type checks with IsTrue and IsFalse

Curated Library Ecosystem ​

Canon serves as a canonical starting point by providing:

  • Pre-configured TypeScript setup - Base configurations that work out of the box
  • Curated dependency set - Known good versions of essential libraries for common needs
  • Standardized patterns - Consistent approaches to common problems
  • Best practice implementations - Proven solutions for type safety and data handling
  • Sensible defaults - Recommended choices when selecting data structures

This approach reduces decision fatigue and provides confidence in your technology stack while recognizing that in many real-world scenarios you must work with existing data structures.

Quick Start ​

Install ​

bash
npm install @relational-fabric/canon

Scaffold via CLI ​

bash
npx canon init

The CLI copies Canon’s starter templates, wires all workflows into package.json, and ensures eslint and typescript are present as dev dependencies. Use --name, --directory, and --force to control the output, or see Project Setup for a guided walk-through.

Use TypeScript Configuration ​

json
{
  "extends": "@relational-fabric/canon/tsconfig"
}

Use ESLint Configuration ​

javascript
// eslint.config.js
import createEslintConfig from '@relational-fabric/canon/eslint'

export default createEslintConfig()

Providing Custom Options ​

javascript
// eslint.config.js
import createEslintConfig from '@relational-fabric/canon/eslint'

export default createEslintConfig({
  ignores: ['custom-ignore'],
  rules: {
    'no-console': 'warn',
  },
})

Requirements ​

This package requires the following peer dependencies:

  • Node.js: 22.0.0 or higher
  • TypeScript: 5.0.0 or higher
  • ESLint: 9.0.0 or higher

Core Concepts ​

The Lazy Typing Pattern ​

Canon implements lazy typing through three complementary components that work together:

Axioms ​

Axioms define semantic concepts independent of data shape. They specify what concepts your code works with, such as:

  • Unique identifiers across different systems
  • Type information and classification
  • Versioning and change tracking
  • Temporal data with conversion between representations
  • Relationships between entities

See docs/axioms.md for the complete type system architecture.

Canons ​

Canons provide shape-specific implementations of axioms. They specify how each semantic concept is represented in a particular data shape:

  • Declarative Style: Local configurations for specific use cases
  • Module Style: Shareable configurations across projects
  • Type Safety: Full TypeScript support with compile-time checking
  • Multiple Shapes: Each canon handles one data shape's implementation

See docs/canons.md for implementation patterns.

Universal APIs ​

Universal APIs provide functions that work across all registered canons. They are the interface your application code uses:

  • Write code once that works with any registered canon
  • Automatic adaptation to different data shapes
  • Full type safety maintained across all shapes

See docs/reference/api.md for available APIs.

Package Exports ​

  • Main package: @relational-fabric/canon - Core axioms and canons
  • TypeScript config: @relational-fabric/canon/tsconfig - Base TypeScript configuration
  • ESLint config: @relational-fabric/canon/eslint - ESLint configuration function

Key Patterns ​

Module Augmentation ​

Register axioms and canons using TypeScript module augmentation:

typescript
declare module '@relational-fabric/canon' {
  interface Axioms {
    MyAxiom: MyAxiomType
  }
  interface Canons {
    MyCanon: MyCanonType
  }
}

Naming Conventions ​

  • Axiom Keys: PascalCase, plural for general concepts (Timestamps, References), singular for specific concepts (Id, Type)
  • Function Names: Use relational *Of pattern (idOf(), typeOf()) not imperative get* patterns
  • Type Names: PascalCase for all type definitions
  • Variables: camelCase for all variables and parameters
  • Distinguished Keys: Use $ prefix only for Canon's internal keys ($basis, $meta)

See CONTRIBUTING.md for complete conventions.

Integration ​

Canon is designed to compose with existing TypeScript libraries and provides:

  • Type Safety: Full TypeScript support with strict type checking
  • Flexibility: Work with existing data structures or define new ones
  • Shape Agnostic: Support for diverse data shapes through universal semantic interfaces
  • Extensibility: Add your own axioms and canons as needed

Planning and Strategy ​

Canon maintains transparent planning and strategic direction:

  • Technology Radar: planning/radar/ - Technology recommendations and assessments
  • Strategic Vision: planning/ - Long-term direction and positioning
  • Development Roadmap: planning/ - Detailed development phases and milestones
  • Architecture Decisions: docs/adrs/ - Documented ADRs for major decisions
  • Update Radar: npm run build:radar - Convert YAML to CSV for visualization

Development ​

Prerequisites ​

  • Node.js 22+
  • npm or yarn

Setup ​

bash
git clone <repository-url>
cd canon
npm install

Available Scripts ​

Checks (Validation):

  • npm run check:all - Run all checks (lint, type check, and tests)
  • npm run checks - Alias for check:all
  • npm run check:types - Type check all code (src + examples)
  • npm run check:types:src - Type check source code only
  • npm run check:types:examples - Type check examples only
  • npm run check:lint - Lint code
  • npm run check:lint:fix - Fix ESLint issues automatically
  • npm run check:radar - Validate radar configuration
  • npm test - Run tests (npm standard)
  • npm run check:test - Run tests (includes examples)

Development:

  • npm run dev - Run TypeScript in watch mode

Documentation:

  • npm run build:docs - Build documentation for production
  • npm run build:docs:restore - Restore README.md files from build

Note: The documentation build process uses a GitHub-first approach. All files use README.md naming in the repository for GitHub compatibility. During build, files are temporarily renamed to index.md for VitePress routing, then automatically restored. Always edit README.md files directly.

Architecture Decision Records:

  • cd docs/adrs && npx adr-tools new "Title" - Create a new ADR
  • npm run build:adr - Build all ADR artifacts (TOC + index)
  • npm run build:adr:toc - Generate table of contents
  • npm run build:adr:index - Generate ADR index in documentation

Technology Radar:

  • npm run build:radar - Convert YAML radar data to CSV

Examples:

  • npm run build:docs:examples - Generate documentation from examples

Documentation ​

Canon provides comprehensive documentation to help you understand and use the system:

Core Documentation ​

  • Getting Started - Introduction and quick start guide
  • Axioms - Fundamental building blocks and type system
  • Canons - Universal type blueprints and implementation patterns
  • Contributing - Conventions, naming patterns, and development workflow

Reference Documentation ​

Examples ​

Architecture ​

License ​

MIT

Released under the MIT License.