react-ko
Version:
React + Knockout integration library
200 lines (144 loc) ⢠4.44 kB
Markdown
# react-ko
en English | [ja ę„ę¬čŖ](./README.ja.md)
[](https://www.npmjs.com/package/react-ko)
> š§ A minimal bridge to use Knockout.js inside React components.
> Combine Knockout's reactivity with React's component architecture ā clean, scoped, and type-safe.
## ⨠Features
- ā
Seamless two-way data binding with Knockout observables
- ā
Use `data-bind="..."` directly in JSX / TSX
- ā
Scoped ViewModel logic via `<KnockoutScope>`
- ā
One-line root binding via `<RootKnockoutProvider>`
- ā
Zero boilerplate ā no event handlers or local state
- ā
Full TypeScript & JavaScript support with zero-config
- ā
No runtime dependencies other than Knockout & React
## š¦ Installation
```bash
npm install react-ko knockout
```
> ā ļø This library requires `react` (v18+) and `knockout` (v3.5+) as peer dependencies.
## ā” Quick Start with Starter Template
### ā¶ TypeScript
```bash
npx degit menimani/react-ko-starter-ts my-app-ts
cd my-app-ts
npm install && npm run dev
```
š GitHub: [react-ko-starter-ts](https://github.com/menimani/react-ko-starter-ts)
### ā¶ JavaScript
```bash
npx degit menimani/react-ko-starter-js my-app-js
cd my-app-js
npm install && npm run dev
```
š GitHub: [react-ko-starter-js](https://github.com/menimani/react-ko-starter-js)
## š Quick Usage (JSX / TSX)
```tsx
import ko from 'knockout'
import { RootKnockoutProvider, KnockoutScope } from 'react-ko'
const viewModel = {
name: ko.observable('Alice')
}
<RootKnockoutProvider viewModel={{}}>
<KnockoutScope viewModel={viewModel}>
<input data-bind="value: name" />
</KnockoutScope>
</RootKnockoutProvider>
```
## š§© Custom Component Example
### ā¶ļø JavaScript (JSX)
```jsx
import { KnockoutScope } from 'react-ko'
export function KoInput({ value }) {
const vm = { value }
return (
<KnockoutScope viewModel={vm}>
<input data-bind="value: value" />
</KnockoutScope>
)
}
```
### ā¶ļø TypeScript (TSX)
```tsx
import ko from 'knockout'
import { KnockoutScope } from 'react-ko'
type Props = {
value: ko.Observable<string>
}
export function KoInput({ value }: Props) {
const vm = { value }
return (
<KnockoutScope viewModel={vm}>
<input data-bind="value: value" />
</KnockoutScope>
)
}
```
### ā¶ļø Component Usage
```tsx
const vm = {
name: ko.observable('Alice')
}
<KnockoutScope viewModel={vm}>
<KoInput value={vm.name} />
</KnockoutScope>
```
### ā Deprecated Components
> ā ļø The following components are deprecated and will be removed in a future release (v2.0.0):
>
> - `KoIfComment`
> - `KoIfNotComment`
> - `KoForeachComment`
>
> Please use the unified components instead:
>
> - ā
`KoIf`
> - ā
`KoIfNot`
> - ā
`KoForeach`
>
> These new components are fully JSX-compliant and no longer rely on HTML comment nodes.
## š¤ Why react-ko?
Without react-ko (pure React):
```tsx
<input
value={value}
onChange={(e) => setValue(e.target.value)}
style={{ color }}
/>
```
With react-ko:
```tsx
<input data-bind="value: value, style: { color: color }" />
```
No need to wire events or manage local state.
Let Knockout observables do the work ā even in modern React.
---
## š Folder Structure
```
src/
āāā components/ // Components
ā āāā scope/ // Core components for binding with Knockout
ā ā āāā KnockoutScope.tsx // Manages the Knockout and React scope
ā ā āāā RootKnockoutProvider.tsx // Root component, initializes Knockout
ā āāā structural/ // Generic components for Knockout flow control
ā ā āāā KoIf.tsx // ko if: control component
ā ā āāā KoIfNot.tsx // ko ifnot: control component
ā ā āāā KoForeach.tsx // ko foreach: control component
āāā context/ // Context management
ā āāā AppViewModelContext.ts // Context related to Knockout's ViewModel
```
---
## š Development
```bash
npm install
npm run build
```
---
## š License
MIT