Lazy Typing Pattern
Write type-safe code against semantic concepts while deferring specific implementations through axioms, canons, and universal APIs
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.
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:
Axioms define what semantic concepts mean, independent of any specific data shape:
Canons provide how each axiom is implemented for specific data shapes:
Universal APIs provide the interface your application code uses:
Expect<A, B>IsTrue and IsFalseCanon serves as a canonical starting point by providing:
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.
npm install @relational-fabric/canonnpx canon initThe 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.
{
"extends": "@relational-fabric/canon/tsconfig"
}// eslint.config.js
import createEslintConfig from '@relational-fabric/canon/eslint'
export default createEslintConfig()// eslint.config.js
import createEslintConfig from '@relational-fabric/canon/eslint'
export default createEslintConfig({
ignores: ['custom-ignore'],
rules: {
'no-console': 'warn',
},
})This package requires the following peer dependencies:
Canon implements lazy typing through three complementary components that work together:
Axioms define semantic concepts independent of data shape. They specify what concepts your code works with, such as:
See docs/axioms.md for the complete type system architecture.
Canons provide shape-specific implementations of axioms. They specify how each semantic concept is represented in a particular data shape:
See docs/canons.md for implementation patterns.
Universal APIs provide functions that work across all registered canons. They are the interface your application code uses:
See docs/reference/api.md for available APIs.
@relational-fabric/canon - Core axioms and canons@relational-fabric/canon/tsconfig - Base TypeScript configuration@relational-fabric/canon/eslint - ESLint configuration functionRegister axioms and canons using TypeScript module augmentation:
declare module '@relational-fabric/canon' {
interface Axioms {
MyAxiom: MyAxiomType
}
interface Canons {
MyCanon: MyCanonType
}
}Timestamps, References), singular for specific concepts (Id, Type)*Of pattern (idOf(), typeOf()) not imperative get* patterns$ prefix only for Canon's internal keys ($basis, $meta)See CONTRIBUTING.md for complete conventions.
Canon is designed to compose with existing TypeScript libraries and provides:
Canon maintains transparent planning and strategic direction:
npm run build:radar - Convert YAML to CSV for visualizationgit clone <repository-url>
cd canon
npm installChecks (Validation):
npm run check:all - Run all checks (lint, type check, and tests)npm run checks - Alias for check:allnpm run check:types - Type check all code (src + examples)npm run check:types:src - Type check source code onlynpm run check:types:examples - Type check examples onlynpm run check:lint - Lint codenpm run check:lint:fix - Fix ESLint issues automaticallynpm run check:radar - Validate radar configurationnpm test - Run tests (npm standard)npm run check:test - Run tests (includes examples)Development:
npm run dev - Run TypeScript in watch modeDocumentation:
npm run build:docs - Build documentation for productionnpm run build:docs:restore - Restore README.md files from buildNote: 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 ADRnpm run build:adr - Build all ADR artifacts (TOC + index)npm run build:adr:toc - Generate table of contentsnpm run build:adr:index - Generate ADR index in documentationTechnology Radar:
npm run build:radar - Convert YAML radar data to CSVExamples:
npm run build:docs:examples - Generate documentation from examplesCanon provides comprehensive documentation to help you understand and use the system:
MIT