Cross-language port (file creation)
Whole-file with `allowCreate` handles new paths. Useful for language ports, scaffolding generators, "explain this and write the test" prompts.
applyEdits with allowCreate: true (the default) handles new files. Pair with the
whole-file format and you've got a one-shot scaffolder.
const py = await readFile("src/parser.py", "utf8");
const { text } = await generateText({
model: openai("gpt-4o"),
system: WHOLE_FILE_PROMPT,
prompt: `Port this Python module to Rust. Output as src/parser.rs:\n\n\`\`\`py\n${py}\n\`\`\``,
});
const [r] = await applyEdits(text, async () => null, { formats: ["whole-file"] });
if (r?.ok) await writeFile(r.path, r.after);Why the file reader returns null
The target file (src/parser.rs) doesn't exist yet. Returning null from the file reader
tells the applier to treat this as a create. With allowCreate: true (default), the
applier accepts it; with allowCreate: false, you get missing-original back.
Creating multiple files in one response
Same pattern — the model emits one fenced block per file:
src/foo.rs
```rs
... contents ...src/bar.rs
... contents ...
Both files are created. Order in the response = order they're applied.Framework migration with unified diffs
Multi-hunk changes per file — Next 13 → 15, React class → hooks, Express 4 → 5. Unified diff stops the model from emitting placeholders.
Live diff preview UI
streamEdits yields each completed edit the moment its closing fence arrives. Flicker each file's diff into the UI before the model finishes.