Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

N34 Diff Preview

Deno Node Bun Browser

What is N34?

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.

Installation

Deno:

deno add npm:@neabyte/n34-diff

npm:

npm install @neabyte/n34-diff

CDN (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>

Usage

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.

Non-Stream

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 }
// ]

Stream

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.

Examples

N34 Diff Demo

Runnable end-to-end demos live in examples/:

API

N34.apply(original, edit, options?)

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)
}

N34.stream(original, options?)

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.

LLM Tool Schemas

Pre-built schemas for tool calling live in schemas/:

Build

npm run build

Testing

deno task check
deno task test

Benchmark

deno task bench
N34 Diff Benchmark

Runnable end-to-end benchmarks live in bench/:

License

Code in this repository is licensed under Apache 2.0, documentation is licensed under CC-BY-4.0.

About

Turn lazy LLM patch output into precise file updates through fuzzy line matching, streaming hunk delivery, and unicode-tolerant anchors.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages