N34 is a fuzzy diff engine that applies LLM-generated edits to source text without relying on strict line numbers. Hunks are located via anchor and soft canonicalization, giving whitespace and Unicode tolerance. It runs synchronously via apply() for whole edits, or incrementally via stream() for chunked LLM output, and returns both the patched result and structured line-by-line diff metadata.
Inspired by Morph Fast Apply - the hosted merge model wired into agents like Cursor, Windsurf, Claude Code, Codex, Amp, OpenCode, Kilo Code, and Antigravity. N34 keeps the same "apply LLM edits without line numbers" idea but runs fully in-process with zero dependencies and zero network calls, so it works the same in a browser tab, a Deno script, or an offline CLI.
Local file editing at 669 apply/s and 99% accuracy across 100 languages with $0.00 cost, 0 network calls, 0 dependencies.
Deno:
deno add npm:@neabyte/n34-diffnpm:
npm install @neabyte/n34-diffCDN (jsDelivr/esm.sh):
<script type="module">
import N34 from 'https://cdn.jsdelivr.net/npm/@neabyte/n34-diff/dist/index.mjs'
</script>Or via esm.sh:
<script type="module">
import N34 from 'https://esm.sh/@neabyte/n34-diff'
</script>Warning
This is a pure text-to-text API with no filesystem I/O, designed to run in any environment including browsers, CLI, and terminal applications. Filesystem operations such as reading, writing, and deleting files are left to the consumer.
import N34 from '@neabyte/n34-diff'
const result = N34.apply(
'function add(a, b) {\n return a - b\n}',
'<<<<<<< SKIP\nfunction add(a, b) {\n return a + b\n}\n<<<<<<< SKIP',
{ timeout: 10000 }
)
console.log(result.before)
// function add(a, b) {
// return a - b
// }
console.log(result.after)
// function add(a, b) {
// return a + b
// }
console.log(result.diff)
// [
// { type: 'equal', value: 'function add(a, b) {', oldLine: 1, newLine: 1 },
// { type: 'delete', value: ' return a - b', oldLine: 2, newLine: null },
// { type: 'add', value: ' return a + b', oldLine: null, newLine: 2 },
// { type: 'equal', value: '}', oldLine: 3, newLine: 3 }
// ]import N34 from '@neabyte/n34-diff'
/** Open stream with idle timeout */
const stream = N34.stream('<original_code>', {
timeout: 10000
})
/** Emit each resolved hunk patch */
stream.callback(result => {
console.log(result.before)
console.log(result.after)
console.log(result.diff)
})
stream.push(chunk1)
stream.push(chunk2)
stream.end()The stream emits one patch per resolved hunk. Each patch has the same shape as apply()'s result: before, after, and structured diff scoped to that hunk's slice of the source.
Runnable end-to-end demos live in examples/:
examples/index.ts- Ollama chat withapply_edittool call, then side-by-side diff
| Parameter | Type | Description |
|---|---|---|
original |
string |
Original source text |
edit |
string |
N34 edit body wrapped with <<<<<<< SKIP markers |
options |
ApplyOption |
Optional. { timeout?: number } in milliseconds. |
Default timeout is 60000 ms. Pass Infinity to disable.
Returns: ApplyResult
type ApplyResult = {
before: string // Original source text
after: string // Patched output text
diff: DiffLine[] // Structured line-by-line diff
}
type DiffLine = {
type: 'add' | 'delete' | 'equal'
value: string // Line content
oldLine: number | null // Source line number (null for adds)
newLine: number | null // Result line number (null for deletes)
}| Parameter | Type | Description |
|---|---|---|
original |
string |
Original source text |
options |
ApplyOption |
Optional. { timeout?: number } in milliseconds (idle deadline). |
The stream idle timeout resets on every push(). If no chunk arrives within the window, the stream closes and further pushes throw.
Returns: StreamHandle
type StreamHandle = {
callback(listener: ((patch: ApplyResult) => void) | null): void
push(chunk: string): void
end(): void
}callback(listener)- Registers or clears the hunk listener and flushes buffered patches.push(chunk)- Feeds a text chunk while the segmenter buffers partial lines until a newline.end()- Signals end of input so remaining buffered text flushes and final hunks are emitted.
Pre-built schemas for tool calling live in schemas/:
schemas/openai.json- OpenAI function calling formatschemas/anthropic.json- Anthropic tool use format
npm run builddeno task checkdeno task testdeno task benchRunnable end-to-end benchmarks live in bench/:
bench/apply.bench.ts-N34.apply()across 100-language corpus and scaling ladderbench/stream.bench.ts-N34.stream()across edge cases and chunk-width ladderbench/output.txt- Latest recorded run for reference
Code in this repository is licensed under Apache 2.0, documentation is licensed under CC-BY-4.0.


