Repository navigation
Version 3 aligns the fluent API with all 56 non-constructor functions in Go 1.27's strings package while keeping Go 1.24 as the minimum and adding no runtime dependencies.
Install
go get github.com/goforj/str/v3@v3.0.0import "github.com/goforj/str/v3"Breaking changes and migration
Changing the import path alone is not enough. Review the v2 to v3 migration guide for the complete behavior changes.
Trimming and joining
| v2 | v3 |
|---|---|
value.Trim() |
value.TrimSpace() |
value.TrimChars(chars) |
value.Trim(chars) |
value.TrimLeft() |
value.TrimLeftFunc(unicode.IsSpace) |
value.TrimRight() |
value.TrimRightFunc(unicode.IsSpace) |
value.Join(elements, sep) |
str.Join(elements, sep) |
Trim, TrimLeft, and TrimRight accept cutsets. An empty cutset leaves the input unchanged. TrimChars and the receiver method Join are removed.
Search indexes and empty matches
Index and LastIndex now return byte offsets. All standard index methods follow that rule; application helpers such as Slice, Take, and CharAt still use rune positions.
// v2: Index("llo") returned 2.
value := str.Of("héllo")
index := value.Index("llo")
fmt.Println(index)
// 3
fmt.Println(value.String()[index:])
// lloEmpty searches follow each standard function's contract. For example, Contains("") is true, Count("") on "abc" is 4, and ReplaceAll("", "-") produces "-a-b-c-".
Folded predicates also match empty searches. Empty-search replacement helpers insert at the corresponding boundaries. Replace, ReplaceAll, ReplaceFold, and each entry in ReplaceArray preserve UTF-8 sequence boundaries; Swap follows strings.Replacer byte boundaries, so an empty key can split a multibyte rune. Swap remains one-pass; ReplaceArray remains sequential.
Lines, casing, and repetition
Lines now returns iter.Seq[string], preserves newline bytes, and omits an extra empty element after a trailing newline.
// v2: Lines() returned ["a" "b" ""].
fmt.Printf("%q\n", slices.Collect(str.Of("a\r\nb\n").Lines()))
// ["a\r\n" "b\n"]Use NormalizeNewlines().Split("\n") for the old normalized slice behavior. Lines, SplitSeq, and SplitAfterSeq are single-use; FieldsSeq and FieldsFuncSeq restart on each iteration.
Title now preserves non-initial letters like strings.Title: "hELLO wORLD" becomes "HELLO WORLD", where v2 produced "Hello World". It carries the standard deprecation notice for Unicode word-boundary limitations. Repeat now panics for negative counts and overflow.
Additional standard operations
The API adds the Cut family, fields and split variants, predicate-based search and trimming, Replace(old, new, n), Map, Clone, ToValidUTF8, special-case conversion, and the remaining standard string functions. See the complete API contract.
The source string becomes the receiver, remaining arguments retain their order, and a single string result becomes str.String. Multiple results, slices, and iterators retain their standard types. Join is a package-level constructor. Stateful strings.Builder, strings.Reader, and strings.Replacer remain in the standard library.
CutLast is backported so it also works on Go 1.24. The docs and examples modules are development tooling; only the root runtime module is released. Existing v2 consumers can continue using the v2 module path.
Full changelog: v2.0.1 to v3.0.0.