# TKO (Typed Knockout) > TypeScript MVVM framework for reactive data binding and UI templating. > Zero runtime dependencies. Successor to Knockout.js. ## Quick Start ```html ``` ## Agent Docs - /agents/soul.md — why Knockout works (design philosophy) - /agents/guide.md — API reference, gotchas, examples - /agents/glossary.md — domain terms, concepts, packages - /agents/testing.md — run + verify TKO code - /agents/contract.md — state/binding/DOM architecture - /agents/options.md — `ko.options.*` — when to use `defineOption` vs core Options fields - /agents/process.md — mandatory agent workflow (doc-ref verification, adversarial review) - /agents/verified-behaviors/index.md — test-backed behavior contracts - /agents/sample-tsx.html — minimal browser TSX scaffold - /examples/ — interactive self-contained HTML examples ## Builds - `@tko/build.reference` — modern TKO (TSX, ko-*, native provider) - `@tko/build.knockout` — Knockout.js compatibility ## Key Concepts - Observables, observableArrays, computeds = state layer - Bindings (`data-bind="text: msg"`) = DOM integration layer - `ko.applyBindings(viewModel, element)` connects state to DOM - TSX: `ko-text={msg}` with esbuild + `tko.jsx.render()` ## Packages - Bindings: `@tko/binding.*` - Observables: `@tko/observable`, `@tko/computed` - Providers: `@tko/provider.*`, `@tko/utils.parser` - TSX/JSX: `@tko/utils.jsx`, `@tko/provider.native` ## Gotchas - Derived `ko-*` values must stay observable/computed — inline expressions freeze - `ko.applyBindings(...)` returns Promise - Inside `ko-foreach`, binding-context vars use strings: `ko-text="$data"` (not `{$data}`) - Component JSX params: pass each constructor param as own attribute (``), never wrap in `params={{...}}` — JSX attrs flatten into one constructor arg, wrapping double-nests to `{ params: {...} }` - Never create `ko.observable()`, `ko.computed()`, or `.subscribe()` inside computed evaluator — re-runs leak instances - Binary HTML attrs (`disabled`, `hidden`, …): return `|| undefined` from computed; `false` renders string `"false"`, keeps attribute ## Browser JSX (esbuild-wasm) ```js import * as esbuild from 'https://cdn.jsdelivr.net/npm/esbuild-wasm@0.27.4/esm/browser.min.js' await esbuild.initialize({ wasmURL: 'https://cdn.jsdelivr.net/npm/esbuild-wasm@0.27.4/esbuild.wasm' }) const result = await esbuild.transform(tsxCode, { loader: 'tsx', jsxFactory: 'tko.jsx.createElement', jsxFragment: 'tko.jsx.Fragment' }) ``` ## Links - Docs: /observables/ · /computed/ · /bindings/ · /components/ - Playground: /playground - GitHub: https://github.com/knockout/tko