NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #618 most downloaded on crates.io
A memory efficient string type that transparently stores strings on the stack, when possible
Last release 2 months ago
13 Jul 2026
Release timing varies
gaps range from 9 days to 1.2 years
Most releases are documented
notes for 16 of 19 stable releases
3 versions withdrawn
withdrawn after publishing
5 years old
23 releases · first in 2021
One column per quarter.
perf: route heap construction through a cold alloc_copy core (fixes x86 inline regression)
#488 built the heap variant via a helper that returned a full HeapBuffer. Returning
that 24-byte aggregate across the outlined call boundary forced its result through
the stack, which made LLVM route the whole constructor -- including the hot inline
arm -- through a stack temporary and scatter-copy it into the return slot on x86:
misaligned 1+8+4+2+1 loads overlapping the 16-byte build stores, a store-to-load
forwarding stall on every construction. This regressed inline creation on x86 (only
ever wall-clock benched on aarch64, where the reload stays clean).
Replace HeapBuffer::build with HeapBuffer::alloc_copy, the single #[cold]
#[inline(never)] allocate+copy core that returns the two-word (ptr, capacity) pair
(passed back in registers, not a stack aggregate). new and alloc_copy_panic become
#[inline(always)] wrappers that assemble the HeapBuffer from that pair at the
callsite. So every construction path -- new_panic and the fallible Repr::new behind
ToCompactString/From/number formatting -- keeps its clean 3x movq / ldp+ldr copy,
lays the heap arm out cold, and only (ptr, capacity) ever crosses the boundary.
Verified: lib tests pass; Miri clean across inline/full-24/multibyte/heap lengths
plus clone/drop under strict provenance.
The overlapping-copy ladder's stores straddle 8-byte word boundaries, so
whole-word reloads of a freshly built repr fail store-to-load forwarding
on x86 (a ~12-cycle stall per blocked load; inline creation measured a
flat ~10ns for every length except 24). Build the buffer's three words in
registers instead: overlapping loads from the source merged with shifts,
so the value can stay in registers entirely. Inline creation drops to
~1.35ns on Sapphire Rapids; aarch64 lowers to ldp/lsr/csel/stp with no
stack traffic. copy_small now only backs the fallback path, so gate it.
clone_heap was #[inline(never)] and returned the 24-byte Repr by value,
forcing an sret return that routed even the plain-copy inline arm through
a scatter-copied stack temporary on x86 -- the same shape fixed for
construction by alloc_copy. new_panic's heap arm already is that cold
out-of-line core, so call it directly. clone small -53%, clone large -32%
on Sapphire Rapids.
The #[cold] empty()/capacity_on_heap() helpers returned Result
through an sret slot, inviting the hot buffer-steal arm into a shared
stack temporary. Inline the empty case (it is one compare) and route the
over-16MB-on-32-bit case through the cold alloc_copy core.
Same protocol as alloc_copy: the out-of-line allocating core returns
(ptr, capacity) in registers and an #[inline(always)] wrapper packs the
HeapBuffer at the callsite, instead of returning the 24-byte buffer by
value across the cold call boundary.
const_new("") folds the empty string to a constant instead of running
the runtime constructor.
v1.71.Error trait impls once again require the std feature. This reverts the (unreleased)
no-std core::error::Error support from #443,
which required Rust v1.81, it can return once the MSRV reaches v1.81.garde validation crate under an
optional feature, implementing its string rule traits for CompactString.
feat: add garde validation support.schemars crate under an optional
feature, implementing JsonSchema for CompactString. Every method delegates to String's
impl, so the generated schema is identical to a String's.
feat: support schemars.valuable crate under an optional
feature, implementing the Valuable trait for CompactString so it presents as a Value::String.
Add impl Valuable.pyo3 feature which implements FromPyObject
and IntoPyObject for CompactString, so it can
be used seamlessly with pyo3 v0.29.
feat: add pyo3 feature.defmt crate under an optional feature,
implementing defmt::Format for CompactString.
feat: Add support for defmt.bevy-reflect feature which implements bevy_reflect's
reflection traits for CompactString (as an opaque type).
feat: Add bevy-reflect feature.utoipa feature which implements utoipa's
PartialSchema and ToSchema traits for CompactString.
fix sqlx type impl, add utoipa feature
and feat: fixup the utoipa feature.#[must_use] from the Drain iterator.
fix: remove #[must_use] from Drain.feat: add kani proof harnesses to verify unsafe code.sqlx dependency to v0.9. Enabling the sqlx
feature now requires Rust v1.94.
deps: bump sqlx to 0.9.bevy_reflect dependency to v0.19.
deps: update optional deps to latest.markup dependency to v0.16.
deps: update optional deps to latest.CompactString.
fix: possible undefined behavior with realloc in a HeapString.CompactString::retain to avoid briefly creating references to invalid UTF-8.
Avoid invalid UTF-8 references in retain.CompactString::as_mut_bytes exposing uninitialized spare capacity through a &mut [u8];
heap spare capacity is now zero-initialized before it's returned.
fix: avoid exposing uninitialized spare capacity.String's existing allocation in CompactString::new.
perf: reuse owned String in CompactString::new.ToCompactString for str.
perf: specialize ToCompactString for str.CompactString instead of &mut Repr.
perf: Drop passes heap fields by-value instead of &mut Repr.Result on the hot inline construction path with Repr::new_panic.
perf: add Repr::new_panic to skip Result on the hot inline path.Repr invariants so the compiler can fold dead error-handling branches on construction.
perf: speed up append, integer formatting, and inline creation.from_utf8_lossy instead of copying byte-by-byte.
perf: bulk-copy valid runs in from_utf8_lossy.memcpy. Keep heap construction out-of-line,
and move the OOM panic off the hot construction path to keep generated assembly lean.
perf: several small improvements.ryu dependency with zmij for float formatting.
deps: replace ryu with zmij for float formatting.Nothing published for this version
start, bump to v0.9.0 bump the version in Cargo.toml update the CHANGELOG update versions in examples
start, bump to v0.9.0
bump the version in Cargo.toml
update the CHANGELOG
update versions in examples
CompactString::new_inline(...) and CompactString::from_static_str(...).
CompactStringExt::join_compact and CompactStringExt::concat_compact to take a
reference (i.e. &C) to a type C: IntoIterator<Item = &str> instead of ownership of a type C
where &C: IntoIterator<Item = &str>.
issue#412 which made the
CompactStringExt more ergonomic.feat: tweak the CompactStringExt trait so join_compact and concat_compact work betterborsch feature in no_std environments.
fix: The borsch feature with no-std.zeroize::Zeroize trait for CompactString.
feat: Add support for zeroize::Zeroize.CompactString::retain method to not set length if the predicate panics.
fix: retain not set len if predicate panics.sqlx::postgres::PgHasArrayType for CompactString.
impl sqlx::postgres::PgHasArrayType.markup dependency to v0.15.
deps: upgrade to markup v0.8.rkyv dependency to v0.8.
deps: upgrade to rkyv v0.8.sqlx dependency to v0.8.
deps: upgrade to sqlx v0.8.Nothing published for this version
bump version to 0.8.1, update changelog
bump version to 0.8.1, update changelog
start, bump version to 0.8.0
start, bump version to 0.8.0 (#398)
CompactString::new_inline(...) and CompactString::from_static_str(...) into CompactString::const:new(...). Methods are currently marked as deprecated and will be removed in v0.9.0.
Add const_new(); remove new_inline() and from_static_str()v1.60
fix: MSRV check and change MSRV to 1.60borsh under an optional feature.
Add borsh supportPartialEq impls for CompactString
fix: More PartialEq implsInlineBuffer and Repr.
Align InlineBuffer same as Reprserde and no_std features.
fix serde no-std issueCompactString::is_empty.
Simplify is_empty()From impls that std::string::String has.
Add missing From impls that String hasClone::clone_from for CompactString.
Impl Clone::clone_from for CompactStringCompactString fallible.
Make (re)allocations fallible&'static strs
Inline short static stringsCompactString from diesel and sqlx
Implement diesel compatibilityImplement for sqlx... and everything from v0.8.0-beta
String in trait ToCompactString by upgrading to castaway v0.2.3
deps: Upgrade to castaway v0.2.3Re-enable specialization for String in trait ToCompactString, #304
String in trait ToCompactString, #304&'static str in a CompactString in O(1)
feat: Support O(1) CompactString::from_static_strno_std environments
support no_stdrepeat() API to CompactString
feat: Implement CompactString::repeatto_ascii_lowercase(), to_ascii_uppercase(), to_lowercase(), and to_uppercase() APIs to CompactString
feat: Implement case conversion fn for CompactStringfrom_str_to_lower(...) and from_str_to_upper(...) APIs to CompactString
feat: Impl CompactString::from_str_to_{lower, upper}caseCompactString::as_str() API
Remove branches from Repr::as_slice()CompactString::len() API
Simplify Repr::len()Clone implementation for CompactString
Simplify clone()Fix and optimize CapacityOpen up more nichesMSRV: Bump to 1.59 Improve the performance of the ToCompactString trait
ToCompactString trait
fix: Don't count bytes in ToCompactStringbranch start, bump version to v0.7
branch start, bump version to v0.7
-Zrandomize-layout rustc flag in CI
ci: Randomize Layout in CIas_ptr() to require only &self and not &mut self
refactor: Change CompactString::as_ptr to take &selfinto_bytes() method behind the smallvec feature which converts a CompactString into a byte vector using a SmallVec
api: Add CompactString::into_bytesfrom_string_buffer() method which always re-uses the underlying buffer from String
Clone-ing a CompactString
perf: Inline strings when Clone-ingFrom<String> and From<Box<str>> to eagerly inline strings
CompactString
Fix a typo in documentationAsRef<[u8]> for CompactString
impl AsRef<[u8]> for CompactStringperf: Refactor underlying buffers for branchless accessFrom<CompactString> for Cow<'_, str>
Implement From<CompactString> for Cow<'_, str>CompactString::new_inline
Copy inline string reversedFromIterator and Extend traits for CompactString
Implement more FromIterator & Extend traitsinto_string() method
Implement more FromIterator & Extend traitsEnable the std feature in proptest to fix documentation on docs.rs
std feature in proptest to fix documentation on docs.rs
Enable "proptest/std" featurebump version to 0.6, update CHANGELOG
bump version to 0.6, update CHANGELOG (#216)
from_utf16_lossy(), from_utf16be_lossy(), and from_utf16le_lossy()
feat: implement from_utf16_lossy APIImplement from_utf16ne_lossy and from_utf16be_lossyfrom_utf16be() and from_utf16le() methods
Implement from_utf16le, from_utf16be, from_utf16nerkyv::Archive, rkyv::Deserialize, and rkyv::Serialize for CompactString
Add rkyv serializationCompactString
Don't format char to determine it's UTF-8 lengthformat_compact! macro
Macro hygiene: use re-exported format_args!()CompactString is allocated on the heap
#160 perf: Implement realloc for BoxStringmarkup::Render trait
#157 Implement markup::Render trait and document featuresArbitrary trait from arbitrary, proptest, and quickcheck
146 feat: Implemented the Arbitrary trait from various crateFrom<CompactString> for String
#118 feat: add impl From<CompactString> for StringAddAssign (+=) for CompactString
add AddAssign operatorstd::String API Parity Milestonefrom_utf8_lossy() method
Implement from_utf8_lossy()from_utf8_unchecked() method
feat: from_utf8_unchecked()retain() method
Implement retain()remove() method
feat: Implement CompactString::remove()from_utf16() method
#170 feat: Implement CompactString::from_utf16split_off() method
#154 Implement split_off()drain() method
#153 Implement drain()clear() method
#149 Implement clear()insert() and insert_str() methods
#148 Implement insert() and insert_str()truncate() method
#132 Implement truncate()replace_range() method
#125 Implement replace_range()as_mut_str() method
#124 Add as_mut_str() methodFix error when creating CompactString with capacity 16711422 on 32-bit archiectures
CompactString with capacity 16711422 on 32-bit archiectures
#161 fix: Test case discovered by AFL#167 backport(v0.5): Test case discovered by AFLFix error when importing compact_str by change the existing Add<...> impls
compact_str by change the existing Add<...> impls
#103 fix/feat: Change the existing Add<...> implsRemove CompactStr type alias to prep for v0.5, as the deprecation message noted
CompactStringExt and ToCompactString traits, and format_compact!(...) macro
CompactStr type alias to prep for v0.5, as the deprecation message noted
#110 chore: Remove CompactStr type aliasCompactStringExt which provides methods to join and concatenate collections into a CompactString
#109 feat: CompactStringExt traitCompactString in such a way that size_of::<CompactString>() == size_of::<Option<CompactString>>()
#105 perf: Option<CompactString> same size as CompactString#75: smol option#22 draft: Optimize Option<CompactStr> to be the same size as CompactStrAsRef<OsStr> for CompactStr
#102 Impl AsRef<OsStr> for CompactStringformat_compact! macro
#101 Add macro_rules format_compact!Fix error when importing compact_str by change the existing Add<...> impls
compact_str by change the existing Add<...> impls
#103 fix/feat: Change the existing Add<...> implsRename CompactStr -> CompactString and ToCompactStr -> ToComapctString
CompactStr -> CompactString and ToCompactStr -> ToComapctString
#97 refactor: Rename CompactStr to CompactStringToCompactStr by reducing copies for some specialized types
#95 perf: Reduce copies in ToCompactStr for integer typesToCompactStr trait, with specialized impls for common types
#16 Add && Impl new trait ToCompactStrFrom<Cow<'_, str>>
#90 Optimize From<Cow<'a, str>> impl for CompactStrAdd<T> for CompactStr, enabling concatination with +
Implemented in #81 impl a bunch of Add<T>s for CompactStr, and Add<CompactStr> for StringDrop for inlined strings
fmt::Write for CompactStr
#73 Implement fmt::Write for CompactStrO(1) conversion from String and Box<str> it became possible for short strings to be heap allocated. Now if we need to resize a short heap string, we'll inline it, instead of re-heap allocating.
#70 perf: Inline short heap strings when resizingEnable O(1) conversion from String or Box to CompactStr
O(1) conversion from String or Box<str> to CompactStr
#65 perf: Move Capacity onto the StackCompactStr became mutable with v0.3.0Implemented in `#64 feature: impl Extend > for CompactStr`
Extend<Cow<str>> for CompactStr
#64 feature: impl Extend<Cow<'_, str>> for CompactStrFrom<Cow<str>> for CompactStr
#62 impl From<Cow<'_, str>> for CompactStrAdd CompactStr::from_utf8(...) API
CompactStr::from_utf8(...) API
#57 feature: Add from_utf8 API#56 feature: BoxString#49 refactor: Combine Inline and Packed VariantsComapctStr
#48 vendor: static-assertionsCompactStr
#46 chore: Add public documentation to CompactStrCompactStr::pop(...), CompactStr::push(...), and CompactStr::push_str(...) APIs
#45 feature: impl the Extend trait for CompactStrExtend trait for CompactStr
#45 feature: impl the Extend trait for CompactStrbytes feature to CompactStr, includes from_utf8_buf*(...) APIs
#40 feature: bytesCompactStr::as_mut_slice(...) API
#37 feature: as_mut_slice APICompactStr::reserve(...) API
#36 feature: reserve API#26, #32, 34, #35, #42, #56Change Minimum Supported Rust Version to 1.49
#24 Make Minimum Supported Rust Version 1.49FromIterator for CompactStr
#23 impl FromIterator<...> for CompactStrFixes `#18 Consider impl trait FromStr for CompactStr`
FromStr for CompactStr
#18 Consider impl trait FromStr for CompactStr#20 impl FromStr for CompactStr#3 Document minimal supported Rust Version#17 Upgrade to Edition 2021 and mac MSRV 1.56`#15` Add impl PartialEq for &str
PartialEq from more types
#[inline] and #[repr(C)] annotations
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →