|
1 | | - |
2 | | -# TKO (“Technical Knockout”) |
| 1 | +# TKO ("Technical Knockout") |
3 | 2 |
|
4 | 3 | [](https://badge.fury.io/js/@tko%2Fbuild.reference) |
5 | | -[](https://gitter.im/knockout/tko?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) |
6 | | -[](https://prettier.io/) |
7 | | - |
8 | | -[](https://github.com/knockout/tko/actions/workflows/main-build.yml) |
9 | | -[](https://coveralls.io/github/knockout/tko?branch=master) |
10 | | -[](https://circleci.com/gh/knockout/tko) |
11 | | -<!-- [](https://saucelabs.com/u/tko) --> |
12 | | - |
13 | | -**TKO** houses the monorepo of [Knockout](https://github.com/knockout/knockout). |
14 | | -TKO, or Technical Knockout, is a JavaScript web framework for data binding and templating. It is a fork of the original Knockout.js, which was created to enhance and modernize the framework while maintaining its core principles. TKO and Knockout implement the [MVVM pattern](http://en.wikipedia.org/wiki/Model_View_ViewModel) (a modern variant of MVC) as a zero-dependency and small sized library. TKO makes it easy to create rich, desktop-like user interfaces with JavaScript/Typescript and HTML. It uses *observers* to automatically keep your UI in sync with an underlying data model, along with a powerful and extensible set of *declarative bindings* to enable productive development. |
15 | | - |
16 | | -TKO aims to provide developers with a more robust, modular, and maintainable codebase in [Typescript](https://www.typescriptlang.org/), making it easier to build rich, responsive, and maintainable web applications. |
17 | | - |
18 | | - |
19 | | - |
20 | | -## Getting Started |
21 | | - |
22 | | -To install use one of the usual package managers e.g. |
23 | | - |
24 | | -- $ `yarn add @tko/build.reference` |
25 | | -- $ `npm install @tko/build.reference` |
26 | | -- $ `pnpm install @tko/build.reference` |
27 | | - |
28 | | - |
29 | | -Over CDN |
30 | | - |
31 | | -- Reference Build: https://cdn.jsdelivr.net/npm/@tko/build.reference/dist/build.reference.min.js |
32 | | - |
33 | | -For more details, see |
34 | | - |
35 | | - * TKO - Documentation (https://tko.io) |
36 | | - * Knockout - Documentation (http://knockoutjs.com/documentation/introduction.html) |
37 | | - * Online examples at [http://knockoutjs.com/examples/](http://knockoutjs.com/examples/) |
38 | | - * Stackoverflow https://stackoverflow.com/questions/tagged/knockout.js |
39 | | - |
40 | | -## Knockout Build |
41 | | - |
42 | | -The Knockout build has some backwards compatibility that is not in the reference build. See the build differences, here: https://tko.io/3to4 |
43 | | - |
44 | | -It's available as `@tko/build.knockout`, and over CDN: |
45 | | - |
46 | | -- Knockout Build https://cdn.jsdelivr.net/npm/@tko/build.knockout/dist/build.knockout.min.js |
47 | | - |
48 | | -### Using the Monorepo |
| 4 | +[](https://github.com/knockout/tko/actions/workflows/test-headless.yml) |
| 5 | +[](https://github.com/knockout/tko/actions/workflows/lint-and-typecheck.yml) |
49 | 6 |
|
50 | | -| Command | Effect | |
51 | | -| ------- | ------ | |
52 | | -| $ `git clone git@github.com:knockout/tko` | Clone the repository. | |
53 | | -| $ `bun install` | Install all dependencies | |
54 | | -| $ `make` | Build all packages (ESM, CommonJS, MJS) | |
55 | | -| $ `make test` | Run all tests (Vitest, headless Chromium via Playwright) | |
56 | | -| $ `bunx changeset add` | Add a changeset for package behavior changes in your PR | |
| 7 | +Modern successor to [Knockout.js](https://knockoutjs.com). Reactive data binding and UI templating with zero runtime dependencies. |
57 | 8 |
|
58 | | -Checkout the `Makefile` for more commands that can be executed with `make {command}`. |
| 9 | +Knockout applications written over a decade ago are still running in production. TKO gives them a path forward — swap the script tag, verify your tests pass, then optionally adopt modern features like TSX, native providers, and modular packages. |
59 | 10 |
|
60 | | -In each individual `packages/*/` directory, you can also run: |
| 11 | +## Quick start |
61 | 12 |
|
62 | | -| Command | Effect | |
63 | | -| --- | --- | |
64 | | -| $ `bunx vitest run` | Run all tests (headless Chromium via Playwright) | |
65 | | - |
66 | | -### Testing |
67 | | - |
68 | | -Tests use Vitest browser mode with Playwright (headless Chromium). Assertions use Chai and Sinon. |
69 | | - |
70 | | -Run `make test` or `bunx vitest run`. |
71 | | - |
72 | | -Other options: |
73 | | - |
74 | | -- `make ci` — use Sauce Labs to test a variety of platforms; requires an account at Sauce Labs and `SAUCE_USERNAME` and `SAUCE_ACCESS_KEY` to be set in the environment. |
75 | | - |
76 | | -## Objectives |
77 | | - |
78 | | -TKO aims to become a base for future versions of Knockout. The objectives include: |
79 | | - |
80 | | -- Modularization into ES6 and separate projects, with compilation using an ES6 compiler like [Esbuild](https://esbuild.github.io/). This solves several problems with Knockout, including: |
81 | | - - Some folks want to roll-their-own with e.g. removing components |
82 | | - - Compilation is now with Closure compiler, which is actually transliterating – meaning the *debug* and *minified* versions have different code paths (mostly in the form of things exposed in *debug* being missing in the *minified* version) |
83 | | - - The compilation of Knockout is just concatenation, leading to difficulties with maintainance, severance, and replacement |
84 | | -- Documentation inline in the source code. This aims to make it easier to document, by making documentation adjacent to the code about-which it speaks. Also, we aim to have examples in the documentation. |
85 | | -- A more comprehensive home page. The hope is to have something fun and fancy, and we have [a rough prototype](http://brianmhunt.github.io/knockout). |
86 | | -- Better setup for plugins. The problems with Knockout include: |
87 | | - - There's no central, searchable repository for knockout |
88 | | - - What should be simple plugins (e.g. binding handlers or providers) are complex, including: |
89 | | - - Built-ins have first-class access to quite a bit of good Knockout code, but plugins generally have second-class access and often have to duplicate Knockout internals |
90 | | - - Quality plugins have lots of boilerplate for compilation, release, documentation, and testing |
91 | | -- Type-safe with Typescript |
92 | | -- CSP compliant |
93 | | -- JSX/TSX support |
94 | | - |
95 | | -## Zero-dependency and small sized - with all plugins, bundled only ~125KB |
| 13 | +```html |
| 14 | +<script type="module"> |
| 15 | + import ko from 'https://esm.run/@tko/build.reference' |
| 16 | +</script> |
| 17 | +``` |
96 | 18 |
|
97 | | -Created with https://esbuild.github.io/analyze/ |
98 | | - |
| 19 | +Or as a classic script: |
99 | 20 |
|
100 | | -## JQUERY and TKO |
| 21 | +```html |
| 22 | +<script src="https://cdn.jsdelivr.net/npm/@tko/build.reference/dist/browser.min.js"></script> |
| 23 | +``` |
101 | 24 |
|
102 | | -Optionally TKO can use JQuery for CSS-Manipulation and HTML-Templates (only if HTML5-Template-Tag no supported). All tests are based on JQuery 3.7. |
103 | | -In the future we will probably remove the usage of JQuery in TKO, as many features have already been migrated to native APIs. Compatibility with JQuery in an application will remain. |
104 | | -You can set useOnlyNativeEvents to false, so JQuery is also use for event-registration. Note: Some tests fails in this case ('change'-event doesn't fire). You can set useTemplateTag to false, so disable using HTML5-Template-Tags. |
| 25 | +Or via a package manager: |
105 | 26 |
|
106 | | -## Sanitizing HTML-Templates |
| 27 | +```sh |
| 28 | +npm install @tko/build.reference |
| 29 | +``` |
107 | 30 |
|
108 | | -TKO supports HTML sanitization through configurable options. To sanitize HTML templates, you can override `options.sanitizeHtmlTemplate` with a library like [DOMPurify](https://github.com/cure53/DOMPurify) or [validator.js](https://github.com/validatorjs/validator.js). |
| 31 | +**[Full documentation at tko.io](https://tko.io)** |
109 | 32 |
|
110 | | -Additionally, implement a well-configured [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) to provide an extra layer of protection against XSS attacks. |
| 33 | +## Builds |
111 | 34 |
|
| 35 | +| Package | Description | |
| 36 | +|---------|-------------| |
| 37 | +| `@tko/build.reference` | **Recommended.** Modern build with TSX, `ko-*` attributes, native provider, strict equality. | |
| 38 | +| `@tko/build.knockout` | Knockout 3.x compatibility. [Migrating from Knockout?](https://tko.io/3to4/) Start here. | |
112 | 39 |
|
113 | | -## Overview of the development stack |
| 40 | +## Development |
114 | 41 |
|
115 | | -- **bun** -> Package manager and script runner |
116 | | -- **make** -> Build tasks |
117 | | -- **esbuild** -> TS/JS compiler and bundler |
118 | | -- **lerna** -> Monorepo build chain |
| 42 | +| Command | Description | |
| 43 | +|---------|-------------| |
| 44 | +| `bun install` | Install dependencies | |
| 45 | +| `bun run build` | Build all packages | |
| 46 | +| `bun run test` | Run tests (Vitest, headless Chromium) | |
| 47 | +| `bun run verify` | Full check: lint + typecheck + build + test | |
| 48 | +| `bun run knip` | Detect unused code and dependencies | |
| 49 | +| `bun run check` | Biome lint + format | |
119 | 50 |
|
120 | | ---- |
| 51 | +See [AGENTS.md](AGENTS.md) for full contributor instructions. |
121 | 52 |
|
122 | | -- Test Runner -> Vitest (browser mode, Playwright) |
123 | | -- Test Environment -> headless Chromium, Firefox, WebKit |
124 | | -- Type Checker -> tsc (TypeScript 6) + tsgo (TypeScript 7, 6x faster) |
125 | | -- Linting -> ESLint |
126 | | -- Formatting -> Prettier |
127 | | -- Assertions -> Chai + Sinon |
| 53 | +## Architecture |
128 | 54 |
|
129 | | -## WSL Setup |
| 55 | +27 modular `@tko/*` packages, two bundled builds. TypeScript source, esbuild compilation, Bun workspaces. |
130 | 56 |
|
131 | | -Install Playwright browser dependencies: |
| 57 | +The core model: observables notify subscribers when they change. Bindings subscribe to observables and update the DOM. No virtual DOM, no diffing — updates are proportional to what changed, not tree size. |
132 | 58 |
|
133 | | -```bash |
134 | | -bunx playwright install --with-deps chromium |
135 | | -``` |
| 59 | +See [agents/soul.md](https://tko.io/agents/soul.md) for the design philosophy. |
136 | 60 |
|
137 | | -Install Firefox for "make test-headless-ff": |
138 | | -```bash |
139 | | -sudo add-apt-repository ppa:mozillateam/ppa |
140 | | -sudo apt install xvfb firefox-esr |
141 | | -sudo ln -s /usr/lib/firefox-esr/firefox.sh /usr/bin/firefox |
| 61 | +## Direction |
142 | 62 |
|
143 | | -or |
144 | | -export FIREFOX_BIN=/usr/bin/firefox-esr |
145 | | -``` |
146 | | - |
147 | | -## Next steps |
148 | | - |
149 | | -There's an [issue for that](https://github.com/knockout/tko/issues/1). |
| 63 | +TKO is moving toward an AI-maintained "dark factory" model — where the tooling, tests, and documentation are robust enough that AI agents can handle routine maintenance autonomously. See [plans/dark-factory.md](plans/dark-factory.md). |
150 | 64 |
|
151 | 65 | ## License |
152 | 66 |
|
153 | | -MIT license - [http://www.opensource.org/licenses/mit-license.php.](http://www.opensource.org/licenses/mit-license.php) |
154 | | - |
155 | | -## Credits |
156 | | -- Knockout Type Definitions by: [Maxime LUCE](https://github.com/SomaticIT), [Michael Best](https://github.com/mbest) |
157 | | - - https://github.com/knockout/knockout/blob/master/build/types/knockout.d.ts#L404 |
158 | | -- Team-Project: https://github.com/knockout |
159 | | -- http://knockoutjs.com / [Steve Sanderson](https://github.com/SteveSanderson), [Michael Best](https://github.com/mbest) |
160 | | - |
161 | | -## Shout Outs |
| 67 | +MIT — [opensource.org/licenses/MIT](https://opensource.org/licenses/MIT) |
162 | 68 |
|
163 | | -<div> |
164 | | - <a href='http://browserstack.com'> |
165 | | - Browser Stack |
166 | | - </a> |
167 | | -<div> |
| 69 | +Copyright (c) TKO contributors. Based on [Knockout.js](https://knockoutjs.com). |
0 commit comments