# @metaobjectsdev/metadata

> Metamodel loader, types, and constants for the MetaObjects standard.

Latest version **1.0.9** (published 2026-09-26) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install @metaobjectsdev/metadata
pnpm add @metaobjectsdev/metadata
yarn add @metaobjectsdev/metadata
bun add @metaobjectsdev/metadata
```

## Health

**Score 65/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.0.9 |
| Published | 2026-09-26 |
| First published | 2026-05-23 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 3.1 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | Doug Mealing <doug@dougmealing.com> |
| Maintainers | dougmealing |
| Keywords | metaobjects, metadata, schema, loader, typescript |

## Links

- npm: https://www.npmjs.com/package/@metaobjectsdev/metadata
- Repository: https://github.com/metaobjectsdev/metaobjects
- Homepage: https://metaobjects.dev
- Issues: https://github.com/metaobjectsdev/metaobjects/issues
- npm.io page: https://npm.io/package/@metaobjectsdev/metadata

## Dependencies (1)

- [yaml](https://npm.io/package/yaml.md) ^2.9.0

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 1.0.9 (latest) — 2026-09-26
- 1.0.9-rc.6 (next) — 2026-09-26
- 1.0.9-rc.5 — 2026-09-26
- 1.0.9-rc.4 — 2026-09-26
- 1.0.9-rc.3 — 2026-09-26
- 1.0.9-rc.2 — 2026-09-26
- 1.0.9-rc.1 — 2026-09-26
- 1.0.8 — 2026-09-26
- 1.0.8-rc.1 — 2026-09-26
- 1.0.7 — 2026-09-24
- 1.0.7-rc.1 — 2026-09-24
- 1.0.5 — 2026-09-23
- 1.0.5-rc.11 — 2026-09-23
- 1.0.5-rc.10 — 2026-09-22
- 1.0.5-rc.9 — 2026-09-22
- … 177 more at https://npm.io/package/@metaobjectsdev/metadata/versions

## README

# MetaObjects

[![npm](https://img.shields.io/npm/v/%40metaobjectsdev%2Fcli?label=npm%20%40metaobjectsdev%2Fcli)](https://www.npmjs.com/package/@metaobjectsdev/cli)
[![Maven Central](https://img.shields.io/maven-central/v/com.metaobjects/metaobjects-metadata?label=maven%20central)](https://central.sonatype.com/artifact/com.metaobjects/metaobjects-metadata)
[![PyPI](https://img.shields.io/pypi/v/metaobjects?label=pypi)](https://pypi.org/project/metaobjects/)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)

Coding agents get context — rules files, memories, MCP servers — and context is
**advisory**: nothing fails when the code stops matching it. MetaObjects gives your
agent one typed model of your application — data, API, UI, prompt payloads, and what
the software is supposed to do — generates each layer's code from it in TypeScript,
Java, Kotlin, C# and Python with **no proprietary runtime** in the output, and fails
your build when generated code, a prompt, or a claimed capability drifts from that
model. Your hand-written logic stays yours.

**One typed model of your app** — data, API, UI, prompt payloads, and what it's
supposed to do — that your agent reads and writes. Two things happen to it:

- **Generate.** The boring parts are derived from it, in TypeScript, Java, Kotlin, C#
  and Python — at build time by generators you write or copy into your repo and own,
  or at runtime from the live model. Nothing proprietary in the output.
- **Verify.** The build fails when generated code drifts from the model and when a
  prompt's payload no longer matches what it's told — and it fails or warns when a
  feature someone marked done has nothing implementing it.

That last one has no equivalent in a test suite: a test exercises code that exists, so
nothing flags a claimed capability that was never built. It checks that the claim points
at something real, not that the something is correct.

> **Scope.** It protects what the model declares; your hand-written logic is still
> yours.

The metamodel is the **durable spine**; generated code is the **disposable
artifact**. Substrate is local-first: typed metadata lives in your repo as YAML or
JSON you own. The entity/model tier of the output is dependency-free, and the optional
client, prompt-render, and runtime tiers are ordinary Apache-2.0 packages you could
vendor or fork. If the package ecosystem disappears tomorrow, you keep working code.

Ships today for **TypeScript, Java, Kotlin, C# and Python** — the same gate in each,
byte-checked against the others. Per-port depth is in the
[capability matrix](#capability-matrix); the [six pillars](#six-pillars) are what is
underneath.

> **Maintainer note.** MetaObjects is primarily a one-person, part-time project.
> Issues and PRs are very welcome — expect responses on the order of days, not
> hours. The metadata-driven *approach* has run in production for 20+ years; the
> unified five-language *standard* in this repo is new and launching now. And by
> design you are never blocked on the maintainer: the generated code carries no
> proprietary runtime (see above), so you are never locked in.

> **Built AI-first, verified by construction.** This standard is developed with heavy
> AI assistance under a disciplined review-and-verify process — nothing ships that
> can't be explained. Breadth across five language ports is a deliberate choice, and
> the architecture is what makes it safe: a single metadata spine, a cross-language
> conformance corpus that byte-checks every port ([`fixtures/`](fixtures/)), and drift
> that breaks the build. The same mechanism that keeps *your* AI-generated code
> coherent is the one that keeps this codebase honest.

## Try it on your repo — nothing to install

MetaObjects ships a hosted **fit & migration assessment**: one Markdown prompt your
coding agent runs against your existing repo. It is **read-only and propose-only** —
it installs nothing, edits nothing in your repository, and needs no database
connection and no signup. Your agent reads the code, the migrations, and the git
history. A **quick pass** (the default) answers in the conversation with a
recommended adoption scope; the optional **full assessment** writes a decision-grade
report (`fit-assessment.md` plus a machine-readable JSON twin) to a directory
outside your repository.

The answer is a scope, not a yes/no: **not worth it**, a **contract spine** (declare
only the shapes that cross between your apps and services, generate just the
types, DTOs and validators each side compiles against, and fail the build of any side
that drifts, with your ORM and migrations left alone), **partial** (one layer or
subsystem), or **full**. Full adoption suits greenfield and early projects; large
estates of interdependent apps usually get the most from a contract spine; a small,
finished, single app usually isn't worth it, and the assessment says so.

The centerpiece is a **drift ledger built from your own history**: every shape your
repo declares more than once, whether the copies disagree *today*, the past commits
where a fix patched one copy and missed the other — and, per finding, the `verify`
gate that would have made it a build failure instead of an incident. In a blinded
retro-test on a real pre-adoption production codebase, the assessment surfaced
specific, git-verified drift incidents that had already bitten — including a
CHECK-constraint mismatch repaired only after a production violation, and a schema
divergence still live at assessment time — and its misses ran conservative, not
inflated ([design + retro-test](docs/superpowers/specs/2026-07-12-metaobjects-fit-assessment-design.md)).

With your repo open in your coding agent (Claude Code, Cursor, Windsurf, GitHub
Copilot, Gemini CLI, Codex — anything that can fetch a URL), send one message:

```text
Fetch https://metaobjects.dev/assess.md and run the MetaObjects Fit & Migration
Assessment against this repository.
```

If your agent can't fetch URLs (or you want it to follow the prompt verbatim), save
the file into your workspace instead — `curl -fsSL https://metaobjects.dev/assess.md
-o metaobjects-assess.md` (don't commit it) — and say: *"Read
`metaobjects-assess.md` and run the assessment it contains against this
repository."* The prompt is one Markdown file
([source](agent-context/skills/metaobjects-fit-assessment/SKILL.md)); read it first
if you like — you should never point your agent at a prompt you haven't vetted.

The catch, stated plainly: it runs in **your** agent on **your** tokens. The quick
pass takes roughly 5–30 minutes of agent time, depending on the agent and the
repository, and the full assessment an hour or more. Findings vary by model and repo
size, and every claim is
cited to a `file:line` or a commit precisely so you can check it. Nothing is sent to
us — there is no signup, and the report stays on your machine.

The report is built to say **no**: the scope can be `NOT WORTH IT`, per-pillar
verdicts include `NOT A FIT`, every
capability claim is capped to what your language's port actually ships, and a
"what you will NOT get" section is mandatory. If the verdict is yes, it ends with a
first-week wedge plan — and `meta init` picks up from there.

## Quick links

- Already have a codebase? → Have your coding agent run the
  [fit assessment](#try-it-on-your-repo--nothing-to-install) — read-only, no
  install; it finds the drift already in your git history.
- New here? Pick your language → [`docs/ports/`](docs/ports/) (TS / Java / Kotlin / C# / Python).
- Want the metamodel feature reference? → [`docs/features/`](docs/features/).
- Want the documentation index? → [`docs/README.md`](docs/README.md).
- Want the design rationale? → [`spec/`](spec/) + [`docs/superpowers/specs/`](docs/superpowers/specs/).
- Want a worked, non-toy model? → [`examples/advanced-modeling/`](examples/advanced-modeling/)
  (projections, value objects, TPH, prompt payloads on one runnable spine).
- Want the cross-language contract? → [`fixtures/`](fixtures/) (the conformance corpora are the oracle).

## Languages

| Language | Status | Quickstart | Source |
|---|---|---|---|
| TypeScript | **npm `1.0.9`** — the `@metaobjectsdev/*` packages | [`docs/ports/typescript.md`](docs/ports/typescript.md) | [`server/typescript/`](server/typescript/) · [`client/web/`](client/web/) |
| Java | **Maven Central `8.0.9`** (`com.metaobjects:*` — the JVM major is npm major + 7) — loader + OMDB + render + Maven plugin all shipped; full conformance green | [`docs/ports/java.md`](docs/ports/java.md) | [`server/java/`](server/java/) |
| Kotlin | **Maven Central `8.0.9`** — codegen tier on top of Java: 14 generators (entity, Exposed table, relations, repository, payload, output-parser, output-prompt, render-helper, extractor, filter-allowlist, validator, Spring config, storedProc, Spring controller); 24 / 24 persistence-conformance | [`docs/ports/kotlin.md`](docs/ports/kotlin.md) | [`server/java/codegen-kotlin/`](server/java/codegen-kotlin/) · [`server/java/metadata-ktx/`](server/java/metadata-ktx/) |
| C# | **NuGet `1.0.9`** — loader + conformance + EF Core codegen + render engine + `dotnet meta` CLI all shipped | [`docs/ports/csharp.md`](docs/ports/csharp.md) | [`server/csharp/`](server/csharp/) |
| Python | **PyPI `1.0.9`** — loader + conformance + render + entity-model codegen + ObjectManager runtime shipped; schema migrations are TS-owned (ADR-0015) | [`docs/ports/python.md`](docs/ports/python.md) | [`server/python/`](server/python/) |

## Capability matrix

| Feature | TS | Java | Kotlin | C# | Python |
|---|---|---|---|---|---|
| Entities + fields | Yes | Yes | Yes | Yes | Yes |
| Relationships + FK | Yes | Yes | Yes | Yes | Loader yes; codegen partial |
| Source kinds (`table` / `view`) | Yes | Yes | Yes | Yes | Loader yes; codegen partial |
| Source kinds (`storedProc` / `tableFunction` / `materializedView`) | Yes | Yes | Yes (storedProc generator) | Partial | Loader yes; codegen partial |
| `field.currency` / `field.enum` | Yes | Yes | Yes | Yes | Yes |
| `field.object` + `@storage=flattened` | Yes | Yes | Yes (per-sub-field columns) | Yes (EF Core `OwnsOne`) | Loader yes; codegen partial |
| Templates + render (FR-004) | Yes | Yes | Yes (wraps Java) | Yes | Yes |
| Payload-VO codegen (the value object's own type, ADR-0056) | Yes (`entityFile()`) | Yes (`SpringValueObjectGenerator`) | Yes (`KotlinEntityGenerator`) | Yes (`EntityGenerator`) | Yes (`entity`) |
| Migration emission | `meta migrate` (Postgres / SQLite / D1) | Via TS toolchain (`@metaobjectsdev/cli migrate`) | Via TS toolchain (`@metaobjectsdev/cli migrate`) | Via TS toolchain (ADR-0015) | Via TS toolchain (ADR-0015) |
| DB-drift verify | `meta verify --db <url>` | Template-drift: `Verify.check`; schema-drift is TS-owned (ADR-0015) | Template-drift: `Verify.check`; startup: `MetadataStartupValidator` | `dotnet meta verify` (codegen-drift) | Schema-drift is TS-owned (ADR-0015) |
| Template-drift verify | Yes | Yes (`Verify.check`) | Yes (via Java) | Yes (`dotnet meta verify`) | Yes (`metaobjects.render.verify`) |
| YAML authoring (sigil-free → JSON) | Yes | Yes | Yes (via Java) | Yes | Yes |
| Capability requirements (`requirement.*`) | Registered + `meta verify` gate | Registered (loads + validates) | Registered (via Java) | Registered (loads + validates) | Registered (loads + validates) |
| Libraries (`libraries: [...]`) | Yes | Yes | Yes (via Java) | Yes | Yes |
| Metadata dependencies (`dependencies`) | Yes (`meta deps sync`, `path` transport) | Phase 2 | Phase 2 | Phase 2 | Yes (loads the synced snapshot) |
| Runtime metadata (ObjectManager-style) | Yes (`runtime-ts`) | Yes (OMDB) | Yes (via Java OMDB + Exposed) | Roadmap | Yes (ObjectManager) |
| React / Angular UI client (browser) | React: **published** (`@metaobjectsdev/react` + `@metaobjectsdev/tanstack`), codegen + runtime. Angular 18: **source-only by decision** ([ADR-0048](spec/decisions/ADR-0048-angular-tier-source-only.md)) — `@metaobjectsdev/angular` + `@metaobjectsdev/codegen-ts-angular` build in-repo on their own `0.6.x` line but are deliberately not on npm (`npm i @metaobjectsdev/angular` will 404) until they meet the ADR's promotion bar. Consume them from source. | Consumes TS client via REST | Consumes TS client via REST | Consumes TS client via REST | Consumes TS client via REST |
| Own a generator (`eject`) | Yes (`meta eject`) | Yes (`mvn metaobjects:eject`; `entity` is not ejectable) | Yes (`mvn metaobjects:eject`) | Yes (`dotnet meta eject`) | Yes (`metaobjects eject`) |
| Cross-port REST routes for the client (reference generators) | Generated (`routesFile()` → Fastify) | Generated (`SpringControllerGenerator` → Spring `@RestController`, incl. filter/sort) | Generated (`KotlinSpringControllerGenerator` → Spring `@RestController`, incl. filter/sort) | Generated (`RoutesGenerator` → ASP.NET Minimal API) | Generated (`router_generator` → FastAPI `APIRouter`, incl. filter/sort) |

A "Yes" means the feature is covered by the shared conformance corpora at
[`fixtures/`](fixtures/) for that port, or by a port-local test of equivalent
scope. For rows that describe generated code, the coverage is of the reference
generators on their fixtures — a quality check on the starting point, not a promise
about the code in your repo. A "partial" means the loader recognizes the metamodel feature but the
codegen / runtime tier doesn't fully exercise it yet.

The React and Angular UI clients are TypeScript-only by construction (the
browser is TS-native) but are **universal** — see
[`docs/features/api-contract.md`](docs/features/api-contract.md) for the
URL grammar + wire format the client speaks, and
[`docs/ports/typescript-client.md`](docs/ports/typescript-client.md) for
the consumer-side wiring (React + TanStack, and the
[Angular 18 tier](docs/ports/typescript-client.md#angular-18)).

## What is guaranteed, and what is yours

MetaObjects has two layers, and only the first is a promise
([ADR-0034 Amendment 3](spec/decisions/ADR-0034-codegen-scaffold-and-own.md#amendment-3-2026-09-22--generators-are-reference-helpers-the-core-is-what-metaobjects-guarantees)):

| | Core — guaranteed | Helpers — yours |
|---|---|---|
| **What** | The metamodel, loader, canonical format and registry; runtime metadata access (the `ObjectManager`, not the HTTP adapters that mount it); schema migrations (`meta migrate`); the drift gates (`meta verify`); prompt render and the reply parser | Every generator that writes code into your repo — the ones you write for the outputs you need, and the reference routes, controllers, ORM wiring, DTOs, forms, grids and hooks you copy |
| **Promise** | Conformance-gated, the same behaviour in every port that ships it, covered by the [compatibility policy](docs/compatibility-policy.md) | Reference starting points that compile and pass their reference fixtures. Copy one with `meta eject` and change it freely |
| **A defect is** | A MetaObjects bug, fixed in a release | A bug in the reference, fixed there; your copy is yours |

The test is mechanical: what the tool guarantees is core; what it writes into your repo
is a helper. Every port can eject: `meta eject` (TypeScript), `metaobjects eject` (Python),
`mvn metaobjects:eject` (Java and Kotlin) and `dotnet meta eject` (C#).

## Six pillars

Each pillar says what ships, in which ports, at what maturity — not how new it is. The
first four ship per-language in all five ports, gated by the cross-port conformance
corpora, but they are not uniformly deep. See the [capability matrix](#capability-matrix)
for per-port coverage; in field materialization the ranking is **drift > codegen >
prompts > runtime metadata** (the youngest of the four). The prompt pillar's library-side building blocks are
complete in all five ports; MCP exposure of declared prompts/tools is the one remaining
roadmap item. The fifth has been dogfooded on maintainer-owned projects only, and the
sixth ships two libraries at their own stability labels:

1. **Codegen** *(generators you write and own, in every port)* — on the core, you build
   the generators your application needs: OpenAPI, JSON Schema, Zod, DTOs, a client,
   docs — anything the model describes. A generator is a name plus a function from the
   model to files, and `verify` gates it with nothing to register; `meta generator new
   <name>` scaffolds a working one on TypeScript, and
   [Write your own generator](docs/recipes/write-your-own-generator.md) has every port's
   20-line shape plus JSON Schema and OpenAPI examples to copy. The reference generators
   (Drizzle/Zod + Fastify for TS, Spring REST + DTO + repository for Java, `data class` +
   Exposed for Kotlin, EF Core record + ASP.NET routes for C#, Pydantic + FastAPI for
   Python) are starting points: eject the one that is close, change it, and regenerate.
   The engine that runs generators is core; their output is yours.
2. **Runtime metadata** — load metadata at runtime, drive behavior dynamically
   (CRUD, validation, relationships, dynamic admin UIs; typed tool payloads are
   declared today, with MCP exposure on the roadmap).
3. **Drift detection** — catch divergence across the 7 drift sources (code/DB,
   code/API-doc, DB/metadata, migration/metadata, generated-edited, prompt/payload,
   generated/runtime). See [`docs/features/migrations-and-drift.md`](docs/features/migrations-and-drift.md).
4. **Prompt construction** *(library-side pieces shipped in all five ports; MCP exposure on the roadmap)* — the prompt
   is code too. Declare a prompt's payload as a typed projection (payload bloat
   becomes a diff), keep its text external and provider-resolved, render it
   deterministically (snapshot-testable, cache-stable, drift-checked at build
   time, conformance-gated cross-language). See
   [`docs/features/templates-and-payloads.md`](docs/features/templates-and-payloads.md).
5. **Requirements and testing** *(vocabulary loads and validates in all five ports;
   the `meta verify` checks run in the Node `meta` CLI; `requirementTests()` scaffolding
   is TypeScript-only; dogfooded on maintainer-owned projects, no outside adopter yet)* —
   declare what the software is supposed to *do* in the same model as the entities. The
   other four pillars keep the code honest about the model; this one asks whether a
   claimed capability is actually built. `@implementedBy` is **resolved, not trusted** —
   it names a real member of the real model, so a claim whose implementation was renamed
   or deleted fails the build rather than going quietly stale; a live claim naming
   nothing is a warning. A green run proves those references resolve, not that an
   implementation is correct. A project that declares no `requirement.*` nodes sees no
   change at all. See [`docs/features/requirements.md`](docs/features/requirements.md).
6. **Libraries** *(since 1.0.4, in all five ports: `ai` stable, `iam` preview)* —
   reusable declared design you opt into by name (`"libraries": ["iam"]`): entities,
   the requirements they promise, and the generators they imply, as one drift-gated
   artifact. The core layer declares no source, so it adds no tables until you also opt
   into its `/db` layer (`["iam", "iam/db"]`). Copy one into your repo with
   `meta eject <library>`. See [`docs/features/libraries.md`](docs/features/libraries.md).

**Sharing a model across your own projects** *(the TypeScript toolchain publishes;
TypeScript and Python projects consume, over a `path` dependency such as a sibling
checkout or submodule; Java, Kotlin and C# arrive in Phase 2)* — one project publishes
part of its model (a common `Customer`, an audited base, a set of enums) with
`sharedModelFile()`, and another declares it in `dependencies`, syncs it into a
committed, hash-locked snapshot and builds on it with `extends` and references. When the
publisher's model moves, `meta verify --deps` says so, instead of two copies drifting
apart. See [`docs/features/metadata-dependencies.md`](docs/features/metadata-dependencies.md).

## Repo layout

```
metaobjects/
├── README.md                       # you are here
├── CLAUDE.md                       # project instructions for Claude
├── spec/                           # canonical metamodel docs, ADRs, roadmap
├── fixtures/                       # 22 cross-language conformance corpora — the oracle
│   ├── conformance/                # metamodel (loader + serializer + navigation), 329 fixtures
│   ├── yaml-conformance/           # YAML authoring desugar
│   ├── render-conformance/         # FR-004 byte-identical render oracle
│   ├── verify-conformance/         # FR-004 template-drift gate
│   ├── extract-conformance/        # FR-010 tolerant output parsing
│   ├── api-contract-conformance/   # the REST wire contract, reference + generated lanes
│   ├── persistence-conformance/    # on-demand integration tests vs real Postgres
│   └── …                           # registry, validation, codegen, provider-composition, …
│                                   #   full matrix: docs/CONFORMANCE.md
├── docs/
│   ├── README.md                   # docs index
│   ├── features/                   # feature reference (one file per metamodel feature)
│   ├── ports/                      # per-port quickstarts
│   ├── recipes/                    # deployment recipes (Cloudflare D1, …)
│   ├── CONFORMANCE.md              # corpus × port matrix + fixture→feature index
│   ├── superpowers/specs/          # design specs
│   └── RELEASING.md                # npm publish procedure
├── examples/
│   └── advanced-modeling/          # a worked, runnable non-toy model
├── library/                        # shipped libraries, opt-in per project via `libraries: [...]`
│   ├── ai/                         #   the LLM-call trace envelope (stable)
│   └── iam/                        #   users, groups, roles, grants (preview)
├── templates/                      # canonical api/docs Mustache templates (the SSOT the
│                                   #   ports embed; byte-gated so copies cannot drift)
├── agent-context/                  # the shared source the per-port AI-assistant context
│                                   #   surfaces are generated from (AGENTS.md, skills, llms.txt)
├── scripts/                        # CI parity (`ci-local.sh`), codegen of embedded assets, one-offs
│
├── server/                         # runs on a server
│   ├── typescript/                 # the reference port
│   ├── java/                       # Java port (incl. codegen-kotlin + metadata-ktx)
│   ├── csharp/                     # C# port
│   └── python/                     # Python port
│
└── client/
    └── web/                        # universal browser packages (React, TanStack, Angular, framework-agnostic)
```

## Getting started

| Language | First command |
|---|---|
| TypeScript | `npm i @metaobjectsdev/cli && npx meta init` → [`docs/ports/typescript.md`](docs/ports/typescript.md) |
| Java | Add `metaobjects-maven-plugin` to your `pom.xml` → [`docs/ports/java.md`](docs/ports/java.md) |
| Kotlin | Add `metaobjects-codegen-kotlin` + `metaobjects-metadata-ktx` → [`docs/ports/kotlin.md`](docs/ports/kotlin.md) |
| C# | `dotnet tool install --global MetaObjects.Cli` → [`docs/ports/csharp.md`](docs/ports/csharp.md) |
| Python | `pip install metaobjects` → [`docs/ports/python.md`](docs/ports/python.md) |

## Cross-language conformance

Every port runs against the same fixture corpora at [`fixtures/`](fixtures/).
Per-port unit tests stay container-free; the on-demand integration suite spins up
ephemeral Postgres containers and exercises every shipped port's persistence
layer against the shared scenario corpus:

```bash
scripts/integration-test.sh            # all runners (ts + csharp + java + python + kotlin)
scripts/integration-test.sh ts         # just TypeScript
scripts/integration-test.sh csharp     # just C#
scripts/integration-test.sh java       # just Java
scripts/integration-test.sh python     # just Python
scripts/integration-test.sh kotlin     # just Kotlin
```

The core corpora (metamodel, registry, YAML, render, extract, verify, persistence)
are the contract: identical normalized results across every port, or it's a port bug.
The codegen-compile gate and the generated lane of the API-contract corpus check the
reference generators, which are helpers you own rather than a promise. See
[`docs/CONFORMANCE.md`](docs/CONFORMANCE.md) for the per-corpus + per-port pass status.

## How to contribute

PRs welcome. Read [`CONTRIBUTING.md`](CONTRIBUTING.md) for how to propose a
change and the project conventions it has to meet (TDD discipline,
named-constants-for-metamodel-strings, no-`any` rule, cross-language porting
contract, public-repo hygiene). For significant new features, open an issue
first to discuss the approach.

## Roadmap

[`spec/roadmap.md`](spec/roadmap.md) for current + planned work.

## Releasing

[`docs/RELEASING.md`](docs/RELEASING.md) for the npm publish procedure
(RC → smoke-test → promote).

## License

Apache 2.0 ([LICENSE](LICENSE)).

---
_Source: https://npm.io/package/@metaobjectsdev/metadata · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
