# 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