Modify strings, generate sourcemaps
magic-string is a lightweight utility designed for modifying JavaScript source code while maintaining accurate sourcemap information. Unlike native string methods that lose positional context after edits, magic-string tracks every transformation, enabling build tools to generate correct sourcemaps that map transformed code back to original source files.
The library is foundational infrastructure in modern JavaScript tooling—Rollup uses it for tree-shaking and code splitting, Svelte and Vue compilers use it for template transformation, and Vite leverages it for fast HMR updates. With nearly 90 million weekly downloads, it's a critical dependency in the build tool ecosystem despite most developers never importing it directly.
magic-string provides a chainable API for operations like remove, update, prepend, and append that record changes without mutating the original string. When you call toString(), it efficiently reconstructs the modified string. When you call generateMap(), it produces a v3 sourcemap reflecting all transformations. This separation allows build tools to perform multiple sequential edits while preserving the ability to map final output positions to original source locations.
The package is intentionally minimal—around 4KB minified—focusing solely on position-aware string manipulation. It doesn't parse code or understand syntax; it operates on character ranges. This makes it fast and flexible enough to work downstream of any parser (Babel, Acorn, SWC) that provides start/end positions for AST nodes.
import MagicString from 'magic-string';
const source = `
function add(a, b) {
console.log('adding');
return a + b;
}
export { add };
`;
const s = new MagicString(source);
// Remove console.log statement (positions from a real parser)
s.remove(30, 54); // removes ' console.log(\'adding\');\n'
// Rename function for minification
s.update(10, 13, 'a').update(14, 15, 'x').update(17, 18, 'y');
// Add export comment
s.prepend('// Auto-generated exports\n');
// Generate transformed code
const output = s.toString();
console.log(output);
// Output:
// // Auto-generated exports
// function a(x, y) {
// return x + y;
// }
// export { add };
// Generate sourcemap
const map = s.generateMap({
source: 'original.js',
file: 'output.js',
includeContent: true
});
console.log(map.mappings); // VLQ-encoded position mappings
console.log(s.hasChanged()); // trueBundler tree-shaking: Rollup uses magic-string to remove unused exports by identifying dead code ranges from static analysis, deleting those character spans, then generating sourcemaps that map the compacted bundle back to original files.
Template compilation: Svelte and Vue compilers parse templates into AST nodes, then use magic-string to replace template syntax (like {#if} blocks or v-for directives) with compiled JavaScript while maintaining line/column mappings for runtime error traces.
Code transformation plugins: Vite and esbuild plugins wrap magic-string to perform import rewrites, inject polyfills, or strip TypeScript types—any transform that needs to preserve sourcemap accuracy through multiple plugin passes.
Minifier preprocessing: Tools that normalize code before minification (like removing comments or whitespace in strategic locations) use magic-string to ensure the minifier's output sourcemap chains correctly to the pre-normalized source.
Documentation generators: Extract JSDoc comments by removing code ranges while keeping comments intact, or inject generated type annotations into source files for tooling that requires inline types.
npm install magic-stringpnpm add magic-stringbun add magic-string