# String's CoW abstraction needs refinement

**URL:** <https://forum.modular.com/t/strings-cow-abstraction-needs-refinement/3524>\
**Category:** Standard Library\
**Created:** [September 23, 2026, 7:54am UTC](https://forum.modular.com/t/strings-cow-abstraction-needs-refinement/3524 "2026-09-23T07:54:38Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![leb-kuchen](https://avatars.discourse-cdn.com/v4/letter/l/a183cd/32.png) [@leb-kuchen](https://forum.modular.com/u/leb-kuchen)\
**Post date:** [September 23, 2026, 7:54am UTC](https://forum.modular.com/t/strings-cow-abstraction-needs-refinement/3524/1 "2026-09-23T07:54:38Z")

</div>

…It’s a great abstraction, but only works for String.

Right now, String behaves like Arc with implicit `Arc::make_mut` calls in Rust, except for small and constant optimizations.

Note that str is an unsized type here, not a reference, and thus there is no double indirection. So Arc in this aspect is basically a template type (`Arc<T: ?Sized>`). The `Sized` trait in Rust has been room for a lot of confusion, so I am not sure if this is path Mojo should pursue. However, it allows for these neat optimizations, which in Mojo require a hardcoded library type with poor interoperability.

So now, where are the problems with Mojo’s approach. First of all, String’s invariant requires the storage to be UTF-8, thus requiring `List[Byte]` as storage. This leads to different performance characteristics just for opting out of UTF-8, and an extra conversion step.  
Second, it requires Atomics for single threaded code, since there is no `Rc<str>` counterpart.

### Solution sketch

String’s `Cow` logic is moved to a separate `BytesStorage` type and exposed via `Bytes` or `ByteList`, and of course, `String`. `String` remains the predominant type with Atomics whereas other byte types expose single threaded options.
