kerfjs 4.4.0 → 4.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +33 -34
- package/ai/manifest.json +1 -1
- package/package.json +1 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [4.4.1] - 2026-08-26
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
- Overhauled the README landing page: new one-line tagline, npm/size/license/TypeScript-types badges, a hoisted "Quick start" (install + `tsconfig`) right under the hook, and a jump nav (Quick start · Why kerf · Quick tour · Docs). The counter example now shows `delegate()` wiring the click handler.
|
|
14
|
+
- Reworked the homepage hero to lead with the value proposition ("Reactive UI that touches only the bytes that changed"), with "Introducing Kerf" demoted to an eyebrow, a right-sized logo, tighter vertical spacing, and "Get started" as the single filled primary action ("View examples" now a secondary/outline button).
|
|
15
|
+
- Redesigned the complete-apps index as a card grid — each app appears once with an animated preview, a one-line summary, and "Run live" / "Source" buttons.
|
|
16
|
+
- Every complete-app page now shows "Run live" and "View source" as buttons above the demo instead of small inline text links.
|
|
17
|
+
- Rewrote the site's docs pages as hand-authored consumer content (cleaner headings, no internal section numbers) rather than verbatim copies of the internal design docs.
|
|
18
|
+
- Renamed the migration guides' "Side-by-side code" heading to "Section by section" (the sections stack code blocks rather than showing true columns), across all framework pages.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
- The getting-started and Markdown-editor demo animations now open on a non-blank frame — real code and a rendered heading are visible immediately instead of an empty pane.
|
|
22
|
+
- Added a horizontal-scroll shadow affordance to wide tables so off-screen columns are discoverable on narrow viewports.
|
|
23
|
+
- Shortened the longest demo alt text on the router and virtual-list pages for more concise screen-reader output.
|
|
24
|
+
- Moved framework version labels out of the performance table's framework column onto a methodology line below, keeping the column a clean label.
|
|
25
|
+
|
|
9
26
|
## [4.4.0] - 2026-08-23
|
|
10
27
|
|
|
11
28
|
|
package/README.md
CHANGED
|
@@ -4,61 +4,72 @@
|
|
|
4
4
|
|
|
5
5
|
<h1 align="center">Kerf</h1>
|
|
6
6
|
|
|
7
|
-
<p align="center"><em>The smallest cut.</em></p>
|
|
7
|
+
<p align="center"><em>A tiny reactive UI framework. The smallest cut.</em></p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
10
|
<a href="https://brianwestphal.github.io/kerf/"><strong>brianwestphal.github.io/kerf</strong></a> — docs · examples · live demo
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://www.npmjs.com/package/kerfjs"><img src="https://img.shields.io/npm/v/kerfjs.svg" alt="npm version" /></a>
|
|
15
|
+
<img src="https://img.shields.io/badge/min%2Bgzip-~12%20KB-brightgreen.svg" alt="~12 KB minified and gzipped" />
|
|
16
|
+
<img src="https://img.shields.io/npm/l/kerfjs.svg" alt="MIT license" />
|
|
17
|
+
<img src="https://img.shields.io/badge/types-included-3178c6.svg" alt="TypeScript types included" />
|
|
18
|
+
</p>
|
|
19
|
+
|
|
13
20
|
---
|
|
14
21
|
|
|
15
|
-
> Introducing Kerf.
|
|
16
|
-
> The smallest cut.
|
|
17
|
-
>
|
|
18
22
|
> ~12 KB. No virtual DOM. No compiler. No magic.
|
|
19
23
|
> Reactive UI that touches only the bytes that changed.
|
|
20
24
|
|
|
21
25
|
```ts
|
|
22
|
-
import { signal, mount } from 'kerfjs';
|
|
26
|
+
import { signal, mount, delegate } from 'kerfjs';
|
|
23
27
|
|
|
24
28
|
const count = signal(0);
|
|
29
|
+
const app = document.getElementById('app')!;
|
|
25
30
|
|
|
26
|
-
mount(
|
|
31
|
+
mount(app, () => (
|
|
27
32
|
<div>
|
|
28
33
|
<button data-action="inc">+</button>
|
|
29
34
|
<span>{count.value}</span>
|
|
30
35
|
</div>
|
|
31
36
|
));
|
|
37
|
+
|
|
38
|
+
delegate(app, 'click', '[data-action="inc"]', () => count.value++);
|
|
32
39
|
```
|
|
33
40
|
|
|
34
41
|
That's it. Your JSX renders to HTML strings, kerf's native diff applies the minimum DOM mutations to make the live tree match, and signals re-run the render only when something they read actually changed.
|
|
35
42
|
|
|
36
43
|
Here's the whole development loop — write a component, run the dev server, click around, edit, watch the browser pick it up:
|
|
37
44
|
|
|
38
|
-
[](https://brianwestphal.github.io/kerf/getting-started/)
|
|
46
|
+
**[Quick start](#quick-start) · [Why kerf](#why-kerf) · [Quick tour](#quick-tour) · [Docs & examples](https://brianwestphal.github.io/kerf/)**
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
## Quick start
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
```bash
|
|
51
|
+
npm install kerfjs
|
|
52
|
+
```
|
|
47
53
|
|
|
48
|
-
|
|
54
|
+
```jsonc
|
|
55
|
+
// tsconfig.json — point JSX at kerf
|
|
56
|
+
{ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "kerfjs" } }
|
|
57
|
+
```
|
|
49
58
|
|
|
50
|
-
|
|
59
|
+
Write plain `.tsx` and build with your existing esbuild / Vite / tsup — no extra plugin. New here? Read the [5-minute orientation](https://github.com/brianwestphal/kerf/blob/main/docs/orientation.md), or open a [complete example](https://brianwestphal.github.io/kerf/examples/complete/).
|
|
60
|
+
## Why Kerf
|
|
51
61
|
|
|
52
|
-
|
|
62
|
+
1. **~12 KB, one dependency.** ~12 KB minified + gzipped including `@preact/signals-core` (~13 KB with `arraySignal`). No virtual DOM, no scheduler, no concurrent-mode machinery. On the official [krausest benchmark](https://krausest.github.io/js-framework-benchmark/current.html) kerf sits in the same cluster as Vue, Lit, and vanjs; Solid's compiler leads the update-path benchmarks, which kerf doesn't try to match by design — no compiler.
|
|
53
63
|
|
|
54
|
-
|
|
64
|
+
2. **No virtual DOM, no compiler.** JSX → HTML strings → native diff. DevTools shows the real DOM because it *is* the DOM.
|
|
55
65
|
|
|
56
|
-
|
|
66
|
+
3. **Values bind, structure re-renders.** Hand a signal *itself* into a JSX hole — `class={selectedId}` — and kerf binds that one node: on change, only that attribute updates, with no render re-run and no list reconcile. A selection flip on a 10,000-row table touches exactly one class. ([more →](#fine-grained-updates-bind-a-signal-into-a-hole))
|
|
57
67
|
|
|
58
|
-
|
|
68
|
+
4. **Focus, selection, and listeners survive re-renders — even mid-list.** The reconciler morphs instead of rebuilding, so caret position, IME composition, scroll, and delegated listeners survive every update; keyed rows are patched in place rather than recreated.
|
|
59
69
|
|
|
60
|
-
|
|
70
|
+
5. **Safe by default.** Text and attributes are HTML-escaped automatically, URL attributes are scheme-screened (`javascript:` dropped), and inline `on*` handlers are rejected outright — so untrusted data stays inert. `raw()` is the explicit, auditable opt-out.
|
|
61
71
|
|
|
72
|
+
**Plus, nothing you don't ask for:** JSX typed against the HTML standard (not React's props) · a ~18-export API with no hooks, lifecycle, or per-instance state · **nine** tree-shakeable companion subpaths (`router`, `list`, `overlay`, `async`, …) that stay out of the core until imported · an [ESLint plugin](https://brianwestphal.github.io/kerf/docs/eslint-plugin/) + opt-in dev warnings + a `create-kerf-component` scaffold · plain TS/JSX/ESM that drops into esbuild / Vite / tsup — or **no** build at all via the `html` tagged template.
|
|
62
73
|
## When to use Kerf
|
|
63
74
|
|
|
64
75
|
- **Hybrid desktop apps (Tauri / Electron)** — small bundle, predictable diff, debuggable runtime; ideal for the embedded webview.
|
|
@@ -247,21 +258,9 @@ mount(app, () => <div><nav>{/* <a href> links, auto-intercepted */}</nav>{router
|
|
|
247
258
|
|
|
248
259
|
Each subpath adds nothing to the main barrel until it's imported. See [`docs/8-api-reference.md`](./docs/8-api-reference.md) for the full list (`list`, `router`, `overlay`, `scope`, `async`, `timing`, `remount`, `attach`, `actions`).
|
|
249
260
|
|
|
250
|
-
##
|
|
251
|
-
|
|
252
|
-
```bash
|
|
253
|
-
npm install kerfjs
|
|
254
|
-
```
|
|
261
|
+
## Optional tooling
|
|
255
262
|
|
|
256
|
-
|
|
257
|
-
// tsconfig.json
|
|
258
|
-
{
|
|
259
|
-
"compilerOptions": {
|
|
260
|
-
"jsx": "react-jsx",
|
|
261
|
-
"jsxImportSource": "kerfjs"
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
```
|
|
263
|
+
Install and JSX setup are in [Quick start](#quick-start) above. These companion packages are opt-in.
|
|
265
264
|
|
|
266
265
|
### Optional: `eslint-plugin-kerfjs`
|
|
267
266
|
|
package/ai/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kerfjs",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.1",
|
|
4
4
|
"description": "Tiny reactive UI framework — fine-grained signals + DOM morphing + JSX. Apply the smallest possible cut to update your DOM.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -184,8 +184,6 @@
|
|
|
184
184
|
"gitgist": {
|
|
185
185
|
"exclude": [
|
|
186
186
|
"site/public/demos/*.svg",
|
|
187
|
-
"site/src/content/docs/docs/*",
|
|
188
|
-
"site/src/content/docs/api.md",
|
|
189
187
|
"ai/*",
|
|
190
188
|
"site/public/llms.txt",
|
|
191
189
|
"bench/results.json",
|