A fast, zero-dependency string builder for Node.js with ESM, CommonJS, and TypeScript support. Collects string parts in an array and joins them on toString() — avoiding the cost of repeated string concatenation.
npm install string-builderconstStringBuilder=require("string-builder");importStringBuilderfrom"string-builder";importStringBuilderfrom"string-builder";constusers=[{name: "Alice",role: "admin"},{name: "Bob",role: "editor"},{name: "Carol",role: "viewer"},];constsb=newStringBuilder("User Report").appendLine().appendLine("============");for(constuserofusers){sb.appendFormat("- {name:U} ({role})",user).appendLine();}sb.appendLine("============").appendFormat("Total: {0} users",users.length);console.log(sb.toString());// User Report// ============// - ALICE (admin)// - BOB (editor)// - CAROL (viewer)// ============// Total: 3 usersconstitems=["Home","About","Contact"];constsb=newStringBuilder("<ul>").appendLine();for(constitemofitems){sb.appendFormat(" <li>{0}</li>",item).appendLine();}sb.append("</ul>");console.log(sb.toString());// <ul>// <li>Home</li>// <li>About</li>// <li>Contact</li>// </ul>constheaders=["id","name","score"];constrows=[{id: 1,name: "Alice",score: 95.5},{id: 2,name: "Bob",score: 87.0},{id: 3,name: "Carol",score: 91.3},];constsb=newStringBuilder().appendJoin(headers,",").appendLine();for(constrowofrows){sb.appendFormat("{id},{name},{score}",row).appendLine();}console.log(sb.toString());// id,name,score// 1,Alice,95.5// 2,Bob,87// 3,Carol,91.3functionbuildQuery({ table, fields, limit }){returnnewStringBuilder("SELECT ").appendJoin(fields,", ").appendFormat(" FROM {0}",table).appendFormat(" LIMIT {0}",limit).toString();}console.log(buildQuery({table: "users",fields: ["id","name","email"],limit: 10}));// SELECT id, name, email FROM users LIMIT 10constsb=newStringBuilder();// :U — uppercasesb.appendFormat("Hello, {0:U}!","world").appendLine();// → Hello, WORLD!// :L — lowercasesb.appendFormat("Status: {0:L}","ACTIVE").appendLine();// → Status: active// :n — thousand separatorsb.appendFormat("Revenue: {0:n}",1234567.89).appendLine();// → Revenue: 1,234,567.89// combined with named placeholderssb.appendFormat("{name:U} earned {amount:n}",{name: "alice",amount: 95000});// → ALICE earned 95,000constsb=newStringBuilder("world");sb.prepend("hello ");console.log(sb.toString());// hello worldsb.replace("world","there");console.log(sb.toString());// hello theresb.append(" and back again").replaceAll("a","@");console.log(sb.toString());// hello there @nd b@ck @g@inconstsb=newStringBuilder();console.log(sb.isEmpty);// trueconsole.log(sb.length);// 0sb.append("hello world");console.log(sb.isEmpty);// falseconsole.log(sb.length);// 11constsb=newStringBuilder();for(constidof[1,2,3]){sb.appendFormat("Processing item {0}...",id);console.log(sb.toString());sb.clear();}// Processing item 1...// Processing item 2...// Processing item 3...constbuf=Buffer.from([0x41,0x42,0x43]);// "ABC"constresult=newStringBuilder().append("string: ").append("hello").appendLine().append("number: ").append(42).appendLine().append("float: ").append(3.14).appendLine().append("bool: ").append(false).appendLine().append("buffer: ").append(buf).appendLine().append("zero: ").append(0).toString();console.log(result);// string: hello// number: 42// float: 3.14// bool: false// buffer: ABC// zero: 0Creates a new instance. Optionally accepts an initial value.
constsb=newStringBuilder("initial");Adds a value to the beginning of the buffer. null and undefined are ignored.
newStringBuilder("world").prepend("hello ").toString();// "hello world"Appends any value. null and undefined are silently ignored. Falsy values like 0, false, and "" are accepted.
sb.append("text").append(42).append(false).append(Buffer.from([0x30]));Appends a newline (\n on Unix, \r\n on Windows), then the optional value.
sb.appendLine();// just a newlinesb.appendLine("hello");// newline + "hello"Positional {0}, {1} or named {key} placeholder interpolation. Supports format specifiers after a colon. Use {{...}} to escape braces.
| Specifier | Effect | Example |
|---|---|---|
:U | uppercase | {0:U} → "HELLO" |
:L | lowercase | {0:L} → "hello" |
:n | thousand separator | {0:n} → "1,234,567" |
sb.appendFormat("{0} + {1} = {2}",1,2,3);// positionalsb.appendFormat("Hello, {name}!",{name: "world"});// namedsb.appendFormat("{0:U} earned {1:n}","alice",95000);// with specifierssb.appendFormat("{{0}} is literal");// escaped → {0}Appends array elements joined by a separator. Default separator is "".
sb.appendJoin(["a","b","c"],", ");// "a, b, c"sb.appendJoin([1,2,3]," + ");// "1 + 2 + 3"Replaces the first occurrence of search (string or RegExp) in the buffer.
sb.replace("foo","bar");sb.replace(/\d+/,"0");Replaces all occurrences of search in the buffer. Automatically adds the g flag to RegExp if missing.
sb.replaceAll("foo","bar");sb.replaceAll(/\s+/,"-");Clears the internal buffer.
sb.clear();sb.toString();// ""Returns the accumulated string by joining all collected parts.
sb.append("a").append("b").append("c").toString();// "abc"Returns the total character count of the current buffer without calling toString().
newStringBuilder("hello").length;// 5Returns true if nothing has been appended yet or after clear().
newStringBuilder().isEmpty;// truenewStringBuilder("x").isEmpty;// falsenewStringBuilder("x").clear().isEmpty;// true (after clear)All methods except clear() return this:
constresult=newStringBuilder().prepend("START: ").append("hello world").replace("world","there").appendLine().appendJoin(["a","b","c"],", ").toString();MIT © 2014 Halil İbrahim ŞAFAK
