diff --git a/mem/include/arena/mem_arena.h b/mem/include/arena/mem_arena.h
index 2ab423c..96c2366 100644
--- a/mem/include/arena/mem_arena.h
+++ b/mem/include/arena/mem_arena.h
@@ -4,4 +4,12 @@
 #include "aliases.h"
 #include <stdbool.h>
 
+typedef struct growing_arena Arena;
+
+bool mem_arena_init(Arena **arena, u64 base_capacity);
+void *mem_arena_alloc(Arena *arena, u64 size);
+void *mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment);
+void mem_arena_clear(Arena *arena);
+void mem_arena_free(Arena **arena);
+
 #endif // !MEM_ARENA_H
diff --git a/mem/src/arena/mem_arena.c b/mem/src/arena/mem_arena.c
index 411b71a..ae3ba04 100644
--- a/mem/src/arena/mem_arena.c
+++ b/mem/src/arena/mem_arena.c
@@ -18,13 +18,158 @@ struct base_arena {
   BaseArena *next;
 };
 
+struct growing_arena {
+  BaseArena *active_arena;
+  u64 count;
+  u64 initial_capacity;
+};
+
 internal bool base_arena_init(BaseArena *arena, u64 capacity);
-internal void *base_arena_alloc(BaseArena *arena, u64 size);
 internal void *base_arena_alloc_aligned(BaseArena *arena, u64 size,
                                         u64 alignment);
 internal void base_arena_clear(BaseArena *arena);
 internal void base_arena_free(BaseArena *arena);
 
+// PUBLIC API
+
+bool mem_arena_init(Arena **arena, u64 base_capacity) {
+  if (!arena || *arena) {
+    return false;
+  }
+
+  *arena = (Arena *)malloc(sizeof(Arena));
+  Arena *arena_ptr = *arena;
+  if (!arena_ptr) {
+    return false;
+  }
+
+  memset(arena_ptr, 0, sizeof(Arena));
+
+  arena_ptr->active_arena = (BaseArena *)malloc(sizeof(BaseArena));
+  if (!(arena_ptr->active_arena)) {
+    return false;
+  }
+
+  memset(arena_ptr->active_arena, 0, sizeof(BaseArena));
+
+  if (!base_arena_init(arena_ptr->active_arena, base_capacity)) {
+    return false;
+  }
+
+  arena_ptr->count = 1;
+  arena_ptr->initial_capacity = base_capacity;
+
+  return true;
+}
+
+void *mem_arena_alloc(Arena *arena, u64 size) {
+  return mem_arena_alloc_aligned(arena, size, DEFAULT_ALIGNMENT);
+}
+
+void *mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
+  if (!arena || !(arena->active_arena)) {
+    return NULL;
+  }
+
+  void *output = base_arena_alloc_aligned(arena->active_arena, size, alignment);
+  if (!output) {
+    if (arena->active_arena->next) {
+      arena->active_arena = arena->active_arena->next;
+    } else {
+      arena->active_arena->next = (BaseArena *)malloc(sizeof(BaseArena));
+      if (!(arena->active_arena->next)) {
+        return NULL;
+      }
+
+      memset(arena->active_arena->next, 0, sizeof(BaseArena));
+
+      if (!base_arena_init(arena->active_arena->next,
+                           arena->initial_capacity)) {
+        free(arena->active_arena->next);
+        return NULL;
+      }
+
+      arena->active_arena->next->prev = arena->active_arena;
+      arena->active_arena = arena->active_arena->next;
+
+      ++(arena->count);
+    }
+
+    output = base_arena_alloc_aligned(arena->active_arena, size, alignment);
+    if (!output) {
+      return NULL;
+    }
+  }
+
+  memset(output, 0, size);
+
+  return output;
+}
+
+void mem_arena_clear(Arena *arena) {
+  if (!arena) {
+    return;
+  }
+
+  BaseArena *new_active = NULL;
+  while (arena->active_arena) {
+    base_arena_clear(arena->active_arena);
+
+    arena->active_arena = arena->active_arena->prev;
+
+    if (arena->active_arena) {
+      new_active = arena->active_arena;
+    }
+  }
+
+  arena->active_arena = new_active;
+}
+
+void mem_arena_free(Arena **arena) {
+  if (!arena) {
+    return;
+  }
+
+  Arena *arena_ptr = *arena;
+
+  BaseArena *current;
+  BaseArena *next;
+  BaseArena *prev;
+
+  current = arena_ptr->active_arena->next;
+  while (current) {
+    next = current->next;
+
+    base_arena_free(current);
+    free(current);
+
+    current = next;
+  }
+
+  current = arena_ptr->active_arena->prev;
+  while (current) {
+    prev = current->prev;
+
+    base_arena_free(current);
+    free(current);
+
+    current = prev;
+  }
+
+  base_arena_free(arena_ptr->active_arena);
+
+  free(arena_ptr->active_arena);
+  arena_ptr->active_arena = NULL;
+
+  arena_ptr->count = 0;
+  arena_ptr->initial_capacity = 0;
+
+  free(*arena);
+  *arena = NULL;
+}
+
+// INTERNAL FUNCTIONS
+
 internal bool base_arena_init(BaseArena *arena, u64 capacity) {
   if (!arena || arena->buf) {
     return false;
@@ -45,10 +190,6 @@ internal bool base_arena_init(BaseArena *arena, u64 capacity) {
   return true;
 }
 
-internal void *base_arena_alloc(BaseArena *arena, u64 size) {
-  return base_arena_alloc_aligned(arena, size, DEFAULT_ALIGNMENT);
-}
-
 internal void *base_arena_alloc_aligned(BaseArena *arena, u64 size,
                                         u64 alignment) {
   if (!arena) {