// the find
Rich-Harris/magic-string
Manipulate strings like a wizard
magic-string does string-level find/replace/insert/remove operations on source text while tracking positions so you can emit a correct source map at the end, without parsing an AST. It's for anyone building a bundler, transpiler, or codemod that only needs light text surgery — Rollup, Svelte, and a chunk of the Vite plugin ecosystem run on it.
The API is small enough to hold in your head — update/overwrite/remove/append/prepend plus move for reordering ranges — and it works on any text, not just JS, since there's no parser involved. Hi-res mapping has three tiers (per-character, word-boundary, and an experimental range-mapping mode) so you can trade sourcemap precision for size instead of being stuck with one default. Bundle handles multi-file concatenation with per-source separators, ignoreList for devtools, and toMagicString() to flatten everything back into one editable instance when you need further passes.
It's ESM-only, so anything still on CommonJS needs a dynamic import or a bundler that papers over the interop. Edits are range-based against the original string, and overlapping or re-splitting an already-edited chunk throws at runtime ('cannot split a chunk that has already been edited') rather than being caught earlier — the README points you to a separate package, magic-string-stack, if you need to chain edit rounds cleanly, which means the core library punts on a case people will hit. length() deliberately excludes content added via prepend/append, so it diverges from toString().length — a subtle footgun if you're doing your own position math on top of it.