diff --git a/src/libraries/Common/src/System/Collections/Generic/StackArrayBuilder.cs b/src/libraries/Common/src/System/Collections/Generic/StackArrayBuilder.cs
new file mode 100644
index 00000000000000..4c202b67641f8d
--- /dev/null
+++ b/src/libraries/Common/src/System/Collections/Generic/StackArrayBuilder.cs
@@ -0,0 +1,140 @@
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+namespace StackArrayBuilder;
+
+///
+/// Helper type for avoiding allocations while building arrays.
+///
+/// The element type.
+///
+/// Will grow heap allocated size, if you need it.
+/// Only use grow in rare cases, as it needs to grow the array, if over already allocated size.
+/// If you are certain of the max size needed, you can use e.g. StackArrayBuilder8
+///
+internal ref struct StackArrayBuilder
+{
+ private InlineArray16 _stackAllocatedBuffer = default;
+ public const int StackAllocatedCapacity = 16;
+ private const int DefaultHeapCapacity = 4;
+
+ private T[]? _heapArrayBuffer; // Starts out null, initialized if capacity is over stack allocated size when constructing or on Add.
+ private int _count; // Number of items added.
+
+ ///
+ /// Initializes the with a specified capacity.
+ ///
+ /// The capacity of the array to allocate.
+ public StackArrayBuilder(int capacity) : this()
+ {
+ Debug.Assert(capacity >= 0);
+ if (capacity > StackAllocatedCapacity)
+ {
+ _heapArrayBuffer = new T[capacity - StackAllocatedCapacity];
+ }
+ }
+
+ ///
+ /// Gets the number of items this instance can store without re-allocating.
+ /// StackAllocatedCapacity if the backing heap array is not needed, all up to that is already stack allocated
+ ///
+ /// Only for unit testing, checking that overallocation does not happen
+ public int Capacity => _heapArrayBuffer?.Length + StackAllocatedCapacity ?? StackAllocatedCapacity;
+
+ ///
+ /// Adds an item, resizing heap allocated array if necessary.
+ ///
+ /// The item to add.
+ public void Add(T item)
+ {
+ if (_count == Capacity)
+ {
+ EnsureCapacity(_count + 1);
+ }
+
+ UncheckedAdd(item);
+ }
+
+ ///
+ /// Creates an array from the contents of this builder.
+ ///
+ public T[] ToArray()
+ {
+ if (_count == 0)
+ {
+ return [];
+ }
+
+ T[] result = new T[_count];
+ int index = 0;
+ foreach (T stackAllocatedValue in _stackAllocatedBuffer)
+ {
+ result[index++] = stackAllocatedValue;
+ if (index >= _count)
+ {
+ return result;
+ }
+ }
+
+ _heapArrayBuffer.AsSpan(0, _count - StackAllocatedCapacity).CopyTo(result.AsSpan(start: StackAllocatedCapacity));
+
+ return result;
+ }
+
+ ///
+ /// Adds an item, without checking if there is room.
+ ///
+ /// The item to add.
+ ///
+ /// Use this method if you know there is enough space in the
+ /// for another item, and you are writing performance-sensitive code.
+ ///
+ public void UncheckedAdd(T item)
+ {
+ Debug.Assert(_count < Capacity);
+ if (_count < StackAllocatedCapacity)
+ {
+ _stackAllocatedBuffer[_count++] = item;
+ }
+ else
+ {
+ _heapArrayBuffer![_count++ - StackAllocatedCapacity] = item;
+ }
+ }
+
+ private void EnsureCapacity(int minimum)
+ {
+ Debug.Assert(minimum > Capacity);
+
+ if (minimum < StackAllocatedCapacity)
+ {
+ return; // There is still room on the stack
+ }
+
+ if (_heapArrayBuffer == null)
+ {
+ // Initial capacity has not been not set or too low, we will allocate the default heap array size
+ _heapArrayBuffer = new T[DefaultHeapCapacity];
+ return;
+ }
+
+ // Check if allocated heap capacity was enough
+ int defaultCapacityWithHeap = _heapArrayBuffer.Length + StackAllocatedCapacity;
+ if (defaultCapacityWithHeap >= minimum)
+ {
+ return; // current allocated stack+heap is large enough
+ }
+
+ // We need to allocate more heap capacity, by increasing the size of the array
+ int nextHeapCapacity = 2 * _heapArrayBuffer.Length;
+
+ if ((uint)nextHeapCapacity > (uint)Array.MaxLength)
+ {
+ nextHeapCapacity = Math.Max(_heapArrayBuffer.Length + 1, Array.MaxLength);
+ }
+
+ nextHeapCapacity = Math.Max(nextHeapCapacity, minimum);
+
+ Array.Resize(ref _heapArrayBuffer, nextHeapCapacity);
+ }
+}
diff --git a/src/libraries/Common/src/System/Collections/Generic/StackArrayBuilder8.cs b/src/libraries/Common/src/System/Collections/Generic/StackArrayBuilder8.cs
new file mode 100644
index 00000000000000..c17429e9f0f0b5
--- /dev/null
+++ b/src/libraries/Common/src/System/Collections/Generic/StackArrayBuilder8.cs
@@ -0,0 +1,55 @@
+using System.Runtime.CompilerServices;
+
+namespace StackArrayBuilder;
+
+///
+/// Helper type for avoiding allocations while building arrays.
+///
+/// The element type.
+///
+/// Throws InvalidOperationException, if the right size is not selected.
+/// Be sure to select the right size to not over- or under-allocate expected size on stack.
+///
+internal ref struct StackArrayBuilder8
+{
+ private InlineArray8 _stackAllocatedBuffer = default;
+ public const int StackAllocatedCapacity = 8;
+
+ private int _count = 0; // Number of items added.
+
+ public StackArrayBuilder8()
+ {
+ }
+
+ /// Adds an item
+ /// The item to add.
+ public void Add(T item)
+ {
+ if (_count == StackAllocatedCapacity)
+ {
+ throw new InvalidOperationException("Stack allocated capacity exceeded");
+ }
+ _stackAllocatedBuffer[_count++] = item;
+ }
+
+ /// Creates an array from the contents of this builder.
+ public T[] ToArray()
+ {
+ if (_count == 0)
+ {
+ return [];
+ }
+
+ T[] result = new T[_count];
+ int index = 0;
+ foreach (T stackAllocatedValue in _stackAllocatedBuffer)
+ {
+ result[index++] = stackAllocatedValue;
+ if (index >= _count)
+ {
+ return result;
+ }
+ }
+ return result;
+ }
+}
diff --git a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj
index ad692fafc90f2c..481c719722f9f0 100644
--- a/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj
+++ b/src/libraries/System.Diagnostics.Process/src/System.Diagnostics.Process.csproj
@@ -47,6 +47,10 @@
Link="Common\System\Text\ValueStringBuilder.cs" />
+
+