kmalakoff/knockback
kmalakoff/knockback has 1,057 GitHub stars and 69 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-09 11:22 UTC. Last push 2026-10-11.
Knockback.js provides Knockout.js magic for Backbone.js Models and Collections.
Measured star growth
- in 24h
- 0
- in 7 days
- Update delayed
- in 15 days
- Update delayed
- in 1 month
- Update delayed
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
Original
Knockback.js provides Knockout.js magic for Backbone.js Models and Collections.
Why Knockback?
- Make amazingly dynamic applications by applying a small number of simple principles
- Leverage the wonderful work from both the Backbone and Knockout communities
- Full TypeScript support with type definitions included
Installation
npm install knockback
Peer Dependencies
Knockback requires these peer dependencies:
npm install backbone knockout underscore
Examples
Simple
The HTML:
<label>First Name: </label><input data-bind="value: first_name, valueUpdate: 'keyup'" />
<label>Last Name: </label><input data-bind="value: last_name, valueUpdate: 'keyup'" />
And...engage:
import Backbone from 'backbone';
import ko from 'knockout';
import kb from '@mcpeasy/knockback';
const model = new Backbone.Model({ first_name: 'Bob', last_name: 'Smith' });
ko.applyBindings(kb.viewModel(model));
When you type in the input boxes, the values are properly transferred bi-directionally to the model and all other bound view models!
Advanced
The View Model:
import Backbone from 'backbone';
import ko from 'knockout';
import kb from '@mcpeasy/knockback';
// Create a model
const model = new Backbone.Model({ first_name: 'Bob', last_name: 'Smith' });
interface PersonViewModel {
first_name: ko.Observable<string>;
last_name: ko.Observable<string>;
full_name: ko.Computed<string>;
}
// Create a view model with a computed property
const vm = kb.viewModel<PersonViewModel>(model, {
extend: (vm) => ({
full_name: ko.computed(() => `${vm.first_name()} ${vm.last_name()}`);
}),
});
// Apply bindings
ko.applyBindings(vm);
// ... do stuff then clean up
vm.dispose();
Named imports are also supported if you prefer them:
```typescript
import { viewModel } from '@mcpeasy/knockback';
const vm = viewModel<PersonViewModel>(model);
vm.dispose();
// dispose() is attached automatically and is called by releaseOnNodeRemove / KO component disposal. // You no longer call destroy() manually.
You can also pass `extend` as a plain object if you prefer:
```typescript
const vm = kb.viewModel<PersonViewModel>(model, {
extend: {
full_name: ko.computed(() => `${model.get('first_name')} ${model.get('last_name')}`),
},
});
The HTML:
<h1 data-bind="text: 'Hello ' + full_name()"></h1>
<label>First Name: </label><input data-bind="value: first_name, valueUpdate: 'keyup'" />
<label>Last Name: </label><input data-bind="value: last_name, valueUpdate: 'keyup'" />
Now, the greeting updates as you type!
Breaking Changes in v2.0
Knockback v2.0 uses modern TypeScript conventions. All option names and API properties have been changed from snake_case to camelCase:
Core Options:
| Old (v1.x) | New (v2.0) |
|---|---|
static_defaults |
staticDefaults |
event_watcher |
eventWatcher |
view_model |
viewModel |
models_only |
modelsOnly |
auto_compact |
autoCompact |
sort_attribute |
sortAttribute |
Plugin Options:
| Old (v1.x) | New (v2.0) | Plugin |
|---|---|---|
kb.locale_manager |
kb.localeManager |
Localization |
event_selector |
eventSelector |
Triggering |
validation_options |
validationOptions |
Validation |
no_attach |
noAttach |
Validation |
$error_count |
$errorCount |
Validation |
$active_error |
$activeError |
Validation |
Migration example:
// v1.x (old)
const co = kb.collectionObservable(collection, {
view_model: PersonViewModel,
sort_attribute: 'name',
auto_compact: true,
});
// v2.0 (new)
const co = kb.collectionObservable(collection, {
viewModel: PersonViewModel,
sortAttribute: 'name',
autoCompact: true,
});
API
Core Functions
observable(model, key, options?)- Create an observable bound to a model attributeviewModel(model, options?)- Create observables for all model attributescollectionObservable(collection, options?)- Create an observable array bound to a collectiondispose()- Attached to view models/observables; called byreleaseOnNodeRemoveand KO component disposaldispose(obj)- Helper to dispose plain objects that contain Knockback observables
Plugins
defaultObservable<T>(observable, defaultValue)- Provide default valuesformattedObservable(format, ...args)- Two-way string formattinglocalizedObservable(value, options)- Locale-aware observables
Localization (typed)
import kb from '@mcpeasy/knockback';
import type { LocaleManager } from '@mcpeasy/knockback';
class MyLocaleManager implements LocaleManager {
get(id: string): string {
return id;
}
getLocale(): string {
return 'en';
}
setLocale(_locale: string): void {}
}
kb.setLocaleManager(new MyLocaleManager());
const localeManager = kb.getLocaleManager<MyLocaleManager>();
Leak checks with Statistics
const stats = new kb.Statistics();
kb.setStatistics(stats);
const before = stats.snapshot();
// ... route change + dispose old page ...
const after = stats.snapshot();
const delta = stats.diff(before, after);
console.log(delta);
triggeredObservable(emitter, event)- Event-based observable updatesvalueValidator(observable, validators)- Value validation
Documentation
Dependencies
- Backbone.js - provides the Model layer
- Knockout.js - provides the ViewModel layer foundations
- Underscore.js - provides JavaScript utilities
Contributing
To build the library:
npm run build
To run tests:
npm test
License
MIT
Explore related projects
codecrafters-io/build-your-own-x
Master programming by recreating your favorite technologies from scratch.
561,363 starspublic-apis/public-apis
A collective list of free APIs
497,621 starsmorluto/rea
Reverse engineer anything with agents, from app behavior down to native binaries.
447,042 starsopenclaw/openclaw
The AI that really does things. Any OS. Any Platform. The lobster way. 🦞
394,259 stars