diff --git a/clay.h b/clay.h
index 18a4396..2c82aa6 100644
--- a/clay.h
+++ b/clay.h
@@ -182,8 +182,13 @@ CLAY__TYPEDEF(Clay__StringArray, struct {
     Clay_String *internalArray;
 });
 
+typedef struct Clay_Context Clay_Context;
+
 CLAY__TYPEDEF(Clay_Arena, struct {
     uintptr_t nextAllocation;
+    Clay_Context* context;
+    int32_t maxElementCount;
+    int32_t maxMeasureTextCacheWordCount;
     size_t capacity;
     char *memory;
 });
@@ -489,7 +494,9 @@ CLAY__TYPEDEF(Clay_ErrorHandler, struct {
 uint32_t Clay_MinMemorySize(void);
 Clay_Arena Clay_CreateArenaWithCapacityAndMemory(uint32_t capacity, void *offset);
 void Clay_SetPointerState(Clay_Vector2 position, bool pointerDown);
-void Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler);
+Clay_Context* Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler);
+Clay_Context* Clay_GetCurrentContext(void);
+void Clay_SetCurrentContext(Clay_Context* context);
 void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime);
 void Clay_SetLayoutDimensions(Clay_Dimensions dimensions);
 void Clay_BeginLayout(void);
@@ -543,6 +550,381 @@ extern uint32_t Clay__debugViewWidth;
 #ifdef CLAY_IMPLEMENTATION
 #undef CLAY_IMPLEMENTATION
 
+thread_local Clay_Context *Clay__currentContext;
+thread_local int32_t Clay__nextInitMaxElementCount = 8192;
+thread_local int32_t Clay__nextInitMaxMeasureTextCacheWordCount = 8192;
+
+CLAY__TYPEDEF(Clay_BooleanWarnings, struct {
+    bool maxElementsExceeded;
+    bool maxRenderCommandsExceeded;
+    bool maxTextMeasureCacheExceeded;
+});
+
+CLAY__TYPEDEF(Clay__Warning, struct {
+    Clay_String baseMessage;
+    Clay_String dynamicMessage;
+});
+
+CLAY__TYPEDEF(Clay__WarningArray, struct {
+    int32_t capacity;
+    int32_t length;
+    Clay__Warning *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__BoolArray, struct
+{
+	int32_t capacity;
+	int32_t length;
+	bool *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__ElementIdArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_ElementId *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__ElementConfigArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_ElementConfig *internalArray;
+});
+CLAY__TYPEDEF(Clay__ElementConfigArraySlice, struct
+{
+    int32_t length;
+    Clay_ElementConfig *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__LayoutConfigArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_LayoutConfig *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__RectangleElementConfigArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_RectangleElementConfig *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__TextElementConfigArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_TextElementConfig *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__ImageElementConfigArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_ImageElementConfig *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__FloatingElementConfigArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_FloatingElementConfig *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__CustomElementConfigArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_CustomElementConfig *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__ScrollElementConfigArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_ScrollElementConfig *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__StringArraySlice, struct
+{
+    int32_t length;
+    Clay_String *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__WrappedTextLine, struct {
+    Clay_Dimensions dimensions;
+    Clay_String line;
+});
+
+CLAY__TYPEDEF(Clay__WrappedTextLineArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay__WrappedTextLine *internalArray;
+});
+CLAY__TYPEDEF(Clay__WrappedTextLineArraySlice, struct
+{
+    int32_t length;
+    Clay__WrappedTextLine *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__TextElementData, struct {
+    Clay_String text;
+    Clay_Dimensions preferredDimensions;
+    int32_t elementIndex;
+    Clay__WrappedTextLineArraySlice wrappedLines;
+});
+
+CLAY__TYPEDEF(Clay__TextElementDataArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay__TextElementData *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__BorderElementConfigArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_BorderElementConfig *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__LayoutElementChildren, struct {
+    int32_t *elements;
+    uint16_t length;
+});
+
+CLAY__TYPEDEF(Clay_LayoutElement, struct {
+    union {
+        Clay__LayoutElementChildren children;
+        Clay__TextElementData *textElementData;
+    } childrenOrTextContent;
+    Clay_Dimensions dimensions;
+    Clay_Dimensions minDimensions;
+    Clay_LayoutConfig *layoutConfig;
+    Clay__ElementConfigArraySlice elementConfigs;
+    uint32_t configsEnabled;
+    uint32_t id;
+});
+
+CLAY__TYPEDEF(Clay_LayoutElementArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_LayoutElement *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__LayoutElementPointerArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_LayoutElement* *internalArray;
+});
+
+
+CLAY__TYPEDEF(Clay__ScrollContainerDataInternal, struct {
+    Clay_LayoutElement *layoutElement;
+    Clay_BoundingBox boundingBox;
+    Clay_Dimensions contentSize;
+    Clay_Vector2 scrollOrigin;
+    Clay_Vector2 pointerOrigin;
+    Clay_Vector2 scrollMomentum;
+    Clay_Vector2 scrollPosition;
+    Clay_Vector2 previousDelta;
+    float momentumTime;
+    uint32_t elementId;
+    bool openThisFrame;
+    bool pointerScrollActive;
+});
+
+CLAY__TYPEDEF(Clay__ScrollContainerDataInternalArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay__ScrollContainerDataInternal *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__DebugElementData, struct {
+    bool collision;
+    bool collapsed;
+});
+
+CLAY__TYPEDEF(Clay__DebugElementDataArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay__DebugElementData *internalArray;
+});
+
+CLAY__TYPEDEF(Clay_LayoutElementHashMapItem, struct { // todo get this struct into a single cache line
+    Clay_BoundingBox boundingBox;
+    Clay_ElementId elementId;
+    Clay_LayoutElement* layoutElement;
+    void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerInfo, intptr_t userData);
+    intptr_t hoverFunctionUserData;
+    int32_t nextIndex;
+    uint32_t generation;
+    Clay__DebugElementData *debugData;
+});
+
+CLAY__TYPEDEF(Clay__LayoutElementHashMapItemArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay_LayoutElementHashMapItem *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__MeasuredWord, struct {
+    int32_t startOffset;
+    int32_t length;
+    float width;
+    int32_t next;
+});
+
+CLAY__TYPEDEF(Clay__MeasuredWordArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay__MeasuredWord *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__MeasureTextCacheItem, struct {
+    Clay_Dimensions unwrappedDimensions;
+    int32_t measuredWordsStartIndex;
+    // Hash map data
+    uint32_t id;
+    int32_t nextIndex;
+    uint32_t generation;
+});
+
+CLAY__TYPEDEF(Clay__MeasureTextCacheItemArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay__MeasureTextCacheItem *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__int32_tArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    int32_t *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__LayoutElementTreeNode, struct {
+    Clay_LayoutElement *layoutElement;
+    Clay_Vector2 position;
+    Clay_Vector2 nextChildOffset;
+});
+
+CLAY__TYPEDEF(Clay__LayoutElementTreeNodeArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay__LayoutElementTreeNode *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__LayoutElementTreeRoot, struct {
+    int32_t layoutElementIndex;
+    uint32_t parentId; // This can be zero in the case of the root layout tree
+    uint32_t clipElementId; // This can be zero if there is no clip element
+    int32_t zIndex;
+    Clay_Vector2 pointerOffset; // Only used when scroll containers are managed externally
+});
+
+CLAY__TYPEDEF(Clay__LayoutElementTreeRootArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    Clay__LayoutElementTreeRoot *internalArray;
+});
+
+CLAY__TYPEDEF(Clay__CharArray, struct
+{
+    int32_t capacity;
+    int32_t length;
+    uint8_t *internalArray;
+});
+
+void Clay__ErrorHandlerFunctionDefault(Clay_ErrorData errorText) {
+    (void) errorText;
+}
+
+struct Clay_Context {
+    bool warningsEnabled = true;
+    Clay_ErrorHandler errorHandler = { .errorHandlerFunction = Clay__ErrorHandlerFunctionDefault };
+    Clay_BooleanWarnings booleanWarnings;
+    Clay__WarningArray warnings = CLAY__DEFAULT_STRUCT;
+
+    Clay_PointerData pointerInfo = { .position = {-1, -1} };
+    Clay_Dimensions layoutDimensions = CLAY__DEFAULT_STRUCT;
+    Clay_ElementId dynamicElementIndexBaseHash = { .id = 128476991, .stringId = { .length = 8, .chars = "Auto ID" } };
+    uint32_t dynamicElementIndex = 0;
+    bool debugModeEnabled = false;
+    bool disableCulling = false;
+    bool externalScrollHandlingEnabled = false;
+    uint32_t debugSelectedElementId = 0;
+    uint32_t generation = 0;
+    uint64_t arenaResetOffset = 0;
+    Clay_Arena internalArena;
+    // Layout Elements / Render Commands
+    Clay_LayoutElementArray layoutElements;
+    Clay_RenderCommandArray renderCommands;
+    Clay__int32_tArray openLayoutElementStack;
+    Clay__int32_tArray layoutElementChildren;
+    Clay__int32_tArray layoutElementChildrenBuffer;
+    Clay__TextElementDataArray textElementData;
+    Clay__LayoutElementPointerArray imageElementPointers;
+    Clay__int32_tArray reusableElementIndexBuffer;
+    Clay__int32_tArray layoutElementClipElementIds;
+    // Configs
+    Clay__LayoutConfigArray layoutConfigs;
+    Clay__ElementConfigArray elementConfigBuffer;
+    Clay__ElementConfigArray elementConfigs;
+    Clay__RectangleElementConfigArray rectangleElementConfigs;
+    Clay__TextElementConfigArray textElementConfigs;
+    Clay__ImageElementConfigArray imageElementConfigs;
+    Clay__FloatingElementConfigArray floatingElementConfigs;
+    Clay__ScrollElementConfigArray scrollElementConfigs;
+    Clay__CustomElementConfigArray customElementConfigs;
+    Clay__BorderElementConfigArray borderElementConfigs;
+    // Misc Data Structures
+    Clay__StringArray layoutElementIdStrings;
+    Clay__WrappedTextLineArray wrappedTextLines;
+    Clay__LayoutElementTreeNodeArray layoutElementTreeNodeArray1;
+    Clay__LayoutElementTreeRootArray layoutElementTreeRoots;
+    Clay__LayoutElementHashMapItemArray layoutElementsHashMapInternal;
+    Clay__int32_tArray layoutElementsHashMap;
+    Clay__MeasureTextCacheItemArray measureTextHashMapInternal;
+    Clay__int32_tArray measureTextHashMapInternalFreeList;
+    Clay__int32_tArray measureTextHashMap;
+    Clay__MeasuredWordArray measuredWords;
+    Clay__int32_tArray measuredWordsFreeList;
+    Clay__int32_tArray openClipElementStack;
+    Clay__ElementIdArray pointerOverIds;
+    Clay__ScrollContainerDataInternalArray scrollContainerDatas;
+    Clay__BoolArray treeNodeVisited;
+    Clay__CharArray dynamicStringData;
+    Clay__DebugElementDataArray debugElementData;
+};
+CLAY__TYPEDEF(Clay_Context, struct Clay_Context);
+
+Clay_Context* Clay__Context_Allocate_Arena(Clay_Arena *arena) {
+    uint32_t alignment = CLAY__ALIGNMENT(Clay_Context);
+    size_t totalSizeBytes = sizeof(Clay_Context);
+    uintptr_t nextAllocAddress = arena->nextAllocation + (uintptr_t)arena->memory;
+    uintptr_t arenaOffsetAligned = nextAllocAddress + (alignment - (nextAllocAddress & alignment));
+    arenaOffsetAligned -= (uintptr_t)arena->memory;
+    if (arenaOffsetAligned + totalSizeBytes > arena->capacity)
+    {
+        return NULL;
+    }
+    arena->nextAllocation = arenaOffsetAligned + totalSizeBytes;
+    arena->context = (Clay_Context*)((uintptr_t)arena->memory + arenaOffsetAligned);
+    return arena->context;
+}
+
 #ifndef CLAY__NULL
 #define CLAY__NULL 0
 #endif
@@ -551,38 +933,12 @@ extern uint32_t Clay__debugViewWidth;
 #define CLAY__MAXFLOAT 3.40282346638528859812e+38F
 #endif
 
-bool Clay__warningsEnabled = true;
-int32_t Clay__maxElementCount = 8192;
-int32_t Clay__maxMeasureTextCacheWordCount = 16384;
-void Clay__ErrorHandlerFunctionDefault(Clay_ErrorData errorText) {
-    (void) errorText;
-}
-Clay_ErrorHandler Clay__errorHandler = { .errorHandlerFunction = Clay__ErrorHandlerFunctionDefault };
-
 Clay_String CLAY__SPACECHAR = { .length = 1, .chars = " " };
 Clay_String CLAY__STRING_DEFAULT = { .length = 0, .chars = NULL };
 
-CLAY__TYPEDEF(Clay_BooleanWarnings, struct {
-    bool maxElementsExceeded;
-    bool maxRenderCommandsExceeded;
-    bool maxTextMeasureCacheExceeded;
-});
-
-Clay_BooleanWarnings Clay__booleanWarnings;
-
-CLAY__TYPEDEF(Clay__Warning, struct {
-    Clay_String baseMessage;
-    Clay_String dynamicMessage;
-});
-
 Clay__Warning CLAY__WARNING_DEFAULT = CLAY__DEFAULT_STRUCT;
 
 #pragma region generated
-CLAY__TYPEDEF(Clay__WarningArray, struct {
-    int32_t capacity;
-    int32_t length;
-    Clay__Warning *internalArray;
-});
 
 Clay__WarningArray Clay__WarningArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     size_t totalSizeBytes = capacity * sizeof(Clay_String);
@@ -595,16 +951,14 @@ Clay__WarningArray Clay__WarningArray_Allocate_Arena(int32_t capacity, Clay_Aren
         arena->nextAllocation = arenaOffsetAligned + totalSizeBytes;
     }
     else {
-        Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
+        arena->context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
             .errorType = CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED,
             .errorText = CLAY_STRING("Clay attempted to allocate memory in its arena, but ran out of capacity. Try increasing the capacity of the arena passed to Clay_Initialize()"),
-            .userData = Clay__errorHandler.userData });
+            .userData = arena->context->errorHandler.userData });
     }
     return array;
 }
 
-Clay__WarningArray Clay_warnings = CLAY__DEFAULT_STRUCT;
-
 Clay__Warning *Clay__WarningArray_Add(Clay__WarningArray *array, Clay__Warning item)
 {
     if (array->length < array->capacity) {
@@ -625,10 +979,10 @@ void* Clay__Array_Allocate_Arena(int32_t capacity, uint32_t itemSize, uint32_t a
         return (void*)((uintptr_t)arena->memory + (uintptr_t)arenaOffsetAligned);
     }
     else {
-        Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
+        arena->context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
                 .errorType = CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED,
                 .errorText = CLAY_STRING("Clay attempted to allocate memory in its arena, but ran out of capacity. Try increasing the capacity of the arena passed to Clay_Initialize()"),
-                .userData = Clay__errorHandler.userData });
+                .userData = arena->context->errorHandler.userData });
     }
     return CLAY__NULL;
 }
@@ -638,10 +992,11 @@ bool Clay__Array_RangeCheck(int32_t index, int32_t length)
     if (index < length && index >= 0) {
         return true;
     }
-    Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
+    Clay_Context* context = Clay_GetCurrentContext();
+    context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
             .errorType = CLAY_ERROR_TYPE_INTERNAL_ERROR,
             .errorText = CLAY_STRING("Clay attempted to make an out of bounds array access. This is an internal error and is likely a bug."),
-            .userData = Clay__errorHandler.userData });
+            .userData = context->errorHandler.userData });
     return false;
 }
 
@@ -650,10 +1005,11 @@ bool Clay__Array_AddCapacityCheck(int32_t length, int32_t capacity)
     if (length < capacity) {
         return true;
     }
-    Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
+    Clay_Context* context = Clay_GetCurrentContext();
+    context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
         .errorType = CLAY_ERROR_TYPE_INTERNAL_ERROR,
         .errorText = CLAY_STRING("Clay attempted to make an out of bounds array access. This is an internal error and is likely a bug."),
-        .userData = Clay__errorHandler.userData });
+        .userData = context->errorHandler.userData });
     return false;
 }
 
@@ -661,12 +1017,6 @@ bool CLAY__BOOL_DEFAULT = false;
 
 // __GENERATED__ template array_define,array_allocate TYPE=bool NAME=Clay__BoolArray
 #pragma region generated
-CLAY__TYPEDEF(Clay__BoolArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	bool *internalArray;
-});
 Clay__BoolArray Clay__BoolArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__BoolArray){.capacity = capacity, .length = 0, .internalArray = (bool *)Clay__Array_Allocate_Arena(capacity, sizeof(bool), CLAY__ALIGNMENT(bool), arena)};
 }
@@ -677,12 +1027,6 @@ Clay_ElementId CLAY__ELEMENT_ID_DEFAULT = CLAY__DEFAULT_STRUCT;
 
 // __GENERATED__ template array_define,array_allocate,array_get,array_add TYPE=Clay_ElementId NAME=Clay__ElementIdArray DEFAULT_VALUE=&CLAY__ELEMENT_ID_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__ElementIdArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_ElementId *internalArray;
-});
 Clay__ElementIdArray Clay__ElementIdArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__ElementIdArray){.capacity = capacity, .length = 0, .internalArray = (Clay_ElementId *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_ElementId), CLAY__ALIGNMENT(Clay_ElementId), arena)};
 }
@@ -703,17 +1047,6 @@ Clay_ElementConfig CLAY__ELEMENT_CONFIG_DEFAULT = {CLAY__ELEMENT_CONFIG_TYPE_NON
 
 // __GENERATED__ template array_define,array_define_slice,array_allocate,array_get,array_add,array_get_slice TYPE=Clay_ElementConfig NAME=Clay__ElementConfigArray DEFAULT_VALUE=&CLAY__ELEMENT_CONFIG_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__ElementConfigArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_ElementConfig *internalArray;
-});
-CLAY__TYPEDEF(Clay__ElementConfigArraySlice, struct
-{
-	int32_t length;
-	Clay_ElementConfig *internalArray;
-});
 Clay__ElementConfigArray Clay__ElementConfigArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__ElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_ElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_ElementConfig), CLAY__ALIGNMENT(Clay_ElementConfig), arena)};
 }
@@ -737,12 +1070,6 @@ Clay_LayoutConfig CLAY_LAYOUT_DEFAULT = { .sizing = { .width = { .size = { .minM
 
 // __GENERATED__ template array_define,array_allocate,array_add TYPE=Clay_LayoutConfig NAME=Clay__LayoutConfigArray DEFAULT_VALUE=&CLAY_LAYOUT_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__LayoutConfigArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_LayoutConfig *internalArray;
-});
 Clay__LayoutConfigArray Clay__LayoutConfigArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__LayoutConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_LayoutConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_LayoutConfig), CLAY__ALIGNMENT(Clay_LayoutConfig), arena)};
 }
@@ -760,12 +1087,6 @@ Clay_RectangleElementConfig CLAY__RECTANGLE_ELEMENT_CONFIG_DEFAULT = CLAY__DEFAU
 
 // __GENERATED__ template array_define,array_allocate,array_add TYPE=Clay_RectangleElementConfig NAME=Clay__RectangleElementConfigArray DEFAULT_VALUE=&CLAY__RECTANGLE_ELEMENT_CONFIG_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__RectangleElementConfigArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_RectangleElementConfig *internalArray;
-});
 Clay__RectangleElementConfigArray Clay__RectangleElementConfigArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__RectangleElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_RectangleElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_RectangleElementConfig), CLAY__ALIGNMENT(Clay_RectangleElementConfig), arena)};
 }
@@ -783,12 +1104,6 @@ Clay_TextElementConfig CLAY__TEXT_ELEMENT_CONFIG_DEFAULT = CLAY__DEFAULT_STRUCT;
 
 // __GENERATED__ template array_define,array_allocate,array_add TYPE=Clay_TextElementConfig NAME=Clay__TextElementConfigArray DEFAULT_VALUE=&CLAY__TEXT_ELEMENT_CONFIG_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__TextElementConfigArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_TextElementConfig *internalArray;
-});
 Clay__TextElementConfigArray Clay__TextElementConfigArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__TextElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_TextElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_TextElementConfig), CLAY__ALIGNMENT(Clay_TextElementConfig), arena)};
 }
@@ -806,12 +1121,6 @@ Clay_ImageElementConfig CLAY__IMAGE_ELEMENT_CONFIG_DEFAULT = CLAY__DEFAULT_STRUC
 
 // __GENERATED__ template array_define,array_allocate,array_add TYPE=Clay_ImageElementConfig NAME=Clay__ImageElementConfigArray DEFAULT_VALUE=&CLAY__IMAGE_ELEMENT_CONFIG_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__ImageElementConfigArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_ImageElementConfig *internalArray;
-});
 Clay__ImageElementConfigArray Clay__ImageElementConfigArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__ImageElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_ImageElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_ImageElementConfig), CLAY__ALIGNMENT(Clay_ImageElementConfig), arena)};
 }
@@ -829,12 +1138,6 @@ Clay_FloatingElementConfig CLAY__FLOATING_ELEMENT_CONFIG_DEFAULT = CLAY__DEFAULT
 
 // __GENERATED__ template array_define,array_allocate,array_add TYPE=Clay_FloatingElementConfig NAME=Clay__FloatingElementConfigArray DEFAULT_VALUE=&CLAY__FLOATING_ELEMENT_CONFIG_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__FloatingElementConfigArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_FloatingElementConfig *internalArray;
-});
 Clay__FloatingElementConfigArray Clay__FloatingElementConfigArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__FloatingElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_FloatingElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_FloatingElementConfig), CLAY__ALIGNMENT(Clay_FloatingElementConfig), arena)};
 }
@@ -852,12 +1155,6 @@ Clay_CustomElementConfig CLAY__CUSTOM_ELEMENT_CONFIG_DEFAULT = CLAY__DEFAULT_STR
 
 // __GENERATED__ template array_define,array_allocate,array_add TYPE=Clay_CustomElementConfig NAME=Clay__CustomElementConfigArray DEFAULT_VALUE=&CLAY__CUSTOM_ELEMENT_CONFIG_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__CustomElementConfigArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_CustomElementConfig *internalArray;
-});
 Clay__CustomElementConfigArray Clay__CustomElementConfigArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__CustomElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_CustomElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_CustomElementConfig), CLAY__ALIGNMENT(Clay_CustomElementConfig), arena)};
 }
@@ -875,12 +1172,6 @@ Clay_ScrollElementConfig CLAY__SCROLL_ELEMENT_CONFIG_DEFAULT = CLAY__DEFAULT_STR
 
 // __GENERATED__ template array_define,array_allocate,array_add TYPE=Clay_ScrollElementConfig NAME=Clay__ScrollElementConfigArray DEFAULT_VALUE=&CLAY__SCROLL_ELEMENT_CONFIG_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__ScrollElementConfigArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_ScrollElementConfig *internalArray;
-});
 Clay__ScrollElementConfigArray Clay__ScrollElementConfigArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__ScrollElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_ScrollElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_ScrollElementConfig), CLAY__ALIGNMENT(Clay_ScrollElementConfig), arena)};
 }
@@ -896,11 +1187,6 @@ Clay_ScrollElementConfig *Clay__ScrollElementConfigArray_Add(Clay__ScrollElement
 
 // __GENERATED__ template array_define_slice,array_allocate,array_add TYPE=Clay_String NAME=Clay__StringArray DEFAULT_VALUE=&CLAY__STRING_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__StringArraySlice, struct
-{
-	int32_t length;
-	Clay_String *internalArray;
-});
 Clay__StringArray Clay__StringArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__StringArray){.capacity = capacity, .length = 0, .internalArray = (Clay_String *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_String), CLAY__ALIGNMENT(Clay_String), arena)};
 }
@@ -914,26 +1200,10 @@ Clay_String *Clay__StringArray_Add(Clay__StringArray *array, Clay_String item) {
 #pragma endregion
 // __GENERATED__ template
 
-CLAY__TYPEDEF(Clay__WrappedTextLine, struct {
-    Clay_Dimensions dimensions;
-    Clay_String line;
-});
-
 Clay__WrappedTextLine CLAY__WRAPPED_TEXT_LINE_DEFAULT = CLAY__DEFAULT_STRUCT;
 
 // __GENERATED__ template array_define,array_define_slice,array_allocate,array_add,array_get TYPE=Clay__WrappedTextLine NAME=Clay__WrappedTextLineArray DEFAULT_VALUE=&CLAY__WRAPPED_TEXT_LINE_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__WrappedTextLineArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay__WrappedTextLine *internalArray;
-});
-CLAY__TYPEDEF(Clay__WrappedTextLineArraySlice, struct
-{
-	int32_t length;
-	Clay__WrappedTextLine *internalArray;
-});
 Clay__WrappedTextLineArray Clay__WrappedTextLineArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__WrappedTextLineArray){.capacity = capacity, .length = 0, .internalArray = (Clay__WrappedTextLine *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__WrappedTextLine), CLAY__ALIGNMENT(Clay__WrappedTextLine), arena)};
 }
@@ -950,23 +1220,10 @@ Clay__WrappedTextLine *Clay__WrappedTextLineArray_Get(Clay__WrappedTextLineArray
 #pragma endregion
 // __GENERATED__ template
 
-CLAY__TYPEDEF(Clay__TextElementData, struct {
-    Clay_String text;
-    Clay_Dimensions preferredDimensions;
-    int32_t elementIndex;
-    Clay__WrappedTextLineArraySlice wrappedLines;
-});
-
 Clay__TextElementData CLAY__TEXT_ELEMENT_DATA_DEFAULT = CLAY__DEFAULT_STRUCT;
 
 // __GENERATED__ template array_define,array_allocate,array_get,array_add TYPE=Clay__TextElementData NAME=Clay__TextElementDataArray DEFAULT_VALUE=&CLAY__TEXT_ELEMENT_DATA_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__TextElementDataArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay__TextElementData *internalArray;
-});
 Clay__TextElementDataArray Clay__TextElementDataArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__TextElementDataArray){.capacity = capacity, .length = 0, .internalArray = (Clay__TextElementData *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__TextElementData), CLAY__ALIGNMENT(Clay__TextElementData), arena)};
 }
@@ -987,12 +1244,6 @@ Clay_BorderElementConfig CLAY__BORDER_ELEMENT_CONFIG_DEFAULT = CLAY__DEFAULT_STR
 
 // __GENERATED__ template array_define,array_allocate,array_add TYPE=Clay_BorderElementConfig NAME=Clay__BorderElementConfigArray DEFAULT_VALUE=&CLAY__BORDER_ELEMENT_CONFIG_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__BorderElementConfigArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_BorderElementConfig *internalArray;
-});
 Clay__BorderElementConfigArray Clay__BorderElementConfigArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__BorderElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_BorderElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_BorderElementConfig), CLAY__ALIGNMENT(Clay_BorderElementConfig), arena)};
 }
@@ -1006,34 +1257,10 @@ Clay_BorderElementConfig *Clay__BorderElementConfigArray_Add(Clay__BorderElement
 #pragma endregion
 // __GENERATED__ template
 
-CLAY__TYPEDEF(Clay__LayoutElementChildren, struct {
-    int32_t *elements;
-    uint16_t length;
-});
-
-CLAY__TYPEDEF(Clay_LayoutElement, struct {
-    union {
-        Clay__LayoutElementChildren children;
-        Clay__TextElementData *textElementData;
-    } childrenOrTextContent;
-    Clay_Dimensions dimensions;
-    Clay_Dimensions minDimensions;
-    Clay_LayoutConfig *layoutConfig;
-    Clay__ElementConfigArraySlice elementConfigs;
-    uint32_t configsEnabled;
-    uint32_t id;
-});
-
 Clay_LayoutElement CLAY__LAYOUT_ELEMENT_DEFAULT = CLAY__DEFAULT_STRUCT;
 
 // __GENERATED__ template array_define,array_allocate,array_add,array_get TYPE=Clay_LayoutElement NAME=Clay_LayoutElementArray DEFAULT_VALUE=&CLAY__LAYOUT_ELEMENT_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay_LayoutElementArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_LayoutElement *internalArray;
-});
 Clay_LayoutElementArray Clay_LayoutElementArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay_LayoutElementArray){.capacity = capacity, .length = 0, .internalArray = (Clay_LayoutElement *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_LayoutElement), CLAY__ALIGNMENT(Clay_LayoutElement), arena)};
 }
@@ -1052,12 +1279,6 @@ Clay_LayoutElement *Clay_LayoutElementArray_Get(Clay_LayoutElementArray *array,
 
 // __GENERATED__ template array_define,array_allocate_pointer,array_add,array_get_value,array_remove_swapback TYPE=Clay_LayoutElement* NAME=Clay__LayoutElementPointerArray DEFAULT_VALUE=CLAY__NULL
 #pragma region generated
-CLAY__TYPEDEF(Clay__LayoutElementPointerArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_LayoutElement* *internalArray;
-});
 Clay__LayoutElementPointerArray Clay__LayoutElementPointerArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__LayoutElementPointerArray){.capacity = capacity, .length = 0, .internalArray = (Clay_LayoutElement* *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_LayoutElement*), CLAY__POINTER_ALIGNMENT, arena)};
 }
@@ -1103,31 +1324,10 @@ Clay_RenderCommand *Clay_RenderCommandArray_Get(Clay_RenderCommandArray *array,
 #pragma endregion
 // __GENERATED__ template
 
-CLAY__TYPEDEF(Clay__ScrollContainerDataInternal, struct {
-    Clay_LayoutElement *layoutElement;
-    Clay_BoundingBox boundingBox;
-    Clay_Dimensions contentSize;
-    Clay_Vector2 scrollOrigin;
-    Clay_Vector2 pointerOrigin;
-    Clay_Vector2 scrollMomentum;
-    Clay_Vector2 scrollPosition;
-    Clay_Vector2 previousDelta;
-    float momentumTime;
-    uint32_t elementId;
-    bool openThisFrame;
-    bool pointerScrollActive;
-});
-
 Clay__ScrollContainerDataInternal CLAY__SCROLL_CONTAINER_DEFAULT = CLAY__DEFAULT_STRUCT;
 
 // __GENERATED__ template array_define,array_allocate,array_add,array_get TYPE=Clay__ScrollContainerDataInternal NAME=Clay__ScrollContainerDataInternalArray DEFAULT_VALUE=&CLAY__SCROLL_CONTAINER_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__ScrollContainerDataInternalArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay__ScrollContainerDataInternal *internalArray;
-});
 Clay__ScrollContainerDataInternalArray Clay__ScrollContainerDataInternalArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__ScrollContainerDataInternalArray){.capacity = capacity, .length = 0, .internalArray = (Clay__ScrollContainerDataInternal *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__ScrollContainerDataInternal), CLAY__ALIGNMENT(Clay__ScrollContainerDataInternal), arena)};
 }
@@ -1158,21 +1358,10 @@ Clay__ScrollContainerDataInternal Clay__ScrollContainerDataInternalArray_RemoveS
 #pragma endregion
 // __GENERATED__ template
 
-CLAY__TYPEDEF(Clay__DebugElementData, struct {
-    bool collision;
-    bool collapsed;
-});
-
 Clay__DebugElementData CLAY__DEBUG_ELEMENT_DATA_DEFAULT = CLAY__DEFAULT_STRUCT;
 
 // __GENERATED__ template array_define,array_allocate,array_add,array_get TYPE=Clay__DebugElementData NAME=Clay__DebugElementDataArray DEFAULT_VALUE=&CLAY__DEBUG_ELEMENT_DATA_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__DebugElementDataArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay__DebugElementData *internalArray;
-});
 Clay__DebugElementDataArray Clay__DebugElementDataArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__DebugElementDataArray){.capacity = capacity, .length = 0, .internalArray = (Clay__DebugElementData *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__DebugElementData), CLAY__ALIGNMENT(Clay__DebugElementData), arena)};
 }
@@ -1189,27 +1378,10 @@ Clay__DebugElementData *Clay__DebugElementDataArray_Get(Clay__DebugElementDataAr
 #pragma endregion
 // __GENERATED__ template
 
-CLAY__TYPEDEF(Clay_LayoutElementHashMapItem, struct { // todo get this struct into a single cache line
-    Clay_BoundingBox boundingBox;
-    Clay_ElementId elementId;
-    Clay_LayoutElement* layoutElement;
-    void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerInfo, intptr_t userData);
-    intptr_t hoverFunctionUserData;
-    int32_t nextIndex;
-    uint32_t generation;
-    Clay__DebugElementData *debugData;
-});
-
 Clay_LayoutElementHashMapItem CLAY__LAYOUT_ELEMENT_HASH_MAP_ITEM_DEFAULT = { .layoutElement = &CLAY__LAYOUT_ELEMENT_DEFAULT };
 
 // __GENERATED__ template array_define,array_allocate,array_get,array_add TYPE=Clay_LayoutElementHashMapItem NAME=Clay__LayoutElementHashMapItemArray DEFAULT_VALUE=&CLAY__LAYOUT_ELEMENT_HASH_MAP_ITEM_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__LayoutElementHashMapItemArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay_LayoutElementHashMapItem *internalArray;
-});
 Clay__LayoutElementHashMapItemArray Clay__LayoutElementHashMapItemArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__LayoutElementHashMapItemArray){.capacity = capacity, .length = 0, .internalArray = (Clay_LayoutElementHashMapItem *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_LayoutElementHashMapItem), CLAY__ALIGNMENT(Clay_LayoutElementHashMapItem), arena)};
 }
@@ -1226,23 +1398,10 @@ Clay_LayoutElementHashMapItem *Clay__LayoutElementHashMapItemArray_Add(Clay__Lay
 #pragma endregion
 // __GENERATED__ template
 
-CLAY__TYPEDEF(Clay__MeasuredWord, struct {
-    int32_t startOffset;
-    int32_t length;
-    float width;
-    int32_t next;
-});
-
 Clay__MeasuredWord CLAY__MEASURED_WORD_DEFAULT = { .next = -1 };
 
 // __GENERATED__ template array_define,array_allocate,array_get,array_set,array_add TYPE=Clay__MeasuredWord NAME=Clay__MeasuredWordArray DEFAULT_VALUE=&CLAY__MEASURED_WORD_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__MeasuredWordArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay__MeasuredWord *internalArray;
-});
 Clay__MeasuredWordArray Clay__MeasuredWordArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__MeasuredWordArray){.capacity = capacity, .length = 0, .internalArray = (Clay__MeasuredWord *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__MeasuredWord), CLAY__ALIGNMENT(Clay__MeasuredWord), arena)};
 }
@@ -1265,25 +1424,10 @@ Clay__MeasuredWord *Clay__MeasuredWordArray_Add(Clay__MeasuredWordArray *array,
 #pragma endregion
 // __GENERATED__ template
 
-CLAY__TYPEDEF(Clay__MeasureTextCacheItem, struct {
-    Clay_Dimensions unwrappedDimensions;
-    int32_t measuredWordsStartIndex;
-    // Hash map data
-    uint32_t id;
-    int32_t nextIndex;
-    uint32_t generation;
-});
-
 Clay__MeasureTextCacheItem CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT = { .measuredWordsStartIndex = -1 };
 
 // __GENERATED__ template array_define,array_allocate,array_get,array_add,array_set TYPE=Clay__MeasureTextCacheItem NAME=Clay__MeasureTextCacheItemArray DEFAULT_VALUE=&CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__MeasureTextCacheItemArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay__MeasureTextCacheItem *internalArray;
-});
 Clay__MeasureTextCacheItemArray Clay__MeasureTextCacheItemArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__MeasureTextCacheItemArray){.capacity = capacity, .length = 0, .internalArray = (Clay__MeasureTextCacheItem *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__MeasureTextCacheItem), CLAY__ALIGNMENT(Clay__MeasureTextCacheItem), arena)};
 }
@@ -1308,12 +1452,6 @@ void Clay__MeasureTextCacheItemArray_Set(Clay__MeasureTextCacheItemArray *array,
 
 // __GENERATED__ template array_define,array_allocate,array_get_value,array_add_value,array_set,array_remove_swapback TYPE=int32_t NAME=Clay__int32_tArray DEFAULT_VALUE=-1
 #pragma region generated
-CLAY__TYPEDEF(Clay__int32_tArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	int32_t *internalArray;
-});
 Clay__int32_tArray Clay__int32_tArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__int32_tArray){.capacity = capacity, .length = 0, .internalArray = (int32_t *)Clay__Array_Allocate_Arena(capacity, sizeof(int32_t), CLAY__ALIGNMENT(int32_t), arena)};
 }
@@ -1343,22 +1481,10 @@ int32_t Clay__int32_tArray_RemoveSwapback(Clay__int32_tArray *array, int32_t ind
 #pragma endregion
 // __GENERATED__ template
 
-CLAY__TYPEDEF(Clay__LayoutElementTreeNode, struct {
-    Clay_LayoutElement *layoutElement;
-    Clay_Vector2 position;
-    Clay_Vector2 nextChildOffset;
-});
-
 Clay__LayoutElementTreeNode CLAY__LAYOUT_ELEMENT_TREE_NODE_DEFAULT = CLAY__DEFAULT_STRUCT;
 
 // __GENERATED__ template array_define,array_allocate,array_add,array_get TYPE=Clay__LayoutElementTreeNode NAME=Clay__LayoutElementTreeNodeArray DEFAULT_VALUE=&CLAY__LAYOUT_ELEMENT_TREE_NODE_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__LayoutElementTreeNodeArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay__LayoutElementTreeNode *internalArray;
-});
 Clay__LayoutElementTreeNodeArray Clay__LayoutElementTreeNodeArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__LayoutElementTreeNodeArray){.capacity = capacity, .length = 0, .internalArray = (Clay__LayoutElementTreeNode *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__LayoutElementTreeNode), CLAY__ALIGNMENT(Clay__LayoutElementTreeNode), arena)};
 }
@@ -1375,24 +1501,10 @@ Clay__LayoutElementTreeNode *Clay__LayoutElementTreeNodeArray_Get(Clay__LayoutEl
 #pragma endregion
 // __GENERATED__ template
 
-CLAY__TYPEDEF(Clay__LayoutElementTreeRoot, struct {
-    int32_t layoutElementIndex;
-    uint32_t parentId; // This can be zero in the case of the root layout tree
-    uint32_t clipElementId; // This can be zero if there is no clip element
-    int32_t zIndex;
-    Clay_Vector2 pointerOffset; // Only used when scroll containers are managed externally
-});
-
 Clay__LayoutElementTreeRoot CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT = CLAY__DEFAULT_STRUCT;
 
 // __GENERATED__ template array_define,array_allocate,array_add,array_get TYPE=Clay__LayoutElementTreeRoot NAME=Clay__LayoutElementTreeRootArray DEFAULT_VALUE=&CLAY__LAYOUT_ELEMENT_TREE_ROOT_DEFAULT
 #pragma region generated
-CLAY__TYPEDEF(Clay__LayoutElementTreeRootArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	Clay__LayoutElementTreeRoot *internalArray;
-});
 Clay__LayoutElementTreeRootArray Clay__LayoutElementTreeRootArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__LayoutElementTreeRootArray){.capacity = capacity, .length = 0, .internalArray = (Clay__LayoutElementTreeRoot *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__LayoutElementTreeRoot), CLAY__ALIGNMENT(Clay__LayoutElementTreeRoot), arena)};
 }
@@ -1411,12 +1523,6 @@ Clay__LayoutElementTreeRoot *Clay__LayoutElementTreeRootArray_Get(Clay__LayoutEl
 
 // __GENERATED__ template array_define,array_allocate TYPE=uint8_t NAME=Clay__CharArray DEFAULT_VALUE=0
 #pragma region generated
-CLAY__TYPEDEF(Clay__CharArray, struct
-{
-	int32_t capacity;
-	int32_t length;
-	uint8_t *internalArray;
-});
 Clay__CharArray Clay__CharArray_Allocate_Arena(int32_t capacity, Clay_Arena *arena) {
     return CLAY__INIT(Clay__CharArray){.capacity = capacity, .length = 0, .internalArray = (uint8_t *)Clay__Array_Allocate_Arena(capacity, sizeof(uint8_t), CLAY__ALIGNMENT(uint8_t), arena)};
 }
@@ -1431,60 +1537,6 @@ Clay_String Clay__WriteStringToCharBuffer(Clay__CharArray *buffer, Clay_String s
     return CLAY__INIT(Clay_String) { .length = string.length, .chars = (const char *)(buffer->internalArray + buffer->length - string.length) };
 }
 
-// Global Variable Definitions ----------------------------------------------
-Clay_PointerData Clay__pointerInfo = { .position = {-1, -1} };
-Clay_Dimensions Clay__layoutDimensions = CLAY__DEFAULT_STRUCT;
-Clay_ElementId Clay__dynamicElementIndexBaseHash = { .id = 128476991, .stringId = { .length = 8, .chars = "Auto ID" } };
-uint32_t Clay__dynamicElementIndex = 0;
-bool Clay__debugModeEnabled = false;
-bool Clay__disableCulling = false;
-bool Clay__externalScrollHandlingEnabled = false;
-uint32_t Clay__debugSelectedElementId = 0;
-uint32_t Clay__debugViewWidth = 400;
-Clay_Color Clay__debugViewHighlightColor = { 168, 66, 28, 100 };
-uint32_t Clay__generation = 0;
-uint64_t Clay__arenaResetOffset = 0;
-Clay_Arena Clay__internalArena;
-// Layout Elements / Render Commands
-Clay_LayoutElementArray Clay__layoutElements;
-Clay_RenderCommandArray Clay__renderCommands;
-Clay__int32_tArray Clay__openLayoutElementStack;
-Clay__int32_tArray Clay__layoutElementChildren;
-Clay__int32_tArray Clay__layoutElementChildrenBuffer;
-Clay__TextElementDataArray Clay__textElementData;
-Clay__LayoutElementPointerArray Clay__imageElementPointers;
-Clay__int32_tArray Clay__reusableElementIndexBuffer;
-Clay__int32_tArray Clay__layoutElementClipElementIds;
-// Configs
-Clay__LayoutConfigArray Clay__layoutConfigs;
-Clay__ElementConfigArray Clay__elementConfigBuffer;
-Clay__ElementConfigArray Clay__elementConfigs;
-Clay__RectangleElementConfigArray Clay__rectangleElementConfigs;
-Clay__TextElementConfigArray Clay__textElementConfigs;
-Clay__ImageElementConfigArray Clay__imageElementConfigs;
-Clay__FloatingElementConfigArray Clay__floatingElementConfigs;
-Clay__ScrollElementConfigArray Clay__scrollElementConfigs;
-Clay__CustomElementConfigArray Clay__customElementConfigs;
-Clay__BorderElementConfigArray Clay__borderElementConfigs;
-// Misc Data Structures
-Clay__StringArray Clay__layoutElementIdStrings;
-Clay__WrappedTextLineArray Clay__wrappedTextLines;
-Clay__LayoutElementTreeNodeArray Clay__layoutElementTreeNodeArray1;
-Clay__LayoutElementTreeRootArray Clay__layoutElementTreeRoots;
-Clay__LayoutElementHashMapItemArray Clay__layoutElementsHashMapInternal;
-Clay__int32_tArray Clay__layoutElementsHashMap;
-Clay__MeasureTextCacheItemArray Clay__measureTextHashMapInternal;
-Clay__int32_tArray Clay__measureTextHashMapInternalFreeList;
-Clay__int32_tArray Clay__measureTextHashMap;
-Clay__MeasuredWordArray Clay__measuredWords;
-Clay__int32_tArray Clay__measuredWordsFreeList;
-Clay__int32_tArray Clay__openClipElementStack;
-Clay__ElementIdArray Clay__pointerOverIds;
-Clay__ScrollContainerDataInternalArray Clay__scrollContainerDatas;
-Clay__BoolArray Clay__treeNodeVisited;
-Clay__CharArray Clay__dynamicStringData;
-Clay__DebugElementDataArray Clay__debugElementData;
-
 #ifdef CLAY_WASM
     __attribute__((import_module("clay"), import_name("measureTextFunction"))) Clay_Dimensions Clay__MeasureText(Clay_String *text, Clay_TextElementConfig *config);
     __attribute__((import_module("clay"), import_name("queryScrollOffsetFunction"))) Clay_Vector2 Clay__QueryScrollOffset(uint32_t elementId);
@@ -1493,12 +1545,13 @@ Clay__DebugElementDataArray Clay__debugElementData;
     Clay_Vector2 (*Clay__QueryScrollOffset)(uint32_t elementId);
 #endif
 
-Clay_LayoutElement* Clay__GetOpenLayoutElement(void) {
-    return Clay_LayoutElementArray_Get(&Clay__layoutElements, Clay__int32_tArray_Get(&Clay__openLayoutElementStack, Clay__openLayoutElementStack.length - 1));
+Clay_LayoutElement* Clay__GetOpenLayoutElement() {
+    Clay_Context* context = Clay_GetCurrentContext();
+    return Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&context->openLayoutElementStack, context->openLayoutElementStack.length - 1));
 }
 
-uint32_t Clay__GetParentElementId(void) {
-    return Clay_LayoutElementArray_Get(&Clay__layoutElements, Clay__int32_tArray_Get(&Clay__openLayoutElementStack, Clay__openLayoutElementStack.length - 2))->id;
+uint32_t Clay__GetParentElementId(Clay_Context *context) {
+    return Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&context->openLayoutElementStack, context->openLayoutElementStack.length - 2))->id;
 }
 
 bool Clay__ElementHasConfig(Clay_LayoutElement *element, Clay__ElementConfigType type) {
@@ -1612,55 +1665,57 @@ uint32_t Clay__HashTextWithConfig(Clay_String *text, Clay_TextElementConfig *con
 }
 
 Clay__MeasuredWord *Clay__AddMeasuredWord(Clay__MeasuredWord word, Clay__MeasuredWord *previousWord) {
-    if (Clay__measuredWordsFreeList.length > 0) {
-        uint32_t newItemIndex = Clay__int32_tArray_Get(&Clay__measuredWordsFreeList, (int)Clay__measuredWordsFreeList.length - 1);
-        Clay__measuredWordsFreeList.length--;
-        Clay__MeasuredWordArray_Set(&Clay__measuredWords, (int)newItemIndex, word);
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->measuredWordsFreeList.length > 0) {
+        uint32_t newItemIndex = Clay__int32_tArray_Get(&context->measuredWordsFreeList, (int)context->measuredWordsFreeList.length - 1);
+        context->measuredWordsFreeList.length--;
+        Clay__MeasuredWordArray_Set(&context->measuredWords, (int)newItemIndex, word);
         previousWord->next = (int32_t)newItemIndex;
-        return Clay__MeasuredWordArray_Get(&Clay__measuredWords, (int)newItemIndex);
+        return Clay__MeasuredWordArray_Get(&context->measuredWords, (int)newItemIndex);
     } else {
-        previousWord->next = (int32_t)Clay__measuredWords.length;
-        return Clay__MeasuredWordArray_Add(&Clay__measuredWords, word);
+        previousWord->next = (int32_t)context->measuredWords.length;
+        return Clay__MeasuredWordArray_Add(&context->measuredWords, word);
     }
 }
 
 Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_TextElementConfig *config) {
+    Clay_Context* context = Clay_GetCurrentContext();
     #ifndef CLAY_WASM
     if (!Clay__MeasureText) {
-        Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
+        context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
             .errorType = CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED,
             .errorText = CLAY_STRING("Clay's internal MeasureText function is null. You may have forgotten to call Clay_SetMeasureTextFunction(), or passed a NULL function pointer by mistake."),
-            .userData = Clay__errorHandler.userData });
+            .userData = context->errorHandler.userData });
         return NULL;
     }
     #endif
     uint32_t id = Clay__HashTextWithConfig(text, config);
-    uint32_t hashBucket = id % (Clay__maxMeasureTextCacheWordCount / 32);
+    uint32_t hashBucket = id % (context->internalArena.maxMeasureTextCacheWordCount / 32);
     int32_t elementIndexPrevious = 0;
-    int32_t elementIndex = Clay__measureTextHashMap.internalArray[hashBucket];
+    int32_t elementIndex = context->measureTextHashMap.internalArray[hashBucket];
     while (elementIndex != 0) {
-        Clay__MeasureTextCacheItem *hashEntry = Clay__MeasureTextCacheItemArray_Get(&Clay__measureTextHashMapInternal, elementIndex);
+        Clay__MeasureTextCacheItem *hashEntry = Clay__MeasureTextCacheItemArray_Get(&context->measureTextHashMapInternal, elementIndex);
         if (hashEntry->id == id) {
-            hashEntry->generation = Clay__generation;
+            hashEntry->generation = context->generation;
             return hashEntry;
         }
         // This element hasn't been seen in a few frames, delete the hash map item
-        if (Clay__generation - hashEntry->generation > 2) {
+        if (context->generation - hashEntry->generation > 2) {
             // Add all the measured words that were included in this measurement to the freelist
             int32_t nextWordIndex = hashEntry->measuredWordsStartIndex;
             while (nextWordIndex != -1) {
-                Clay__MeasuredWord *measuredWord = Clay__MeasuredWordArray_Get(&Clay__measuredWords, nextWordIndex);
-                Clay__int32_tArray_Add(&Clay__measuredWordsFreeList, nextWordIndex);
+                Clay__MeasuredWord *measuredWord = Clay__MeasuredWordArray_Get(&context->measuredWords, nextWordIndex);
+                Clay__int32_tArray_Add(&context->measuredWordsFreeList, nextWordIndex);
                 nextWordIndex = measuredWord->next;
             }
 
             int32_t nextIndex = hashEntry->nextIndex;
-            Clay__MeasureTextCacheItemArray_Set(&Clay__measureTextHashMapInternal, elementIndex, CLAY__INIT(Clay__MeasureTextCacheItem) { .measuredWordsStartIndex = -1 });
-            Clay__int32_tArray_Add(&Clay__measureTextHashMapInternalFreeList, elementIndex);
+            Clay__MeasureTextCacheItemArray_Set(&context->measureTextHashMapInternal, elementIndex, CLAY__INIT(Clay__MeasureTextCacheItem) { .measuredWordsStartIndex = -1 });
+            Clay__int32_tArray_Add(&context->measureTextHashMapInternalFreeList, elementIndex);
             if (elementIndexPrevious == 0) {
-                Clay__measureTextHashMap.internalArray[hashBucket] = nextIndex;
+                context->measureTextHashMap.internalArray[hashBucket] = nextIndex;
             } else {
-                Clay__MeasureTextCacheItem *previousHashEntry = Clay__MeasureTextCacheItemArray_Get(&Clay__measureTextHashMapInternal, elementIndexPrevious);
+                Clay__MeasureTextCacheItem *previousHashEntry = Clay__MeasureTextCacheItemArray_Get(&context->measureTextHashMapInternal, elementIndexPrevious);
                 previousHashEntry->nextIndex = nextIndex;
             }
             elementIndex = nextIndex;
@@ -1671,26 +1726,26 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
     }
 
     int32_t newItemIndex = 0;
-    Clay__MeasureTextCacheItem newCacheItem = { .measuredWordsStartIndex = -1, .id = id, .generation = Clay__generation };
+    Clay__MeasureTextCacheItem newCacheItem = { .measuredWordsStartIndex = -1, .id = id, .generation = context->generation };
     Clay__MeasureTextCacheItem *measured = NULL;
-    if (Clay__measureTextHashMapInternalFreeList.length > 0) {
-        newItemIndex = Clay__int32_tArray_Get(&Clay__measureTextHashMapInternalFreeList, Clay__measureTextHashMapInternalFreeList.length - 1);
-        Clay__measureTextHashMapInternalFreeList.length--;
-        Clay__MeasureTextCacheItemArray_Set(&Clay__measureTextHashMapInternal, newItemIndex, newCacheItem);
-        measured = Clay__MeasureTextCacheItemArray_Get(&Clay__measureTextHashMapInternal, newItemIndex);
+    if (context->measureTextHashMapInternalFreeList.length > 0) {
+        newItemIndex = Clay__int32_tArray_Get(&context->measureTextHashMapInternalFreeList, context->measureTextHashMapInternalFreeList.length - 1);
+        context->measureTextHashMapInternalFreeList.length--;
+        Clay__MeasureTextCacheItemArray_Set(&context->measureTextHashMapInternal, newItemIndex, newCacheItem);
+        measured = Clay__MeasureTextCacheItemArray_Get(&context->measureTextHashMapInternal, newItemIndex);
     } else {
-        if (Clay__measureTextHashMapInternal.length == Clay__measureTextHashMapInternal.capacity - 1) {
-            if (Clay__booleanWarnings.maxTextMeasureCacheExceeded) {
-                Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
+        if (context->measureTextHashMapInternal.length == context->measureTextHashMapInternal.capacity - 1) {
+            if (context->booleanWarnings.maxTextMeasureCacheExceeded) {
+                context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
                         .errorType = CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED,
                         .errorText = CLAY_STRING("Clay ran out of capacity while attempting to measure text elements. Try using Clay_SetMaxElementCount() with a higher value."),
-                        .userData = Clay__errorHandler.userData });
-                Clay__booleanWarnings.maxTextMeasureCacheExceeded = true;
+                        .userData = context->errorHandler.userData });
+                context->booleanWarnings.maxTextMeasureCacheExceeded = true;
             }
             return &CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT;
         }
-        measured = Clay__MeasureTextCacheItemArray_Add(&Clay__measureTextHashMapInternal, newCacheItem);
-        newItemIndex = Clay__measureTextHashMapInternal.length - 1;
+        measured = Clay__MeasureTextCacheItemArray_Add(&context->measureTextHashMapInternal, newCacheItem);
+        newItemIndex = context->measureTextHashMapInternal.length - 1;
     }
 
     int32_t start = 0;
@@ -1701,13 +1756,13 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
     Clay__MeasuredWord tempWord = { .next = -1 };
     Clay__MeasuredWord *previousWord = &tempWord;
     while (end < text->length) {
-        if (Clay__measuredWords.length == Clay__measuredWords.capacity - 1) {
-            if (!Clay__booleanWarnings.maxTextMeasureCacheExceeded) {
-                Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
+        if (context->measuredWords.length == context->measuredWords.capacity - 1) {
+            if (!context->booleanWarnings.maxTextMeasureCacheExceeded) {
+                context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
                     .errorType = CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED,
                     .errorText = CLAY_STRING("Clay has run out of space in it's internal text measurement cache. Try using Clay_SetMaxMeasureTextCacheWordCount() (default 16384, with 1 unit storing 1 measured word)."),
-                    .userData = Clay__errorHandler.userData });
-                Clay__booleanWarnings.maxTextMeasureCacheExceeded = true;
+                    .userData = context->errorHandler.userData });
+                context->booleanWarnings.maxTextMeasureCacheExceeded = true;
             }
             return &CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT;
         }
@@ -1744,9 +1799,9 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
     measured->unwrappedDimensions.height = measuredHeight;
 
     if (elementIndexPrevious != 0) {
-        Clay__MeasureTextCacheItemArray_Get(&Clay__measureTextHashMapInternal, elementIndexPrevious)->nextIndex = newItemIndex;
+        Clay__MeasureTextCacheItemArray_Get(&context->measureTextHashMapInternal, elementIndexPrevious)->nextIndex = newItemIndex;
     } else {
-        Clay__measureTextHashMap.internalArray[hashBucket] = newItemIndex;
+        context->measureTextHashMap.internalArray[hashBucket] = newItemIndex;
     }
     return measured;
 }
@@ -1756,27 +1811,28 @@ bool Clay__PointIsInsideRect(Clay_Vector2 point, Clay_BoundingBox rect) {
 }
 
 Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Clay_LayoutElement* layoutElement) {
-    if (Clay__layoutElementsHashMapInternal.length == Clay__layoutElementsHashMapInternal.capacity - 1) {
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->layoutElementsHashMapInternal.length == context->layoutElementsHashMapInternal.capacity - 1) {
         return NULL;
     }
-    Clay_LayoutElementHashMapItem item = { .elementId = elementId, .layoutElement = layoutElement, .nextIndex = -1, .generation = Clay__generation + 1 };
-    uint32_t hashBucket = elementId.id % Clay__layoutElementsHashMap.capacity;
+    Clay_LayoutElementHashMapItem item = { .elementId = elementId, .layoutElement = layoutElement, .nextIndex = -1, .generation = context->generation + 1 };
+    uint32_t hashBucket = elementId.id % context->layoutElementsHashMap.capacity;
     int32_t hashItemPrevious = -1;
-    int32_t hashItemIndex = Clay__layoutElementsHashMap.internalArray[hashBucket];
+    int32_t hashItemIndex = context->layoutElementsHashMap.internalArray[hashBucket];
     while (hashItemIndex != -1) { // Just replace collision, not a big deal - leave it up to the end user
-        Clay_LayoutElementHashMapItem *hashItem = Clay__LayoutElementHashMapItemArray_Get(&Clay__layoutElementsHashMapInternal, hashItemIndex);
+        Clay_LayoutElementHashMapItem *hashItem = Clay__LayoutElementHashMapItemArray_Get(&context->layoutElementsHashMapInternal, hashItemIndex);
         if (hashItem->elementId.id == elementId.id) { // Collision - resolve based on generation
             item.nextIndex = hashItem->nextIndex;
-            if (hashItem->generation <= Clay__generation) { // First collision - assume this is the "same" element
-                hashItem->generation = Clay__generation + 1;
+            if (hashItem->generation <= context->generation) { // First collision - assume this is the "same" element
+                hashItem->generation = context->generation + 1;
                 hashItem->layoutElement = layoutElement;
                 hashItem->debugData->collision = false;
             } else { // Multiple collisions this frame - two elements have the same ID
-                Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
+                context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
                     .errorType = CLAY_ERROR_TYPE_DUPLICATE_ID,
                     .errorText = CLAY_STRING("An element with this ID was already previously declared during this layout."),
-                    .userData = Clay__errorHandler.userData });
-                if (Clay__debugModeEnabled) {
+                    .userData = context->errorHandler.userData });
+                if (context->debugModeEnabled) {
                     hashItem->debugData->collision = true;
                 }
             }
@@ -1785,21 +1841,22 @@ Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Cl
         hashItemPrevious = hashItemIndex;
         hashItemIndex = hashItem->nextIndex;
     }
-    Clay_LayoutElementHashMapItem *hashItem = Clay__LayoutElementHashMapItemArray_Add(&Clay__layoutElementsHashMapInternal, item);
-    hashItem->debugData = Clay__DebugElementDataArray_Add(&Clay__debugElementData, CLAY__INIT(Clay__DebugElementData) CLAY__DEFAULT_STRUCT);
+    Clay_LayoutElementHashMapItem *hashItem = Clay__LayoutElementHashMapItemArray_Add(&context->layoutElementsHashMapInternal, item);
+    hashItem->debugData = Clay__DebugElementDataArray_Add(&context->debugElementData, CLAY__INIT(Clay__DebugElementData) CLAY__DEFAULT_STRUCT);
     if (hashItemPrevious != -1) {
-        Clay__LayoutElementHashMapItemArray_Get(&Clay__layoutElementsHashMapInternal, hashItemPrevious)->nextIndex = (int32_t)Clay__layoutElementsHashMapInternal.length - 1;
+        Clay__LayoutElementHashMapItemArray_Get(&context->layoutElementsHashMapInternal, hashItemPrevious)->nextIndex = (int32_t)context->layoutElementsHashMapInternal.length - 1;
     } else {
-        Clay__layoutElementsHashMap.internalArray[hashBucket] = (int32_t)Clay__layoutElementsHashMapInternal.length - 1;
+        context->layoutElementsHashMap.internalArray[hashBucket] = (int32_t)context->layoutElementsHashMapInternal.length - 1;
     }
     return hashItem;
 }
 
 Clay_LayoutElementHashMapItem *Clay__GetHashMapItem(uint32_t id) {
-    uint32_t hashBucket = id % Clay__layoutElementsHashMap.capacity;
-    int32_t elementIndex = Clay__layoutElementsHashMap.internalArray[hashBucket];
+    Clay_Context* context = Clay_GetCurrentContext();
+    uint32_t hashBucket = id % context->layoutElementsHashMap.capacity;
+    int32_t elementIndex = context->layoutElementsHashMap.internalArray[hashBucket];
     while (elementIndex != -1) {
-        Clay_LayoutElementHashMapItem *hashEntry = Clay__LayoutElementHashMapItemArray_Get(&Clay__layoutElementsHashMapInternal, elementIndex);
+        Clay_LayoutElementHashMapItem *hashEntry = Clay__LayoutElementHashMapItemArray_Get(&context->layoutElementsHashMapInternal, elementIndex);
         if (hashEntry->elementId.id == id) {
             return hashEntry;
         }
@@ -1809,15 +1866,17 @@ Clay_LayoutElementHashMapItem *Clay__GetHashMapItem(uint32_t id) {
 }
 
 void Clay__GenerateIdForAnonymousElement(Clay_LayoutElement *openLayoutElement) {
-    Clay_LayoutElement *parentElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, Clay__int32_tArray_Get(&Clay__openLayoutElementStack, Clay__openLayoutElementStack.length - 2));
+    Clay_Context* context = Clay_GetCurrentContext();
+    Clay_LayoutElement *parentElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&context->openLayoutElementStack, context->openLayoutElementStack.length - 2));
     Clay_ElementId elementId = Clay__HashNumber(parentElement->childrenOrTextContent.children.length, parentElement->id);
     openLayoutElement->id = elementId.id;
     Clay__AddHashMapItem(elementId, openLayoutElement);
-    Clay__StringArray_Add(&Clay__layoutElementIdStrings, elementId.stringId);
+    Clay__StringArray_Add(&context->layoutElementIdStrings, elementId.stringId);
 }
 
-void Clay__ElementPostConfiguration(void) {
-    if (Clay__booleanWarnings.maxElementsExceeded) {
+void Clay__ElementPostConfiguration() {
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->booleanWarnings.maxElementsExceeded) {
         return;
     }
     Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
@@ -1831,9 +1890,9 @@ void Clay__ElementPostConfiguration(void) {
     }
 
     // Loop through element configs and handle special cases
-    openLayoutElement->elementConfigs.internalArray = &Clay__elementConfigs.internalArray[Clay__elementConfigs.length];
+    openLayoutElement->elementConfigs.internalArray = &context->elementConfigs.internalArray[context->elementConfigs.length];
     for (int32_t elementConfigIndex = 0; elementConfigIndex < openLayoutElement->elementConfigs.length; elementConfigIndex++) {
-        Clay_ElementConfig *config = Clay__ElementConfigArray_Add(&Clay__elementConfigs, *Clay__ElementConfigArray_Get(&Clay__elementConfigBuffer, Clay__elementConfigBuffer.length - openLayoutElement->elementConfigs.length + elementConfigIndex));
+        Clay_ElementConfig *config = Clay__ElementConfigArray_Add(&context->elementConfigs, *Clay__ElementConfigArray_Get(&context->elementConfigBuffer, context->elementConfigBuffer.length - openLayoutElement->elementConfigs.length + elementConfigIndex));
         openLayoutElement->configsEnabled |= config->type;
         switch (config->type) {
             case CLAY__ELEMENT_CONFIG_TYPE_RECTANGLE:
@@ -1841,7 +1900,7 @@ void Clay__ElementPostConfiguration(void) {
             case CLAY__ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER: {
                 Clay_FloatingElementConfig *floatingConfig = config->config.floatingElementConfig;
                 // This looks dodgy but because of the auto generated root element the depth of the tree will always be at least 2 here
-                Clay_LayoutElement *hierarchicalParent = Clay_LayoutElementArray_Get(&Clay__layoutElements, Clay__int32_tArray_Get(&Clay__openLayoutElementStack, Clay__openLayoutElementStack.length - 2));
+                Clay_LayoutElement *hierarchicalParent = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&context->openLayoutElementStack, context->openLayoutElementStack.length - 2));
                 if (!hierarchicalParent) {
                     break;
                 }
@@ -1850,24 +1909,24 @@ void Clay__ElementPostConfiguration(void) {
                     // If no parent id was specified, attach to the elements direct hierarchical parent
                     Clay_FloatingElementConfig newConfig = *floatingConfig;
                     newConfig.parentId = hierarchicalParent->id;
-                    floatingConfig = Clay__FloatingElementConfigArray_Add(&Clay__floatingElementConfigs, newConfig);
+                    floatingConfig = Clay__FloatingElementConfigArray_Add(&context->floatingElementConfigs, newConfig);
                     config->config.floatingElementConfig = floatingConfig;
-                    if (Clay__openClipElementStack.length > 0) {
-                        clipElementId = Clay__int32_tArray_Get(&Clay__openClipElementStack, (int)Clay__openClipElementStack.length - 1);
+                    if (context->openClipElementStack.length > 0) {
+                        clipElementId = Clay__int32_tArray_Get(&context->openClipElementStack, (int)context->openClipElementStack.length - 1);
                     }
                 } else {
                     Clay_LayoutElementHashMapItem *parentItem = Clay__GetHashMapItem(floatingConfig->parentId);
                     if (!parentItem) {
-                        Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
+                        context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
                             .errorType = CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND,
                             .errorText = CLAY_STRING("A floating element was declared with a parentId, but no element with that ID was found."),
-                            .userData = Clay__errorHandler.userData });
+                            .userData = context->errorHandler.userData });
                     } else {
-                        clipElementId = Clay__int32_tArray_Get(&Clay__layoutElementClipElementIds, parentItem->layoutElement - Clay__layoutElements.internalArray);
+                        clipElementId = Clay__int32_tArray_Get(&context->layoutElementClipElementIds, parentItem->layoutElement - context->layoutElements.internalArray);
                     }
                 }
-                Clay__LayoutElementTreeRootArray_Add(&Clay__layoutElementTreeRoots, CLAY__INIT(Clay__LayoutElementTreeRoot) {
-                    .layoutElementIndex = Clay__int32_tArray_Get(&Clay__openLayoutElementStack, Clay__openLayoutElementStack.length - 1),
+                Clay__LayoutElementTreeRootArray_Add(&context->layoutElementTreeRoots, CLAY__INIT(Clay__LayoutElementTreeRoot) {
+                    .layoutElementIndex = Clay__int32_tArray_Get(&context->openLayoutElementStack, context->openLayoutElementStack.length - 1),
                     .parentId = floatingConfig->parentId,
                     .clipElementId = clipElementId,
                     .zIndex = floatingConfig->zIndex,
@@ -1875,11 +1934,11 @@ void Clay__ElementPostConfiguration(void) {
                 break;
             }
             case CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER: {
-                Clay__int32_tArray_Add(&Clay__openClipElementStack, (int)openLayoutElement->id);
+                Clay__int32_tArray_Add(&context->openClipElementStack, (int)openLayoutElement->id);
                 // Retrieve or create cached data to track scroll position across frames
                 Clay__ScrollContainerDataInternal *scrollOffset = CLAY__NULL;
-                for (int32_t i = 0; i < Clay__scrollContainerDatas.length; i++) {
-                    Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&Clay__scrollContainerDatas, i);
+                for (int32_t i = 0; i < context->scrollContainerDatas.length; i++) {
+                    Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
                     if (openLayoutElement->id == mapping->elementId) {
                         scrollOffset = mapping;
                         scrollOffset->layoutElement = openLayoutElement;
@@ -1887,27 +1946,28 @@ void Clay__ElementPostConfiguration(void) {
                     }
                 }
                 if (!scrollOffset) {
-                    scrollOffset = Clay__ScrollContainerDataInternalArray_Add(&Clay__scrollContainerDatas, CLAY__INIT(Clay__ScrollContainerDataInternal){.layoutElement = openLayoutElement, .scrollOrigin = {-1,-1}, .elementId = openLayoutElement->id, .openThisFrame = true});
+                    scrollOffset = Clay__ScrollContainerDataInternalArray_Add(&context->scrollContainerDatas, CLAY__INIT(Clay__ScrollContainerDataInternal){.layoutElement = openLayoutElement, .scrollOrigin = {-1,-1}, .elementId = openLayoutElement->id, .openThisFrame = true});
                 }
-                if (Clay__externalScrollHandlingEnabled) {
+                if (context->externalScrollHandlingEnabled) {
                     scrollOffset->scrollPosition = Clay__QueryScrollOffset(scrollOffset->elementId);
                 }
                 break;
             }
             case CLAY__ELEMENT_CONFIG_TYPE_CUSTOM: break;
             case CLAY__ELEMENT_CONFIG_TYPE_IMAGE: {
-                Clay__LayoutElementPointerArray_Add(&Clay__imageElementPointers, openLayoutElement);
+                Clay__LayoutElementPointerArray_Add(&context->imageElementPointers, openLayoutElement);
                 break;
             }
             case CLAY__ELEMENT_CONFIG_TYPE_TEXT:
             default: break;
         }
     }
-    Clay__elementConfigBuffer.length -= openLayoutElement->elementConfigs.length;
+    context->elementConfigBuffer.length -= openLayoutElement->elementConfigs.length;
 }
 
-void Clay__CloseElement(void) {
-    if (Clay__booleanWarnings.maxElementsExceeded) {
+void Clay__CloseElement() {
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->booleanWarnings.maxElementsExceeded) {
         return;
     }
     Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
@@ -1918,16 +1978,16 @@ void Clay__CloseElement(void) {
         Clay_ScrollElementConfig *scrollConfig = Clay__FindElementConfigWithType(openLayoutElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER).scrollElementConfig;
         elementHasScrollHorizontal = scrollConfig->horizontal;
         elementHasScrollVertical = scrollConfig->vertical;
-        Clay__openClipElementStack.length--;
+        context->openClipElementStack.length--;
     }
 
     // Attach children to the current open element
-    openLayoutElement->childrenOrTextContent.children.elements = &Clay__layoutElementChildren.internalArray[Clay__layoutElementChildren.length];
+    openLayoutElement->childrenOrTextContent.children.elements = &context->layoutElementChildren.internalArray[context->layoutElementChildren.length];
     if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
         openLayoutElement->dimensions.width = (float)layoutConfig->padding.x * 2;
         for (int32_t i = 0; i < openLayoutElement->childrenOrTextContent.children.length; i++) {
-            int32_t childIndex = Clay__int32_tArray_Get(&Clay__layoutElementChildrenBuffer, (int)Clay__layoutElementChildrenBuffer.length - openLayoutElement->childrenOrTextContent.children.length + i);
-            Clay_LayoutElement *child = Clay_LayoutElementArray_Get(&Clay__layoutElements, childIndex);
+            int32_t childIndex = Clay__int32_tArray_Get(&context->layoutElementChildrenBuffer, (int)context->layoutElementChildrenBuffer.length - openLayoutElement->childrenOrTextContent.children.length + i);
+            Clay_LayoutElement *child = Clay_LayoutElementArray_Get(&context->layoutElements, childIndex);
             openLayoutElement->dimensions.width += child->dimensions.width;
             openLayoutElement->dimensions.height = CLAY__MAX(openLayoutElement->dimensions.height, child->dimensions.height + layoutConfig->padding.y * 2);
             // Minimum size of child elements doesn't matter to scroll containers as they can shrink and hide their contents
@@ -1937,7 +1997,7 @@ void Clay__CloseElement(void) {
             if (!elementHasScrollVertical) {
                 openLayoutElement->minDimensions.height = CLAY__MAX(openLayoutElement->minDimensions.height, child->minDimensions.height + layoutConfig->padding.y * 2);
             }
-            Clay__int32_tArray_Add(&Clay__layoutElementChildren, childIndex);
+            Clay__int32_tArray_Add(&context->layoutElementChildren, childIndex);
         }
         float childGap = (float)(CLAY__MAX(openLayoutElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap);
         openLayoutElement->dimensions.width += childGap; // TODO this is technically a bug with childgap and scroll containers
@@ -1946,8 +2006,8 @@ void Clay__CloseElement(void) {
     else if (layoutConfig->layoutDirection == CLAY_TOP_TO_BOTTOM) {
         openLayoutElement->dimensions.height = (float)layoutConfig->padding.y * 2;
         for (int32_t i = 0; i < openLayoutElement->childrenOrTextContent.children.length; i++) {
-            int32_t childIndex = Clay__int32_tArray_Get(&Clay__layoutElementChildrenBuffer, (int)Clay__layoutElementChildrenBuffer.length - openLayoutElement->childrenOrTextContent.children.length + i);
-            Clay_LayoutElement *child = Clay_LayoutElementArray_Get(&Clay__layoutElements, childIndex);
+            int32_t childIndex = Clay__int32_tArray_Get(&context->layoutElementChildrenBuffer, (int)context->layoutElementChildrenBuffer.length - openLayoutElement->childrenOrTextContent.children.length + i);
+            Clay_LayoutElement *child = Clay_LayoutElementArray_Get(&context->layoutElements, childIndex);
             openLayoutElement->dimensions.height += child->dimensions.height;
             openLayoutElement->dimensions.width = CLAY__MAX(openLayoutElement->dimensions.width, child->dimensions.width + layoutConfig->padding.x * 2);
             // Minimum size of child elements doesn't matter to scroll containers as they can shrink and hide their contents
@@ -1957,14 +2017,14 @@ void Clay__CloseElement(void) {
             if (!elementHasScrollHorizontal) {
                 openLayoutElement->minDimensions.width = CLAY__MAX(openLayoutElement->minDimensions.width, child->minDimensions.width + layoutConfig->padding.x * 2);
             }
-            Clay__int32_tArray_Add(&Clay__layoutElementChildren, childIndex);
+            Clay__int32_tArray_Add(&context->layoutElementChildren, childIndex);
         }
         float childGap = (float)(CLAY__MAX(openLayoutElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap);
         openLayoutElement->dimensions.height += childGap; // TODO this is technically a bug with childgap and scroll containers
         openLayoutElement->minDimensions.height += childGap;
     }
 
-    Clay__layoutElementChildrenBuffer.length -= openLayoutElement->childrenOrTextContent.children.length;
+    context->layoutElementChildrenBuffer.length -= openLayoutElement->childrenOrTextContent.children.length;
 
     // Clamp element min and max width to the values configured in the layout
     if (layoutConfig->sizing.width.type != CLAY__SIZING_TYPE_PERCENT) {
@@ -1991,33 +2051,35 @@ void Clay__CloseElement(void) {
     bool elementIsFloating = Clay__ElementHasConfig(openLayoutElement, CLAY__ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER);
 
     // Close the currently open element
-    int32_t closingElementIndex = Clay__int32_tArray_RemoveSwapback(&Clay__openLayoutElementStack, (int)Clay__openLayoutElementStack.length - 1);
+    int32_t closingElementIndex = Clay__int32_tArray_RemoveSwapback(&context->openLayoutElementStack, (int)context->openLayoutElementStack.length - 1);
     openLayoutElement = Clay__GetOpenLayoutElement();
 
-    if (!elementIsFloating && Clay__openLayoutElementStack.length > 1) {
+    if (!elementIsFloating && context->openLayoutElementStack.length > 1) {
         openLayoutElement->childrenOrTextContent.children.length++;
-        Clay__int32_tArray_Add(&Clay__layoutElementChildrenBuffer, closingElementIndex);
+        Clay__int32_tArray_Add(&context->layoutElementChildrenBuffer, closingElementIndex);
     }
 }
 
-void Clay__OpenElement(void) {
-    if (Clay__layoutElements.length == Clay__layoutElements.capacity - 1 || Clay__booleanWarnings.maxElementsExceeded) {
-        Clay__booleanWarnings.maxElementsExceeded = true;
+void Clay__OpenElement() {
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->layoutElements.length == context->layoutElements.capacity - 1 || context->booleanWarnings.maxElementsExceeded) {
+        context->booleanWarnings.maxElementsExceeded = true;
         return;
     }
     Clay_LayoutElement layoutElement = CLAY__DEFAULT_STRUCT;
-    Clay_LayoutElementArray_Add(&Clay__layoutElements, layoutElement);
-    Clay__int32_tArray_Add(&Clay__openLayoutElementStack, Clay__layoutElements.length - 1);
-    if (Clay__openClipElementStack.length > 0) {
-        Clay__int32_tArray_Set(&Clay__layoutElementClipElementIds, Clay__layoutElements.length - 1, Clay__int32_tArray_Get(&Clay__openClipElementStack, (int)Clay__openClipElementStack.length - 1));
+    Clay_LayoutElementArray_Add(&context->layoutElements, layoutElement);
+    Clay__int32_tArray_Add(&context->openLayoutElementStack, context->layoutElements.length - 1);
+    if (context->openClipElementStack.length > 0) {
+        Clay__int32_tArray_Set(&context->layoutElementClipElementIds, context->layoutElements.length - 1, Clay__int32_tArray_Get(&context->openClipElementStack, (int)context->openClipElementStack.length - 1));
     } else {
-        Clay__int32_tArray_Set(&Clay__layoutElementClipElementIds, Clay__layoutElements.length - 1, 0);
+        Clay__int32_tArray_Set(&context->layoutElementClipElementIds, context->layoutElements.length - 1, 0);
     }
 }
 
 void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig) {
-    if (Clay__layoutElements.length == Clay__layoutElements.capacity - 1 || Clay__booleanWarnings.maxElementsExceeded) {
-        Clay__booleanWarnings.maxElementsExceeded = true;
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->layoutElements.length == context->layoutElements.capacity - 1 || context->booleanWarnings.maxElementsExceeded) {
+        context->booleanWarnings.maxElementsExceeded = true;
         return;
     }
     Clay_LayoutElement *parentElement = Clay__GetOpenLayoutElement();
@@ -2025,75 +2087,81 @@ void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig)
 
     Clay__OpenElement();
     Clay_LayoutElement * openLayoutElement = Clay__GetOpenLayoutElement();
-    Clay__int32_tArray_Add(&Clay__layoutElementChildrenBuffer, Clay__layoutElements.length - 1);
+    Clay__int32_tArray_Add(&context->layoutElementChildrenBuffer, context->layoutElements.length - 1);
     Clay__MeasureTextCacheItem *textMeasured = Clay__MeasureTextCached(&text, textConfig);
     Clay_ElementId elementId = Clay__HashString(CLAY_STRING("Text"), parentElement->childrenOrTextContent.children.length, parentElement->id);
     openLayoutElement->id = elementId.id;
     Clay__AddHashMapItem(elementId, openLayoutElement);
-    Clay__StringArray_Add(&Clay__layoutElementIdStrings, elementId.stringId);
+    Clay__StringArray_Add(&context->layoutElementIdStrings, elementId.stringId);
     Clay_Dimensions textDimensions = { .width = textMeasured->unwrappedDimensions.width, .height = textConfig->lineHeight > 0 ? (float)textConfig->lineHeight : textMeasured->unwrappedDimensions.height };
     openLayoutElement->dimensions = textDimensions;
     openLayoutElement->minDimensions = CLAY__INIT(Clay_Dimensions) { .width = textMeasured->unwrappedDimensions.height, .height = textDimensions.height }; // TODO not sure this is the best way to decide min width for text
-    openLayoutElement->childrenOrTextContent.textElementData = Clay__TextElementDataArray_Add(&Clay__textElementData, CLAY__INIT(Clay__TextElementData) { .text = text, .preferredDimensions = textMeasured->unwrappedDimensions, .elementIndex = Clay__layoutElements.length - 1 });
+    openLayoutElement->childrenOrTextContent.textElementData = Clay__TextElementDataArray_Add(&context->textElementData, CLAY__INIT(Clay__TextElementData) { .text = text, .preferredDimensions = textMeasured->unwrappedDimensions, .elementIndex = context->layoutElements.length - 1 });
     openLayoutElement->elementConfigs = CLAY__INIT(Clay__ElementConfigArraySlice) {
         .length = 1,
-        .internalArray = Clay__ElementConfigArray_Add(&Clay__elementConfigs, CLAY__INIT(Clay_ElementConfig) { .type = CLAY__ELEMENT_CONFIG_TYPE_TEXT, .config = { .textElementConfig = textConfig }})
+        .internalArray = Clay__ElementConfigArray_Add(&context->elementConfigs, CLAY__INIT(Clay_ElementConfig) { .type = CLAY__ELEMENT_CONFIG_TYPE_TEXT, .config = { .textElementConfig = textConfig }})
     };
     openLayoutElement->configsEnabled |= CLAY__ELEMENT_CONFIG_TYPE_TEXT;
     openLayoutElement->layoutConfig = &CLAY_LAYOUT_DEFAULT;
     // Close the currently open element
-    Clay__int32_tArray_RemoveSwapback(&Clay__openLayoutElementStack, (int)Clay__openLayoutElementStack.length - 1);
+    Clay__int32_tArray_RemoveSwapback(&context->openLayoutElementStack, (int)context->openLayoutElementStack.length - 1);
 }
 
 void Clay__InitializeEphemeralMemory(Clay_Arena *arena) {
+    Clay_Context* context = arena->context;
+    int32_t maxElementCount = arena->maxElementCount;
     // Ephemeral Memory - reset every frame
-    Clay__internalArena.nextAllocation = Clay__arenaResetOffset;
+    context->internalArena.nextAllocation = context->arenaResetOffset;
 
-    Clay__layoutElementChildrenBuffer = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__layoutElements = Clay_LayoutElementArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay_warnings = Clay__WarningArray_Allocate_Arena(100, arena);
+    context->layoutElementChildrenBuffer = Clay__int32_tArray_Allocate_Arena(maxElementCount, arena);
+    context->layoutElements = Clay_LayoutElementArray_Allocate_Arena(maxElementCount, arena);
+    context->warnings = Clay__WarningArray_Allocate_Arena(100, arena);
 
-    Clay__layoutConfigs = Clay__LayoutConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__elementConfigBuffer = Clay__ElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__elementConfigs = Clay__ElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__rectangleElementConfigs = Clay__RectangleElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__textElementConfigs = Clay__TextElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__imageElementConfigs = Clay__ImageElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__floatingElementConfigs = Clay__FloatingElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__scrollElementConfigs = Clay__ScrollElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__customElementConfigs = Clay__CustomElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__borderElementConfigs = Clay__BorderElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
+    context->layoutConfigs = Clay__LayoutConfigArray_Allocate_Arena(maxElementCount, arena);
+    context->elementConfigBuffer = Clay__ElementConfigArray_Allocate_Arena(maxElementCount, arena);
+    context->elementConfigs = Clay__ElementConfigArray_Allocate_Arena(maxElementCount, arena);
+    context->rectangleElementConfigs = Clay__RectangleElementConfigArray_Allocate_Arena(maxElementCount, arena);
+    context->textElementConfigs = Clay__TextElementConfigArray_Allocate_Arena(maxElementCount, arena);
+    context->imageElementConfigs = Clay__ImageElementConfigArray_Allocate_Arena(maxElementCount, arena);
+    context->floatingElementConfigs = Clay__FloatingElementConfigArray_Allocate_Arena(maxElementCount, arena);
+    context->scrollElementConfigs = Clay__ScrollElementConfigArray_Allocate_Arena(maxElementCount, arena);
+    context->customElementConfigs = Clay__CustomElementConfigArray_Allocate_Arena(maxElementCount, arena);
+    context->borderElementConfigs = Clay__BorderElementConfigArray_Allocate_Arena(maxElementCount, arena);
 
-    Clay__layoutElementIdStrings = Clay__StringArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__wrappedTextLines = Clay__WrappedTextLineArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__layoutElementTreeNodeArray1 = Clay__LayoutElementTreeNodeArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__layoutElementTreeRoots = Clay__LayoutElementTreeRootArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__layoutElementChildren = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__openLayoutElementStack = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__textElementData = Clay__TextElementDataArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__imageElementPointers = Clay__LayoutElementPointerArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__renderCommands = Clay_RenderCommandArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__treeNodeVisited = Clay__BoolArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__treeNodeVisited.length = Clay__treeNodeVisited.capacity; // This array is accessed directly rather than behaving as a list
-    Clay__openClipElementStack = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__reusableElementIndexBuffer = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__layoutElementClipElementIds = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__dynamicStringData = Clay__CharArray_Allocate_Arena(Clay__maxElementCount, arena);
+    context->layoutElementIdStrings = Clay__StringArray_Allocate_Arena(maxElementCount, arena);
+    context->wrappedTextLines = Clay__WrappedTextLineArray_Allocate_Arena(maxElementCount, arena);
+    context->layoutElementTreeNodeArray1 = Clay__LayoutElementTreeNodeArray_Allocate_Arena(maxElementCount, arena);
+    context->layoutElementTreeRoots = Clay__LayoutElementTreeRootArray_Allocate_Arena(maxElementCount, arena);
+    context->layoutElementChildren = Clay__int32_tArray_Allocate_Arena(maxElementCount, arena);
+    context->openLayoutElementStack = Clay__int32_tArray_Allocate_Arena(maxElementCount, arena);
+    context->textElementData = Clay__TextElementDataArray_Allocate_Arena(maxElementCount, arena);
+    context->imageElementPointers = Clay__LayoutElementPointerArray_Allocate_Arena(maxElementCount, arena);
+    context->renderCommands = Clay_RenderCommandArray_Allocate_Arena(maxElementCount, arena);
+    context->treeNodeVisited = Clay__BoolArray_Allocate_Arena(maxElementCount, arena);
+    context->treeNodeVisited.length = context->treeNodeVisited.capacity; // This array is accessed directly rather than behaving as a list
+    context->openClipElementStack = Clay__int32_tArray_Allocate_Arena(maxElementCount, arena);
+    context->reusableElementIndexBuffer = Clay__int32_tArray_Allocate_Arena(maxElementCount, arena);
+    context->layoutElementClipElementIds = Clay__int32_tArray_Allocate_Arena(maxElementCount, arena);
+    context->dynamicStringData = Clay__CharArray_Allocate_Arena(maxElementCount, arena);
 }
 
 void Clay__InitializePersistentMemory(Clay_Arena *arena) {
     // Persistent memory - initialized once and not reset
-    Clay__scrollContainerDatas = Clay__ScrollContainerDataInternalArray_Allocate_Arena(10, arena);
-    Clay__layoutElementsHashMapInternal = Clay__LayoutElementHashMapItemArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__layoutElementsHashMap = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__measureTextHashMapInternal = Clay__MeasureTextCacheItemArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__measureTextHashMapInternalFreeList = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__measuredWordsFreeList = Clay__int32_tArray_Allocate_Arena(Clay__maxMeasureTextCacheWordCount, arena);
-    Clay__measureTextHashMap = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__measuredWords = Clay__MeasuredWordArray_Allocate_Arena(Clay__maxMeasureTextCacheWordCount, arena);
-    Clay__pointerOverIds = Clay__ElementIdArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__debugElementData = Clay__DebugElementDataArray_Allocate_Arena(Clay__maxElementCount, arena);
-    Clay__arenaResetOffset = arena->nextAllocation;
+    Clay_Context* context = arena->context;
+    int32_t maxElementCount = arena->maxElementCount;
+    int32_t maxMeasureTextCacheWordCount = arena->maxMeasureTextCacheWordCount;
+    
+    context->scrollContainerDatas = Clay__ScrollContainerDataInternalArray_Allocate_Arena(10, arena);
+    context->layoutElementsHashMapInternal = Clay__LayoutElementHashMapItemArray_Allocate_Arena(maxElementCount, arena);
+    context->layoutElementsHashMap = Clay__int32_tArray_Allocate_Arena(maxElementCount, arena);
+    context->measureTextHashMapInternal = Clay__MeasureTextCacheItemArray_Allocate_Arena(maxElementCount, arena);
+    context->measureTextHashMapInternalFreeList = Clay__int32_tArray_Allocate_Arena(maxElementCount, arena);
+    context->measuredWordsFreeList = Clay__int32_tArray_Allocate_Arena(maxMeasureTextCacheWordCount, arena);
+    context->measureTextHashMap = Clay__int32_tArray_Allocate_Arena(maxElementCount, arena);
+    context->measuredWords = Clay__MeasuredWordArray_Allocate_Arena(maxMeasureTextCacheWordCount, arena);
+    context->pointerOverIds = Clay__ElementIdArray_Allocate_Arena(maxElementCount, arena);
+    context->debugElementData = Clay__DebugElementDataArray_Allocate_Arena(maxElementCount, arena);
+    context->arenaResetOffset = arena->nextAllocation;
 }
 
 
@@ -2104,7 +2172,8 @@ CLAY__TYPEDEF(Clay__SizeDistributionType, enum {
 });
 
 float Clay__DistributeSizeAmongChildren(bool xAxis, float sizeToDistribute, Clay__int32_tArray resizableContainerBuffer, Clay__SizeDistributionType distributionType) {
-    Clay__int32_tArray remainingElements = Clay__openClipElementStack;
+    Clay_Context* context = Clay_GetCurrentContext();
+    Clay__int32_tArray remainingElements = context->openClipElementStack;
     remainingElements.length = 0;
 
     for (int32_t i = 0; i < resizableContainerBuffer.length; ++i) {
@@ -2114,7 +2183,7 @@ float Clay__DistributeSizeAmongChildren(bool xAxis, float sizeToDistribute, Clay
     while (sizeToDistribute != 0 && remainingElements.length > 0) {
         float dividedSize = sizeToDistribute / (float)remainingElements.length;
         for (int32_t childOffset = 0; childOffset < remainingElements.length; childOffset++) {
-            Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, Clay__int32_tArray_Get(&remainingElements, childOffset));
+            Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&remainingElements, childOffset));
             Clay_SizingAxis childSizing = xAxis ? childElement->layoutConfig->sizing.width : childElement->layoutConfig->sizing.height;
             float *childSize = xAxis ? &childElement->dimensions.width : &childElement->dimensions.height;
             float childMinSize = xAxis ? childElement->minDimensions.width : childElement->minDimensions.height;
@@ -2165,12 +2234,13 @@ float Clay__DistributeSizeAmongChildren(bool xAxis, float sizeToDistribute, Clay
 }
 
 void Clay__SizeContainersAlongAxis(bool xAxis) {
-    Clay__int32_tArray bfsBuffer = Clay__layoutElementChildrenBuffer;
-    Clay__int32_tArray resizableContainerBuffer = Clay__openLayoutElementStack;
-    for (int32_t rootIndex = 0; rootIndex < Clay__layoutElementTreeRoots.length; ++rootIndex) {
+    Clay_Context* context = Clay_GetCurrentContext();
+    Clay__int32_tArray bfsBuffer = context->layoutElementChildrenBuffer;
+    Clay__int32_tArray resizableContainerBuffer = context->openLayoutElementStack;
+    for (int32_t rootIndex = 0; rootIndex < context->layoutElementTreeRoots.length; ++rootIndex) {
         bfsBuffer.length = 0;
-        Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&Clay__layoutElementTreeRoots, rootIndex);
-        Clay_LayoutElement *rootElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, (int)root->layoutElementIndex);
+        Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&context->layoutElementTreeRoots, rootIndex);
+        Clay_LayoutElement *rootElement = Clay_LayoutElementArray_Get(&context->layoutElements, (int)root->layoutElementIndex);
         Clay__int32_tArray_Add(&bfsBuffer, (int32_t)root->layoutElementIndex);
 
         // Size floating containers to their parents
@@ -2193,7 +2263,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
 
         for (int32_t i = 0; i < bfsBuffer.length; ++i) {
             int32_t parentIndex = Clay__int32_tArray_Get(&bfsBuffer, i);
-            Clay_LayoutElement *parent = Clay_LayoutElementArray_Get(&Clay__layoutElements, parentIndex);
+            Clay_LayoutElement *parent = Clay_LayoutElementArray_Get(&context->layoutElements, parentIndex);
             Clay_LayoutConfig *parentStyleConfig = parent->layoutConfig;
             int32_t growContainerCount = 0;
             float parentSize = xAxis ? parent->dimensions.width : parent->dimensions.height;
@@ -2205,7 +2275,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
 
             for (int32_t childOffset = 0; childOffset < parent->childrenOrTextContent.children.length; childOffset++) {
                 int32_t childElementIndex = parent->childrenOrTextContent.children.elements[childOffset];
-                Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, childElementIndex);
+                Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, childElementIndex);
                 Clay_SizingAxis childSizing = xAxis ? childElement->layoutConfig->sizing.width : childElement->layoutConfig->sizing.height;
                 float childSize = xAxis ? childElement->dimensions.width : childElement->dimensions.height;
 
@@ -2235,7 +2305,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
             // Expand percentage containers to size
             for (int32_t childOffset = 0; childOffset < parent->childrenOrTextContent.children.length; childOffset++) {
                 int32_t childElementIndex = parent->childrenOrTextContent.children.elements[childOffset];
-                Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, childElementIndex);
+                Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, childElementIndex);
                 Clay_SizingAxis childSizing = xAxis ? childElement->layoutConfig->sizing.width : childElement->layoutConfig->sizing.height;
                 float *childSize = xAxis ? &childElement->dimensions.width : &childElement->dimensions.height;
                 if (childSizing.type == CLAY__SIZING_TYPE_PERCENT) {
@@ -2274,7 +2344,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
                 } else if (sizeToDistribute > 0 && growContainerCount > 0) {
                     float targetSize = (sizeToDistribute + growContainerContentSize) / (float)growContainerCount;
                     for (int32_t childOffset = 0; childOffset < resizableContainerBuffer.length; childOffset++) {
-                        Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, Clay__int32_tArray_Get(&resizableContainerBuffer, childOffset));
+                        Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&resizableContainerBuffer, childOffset));
                         Clay_SizingAxis childSizing = xAxis ? childElement->layoutConfig->sizing.width : childElement->layoutConfig->sizing.height;
                         if (childSizing.type == CLAY__SIZING_TYPE_GROW) {
                             float *childSize = xAxis ? &childElement->dimensions.width : &childElement->dimensions.height;
@@ -2294,7 +2364,7 @@ void Clay__SizeContainersAlongAxis(bool xAxis) {
             // Sizing along the non layout axis ("off axis")
             } else {
                 for (int32_t childOffset = 0; childOffset < resizableContainerBuffer.length; childOffset++) {
-                    Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, Clay__int32_tArray_Get(&resizableContainerBuffer, childOffset));
+                    Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&resizableContainerBuffer, childOffset));
                     Clay_SizingAxis childSizing = xAxis ? childElement->layoutConfig->sizing.width : childElement->layoutConfig->sizing.height;
                     float *childSize = xAxis ? &childElement->dimensions.width : &childElement->dimensions.height;
 
@@ -2325,7 +2395,8 @@ Clay_String Clay__IntToString(int32_t integer) {
     if (integer == 0) {
         return CLAY__INIT(Clay_String) { .length = 1, .chars = "0" };
     }
-    char *chars = (char *)(Clay__dynamicStringData.internalArray + Clay__dynamicStringData.length);
+    Clay_Context* context = Clay_GetCurrentContext();
+    char *chars = (char *)(context->dynamicStringData.internalArray + context->dynamicStringData.length);
     int32_t length = 0;
     int32_t sign = integer;
 
@@ -2347,44 +2418,47 @@ Clay_String Clay__IntToString(int32_t integer) {
         chars[j] = chars[k];
         chars[k] = temp;
     }
-    Clay__dynamicStringData.length += length;
+    context->dynamicStringData.length += length;
     return CLAY__INIT(Clay_String) { .length = length, .chars = chars };
 }
 
 void Clay__AddRenderCommand(Clay_RenderCommand renderCommand) {
-    if (Clay__renderCommands.length < Clay__renderCommands.capacity - 1) {
-        Clay_RenderCommandArray_Add(&Clay__renderCommands, renderCommand);
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->renderCommands.length < context->renderCommands.capacity - 1) {
+        Clay_RenderCommandArray_Add(&context->renderCommands, renderCommand);
     } else {
-        if (!Clay__booleanWarnings.maxRenderCommandsExceeded) {
-            Clay__booleanWarnings.maxRenderCommandsExceeded = true;
-            Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
+        if (!context->booleanWarnings.maxRenderCommandsExceeded) {
+            context->booleanWarnings.maxRenderCommandsExceeded = true;
+            context->errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
                 .errorType = CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED,
                 .errorText = CLAY_STRING("Clay ran out of capacity while attempting to create render commands. This is usually caused by a large amount of wrapping text elements while close to the max element capacity. Try using Clay_SetMaxElementCount() with a higher value."),
-                .userData = Clay__errorHandler.userData });
+                .userData = context->errorHandler.userData });
         }
     }
 }
 
 bool Clay__ElementIsOffscreen(Clay_BoundingBox *boundingBox) {
-    if (Clay__disableCulling) {
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->disableCulling) {
         return false;
     }
 
-    return (boundingBox->x > (float)Clay__layoutDimensions.width) ||
-           (boundingBox->y > (float)Clay__layoutDimensions.height) ||
+    return (boundingBox->x > (float)context->layoutDimensions.width) ||
+           (boundingBox->y > (float)context->layoutDimensions.height) ||
            (boundingBox->x + boundingBox->width < 0) ||
            (boundingBox->y + boundingBox->height < 0);
 }
 
-void Clay__CalculateFinalLayout(void) {
+void Clay__CalculateFinalLayout() {
+    Clay_Context* context = Clay_GetCurrentContext();
     // Calculate sizing along the X axis
     Clay__SizeContainersAlongAxis(true);
 
     // Wrap text
-    for (int32_t textElementIndex = 0; textElementIndex < Clay__textElementData.length; ++textElementIndex) {
-        Clay__TextElementData *textElementData = Clay__TextElementDataArray_Get(&Clay__textElementData, textElementIndex);
-        textElementData->wrappedLines = CLAY__INIT(Clay__WrappedTextLineArraySlice) { .length = 0, .internalArray = &Clay__wrappedTextLines.internalArray[Clay__wrappedTextLines.length] };
-        Clay_LayoutElement *containerElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, (int)textElementData->elementIndex);
+    for (int32_t textElementIndex = 0; textElementIndex < context->textElementData.length; ++textElementIndex) {
+        Clay__TextElementData *textElementData = Clay__TextElementDataArray_Get(&context->textElementData, textElementIndex);
+        textElementData->wrappedLines = CLAY__INIT(Clay__WrappedTextLineArraySlice) { .length = 0, .internalArray = &context->wrappedTextLines.internalArray[context->wrappedTextLines.length] };
+        Clay_LayoutElement *containerElement = Clay_LayoutElementArray_Get(&context->layoutElements, (int)textElementData->elementIndex);
         Clay_TextElementConfig *textConfig = Clay__FindElementConfigWithType(containerElement, CLAY__ELEMENT_CONFIG_TYPE_TEXT).textElementConfig;
         Clay__MeasureTextCacheItem *measureTextCacheItem = Clay__MeasureTextCached(&textElementData->text, textConfig);
         float lineWidth = 0;
@@ -2392,19 +2466,19 @@ void Clay__CalculateFinalLayout(void) {
         int32_t lineLengthChars = 0;
         int32_t lineStartOffset = 0;
         if (textElementData->preferredDimensions.width <= containerElement->dimensions.width) {
-            Clay__WrappedTextLineArray_Add(&Clay__wrappedTextLines, CLAY__INIT(Clay__WrappedTextLine) { containerElement->dimensions,  textElementData->text });
+            Clay__WrappedTextLineArray_Add(&context->wrappedTextLines, CLAY__INIT(Clay__WrappedTextLine) { containerElement->dimensions,  textElementData->text });
             textElementData->wrappedLines.length++;
             continue;
         }
         int32_t wordIndex = measureTextCacheItem->measuredWordsStartIndex;
         while (wordIndex != -1) {
-            if (Clay__wrappedTextLines.length > Clay__wrappedTextLines.capacity - 1) {
+            if (context->wrappedTextLines.length > context->wrappedTextLines.capacity - 1) {
                 break;
             }
-            Clay__MeasuredWord *measuredWord = Clay__MeasuredWordArray_Get(&Clay__measuredWords, wordIndex);
+            Clay__MeasuredWord *measuredWord = Clay__MeasuredWordArray_Get(&context->measuredWords, wordIndex);
             // Only word on the line is too large, just render it anyway
             if (lineLengthChars == 0 && lineWidth + measuredWord->width > containerElement->dimensions.width) {
-                Clay__WrappedTextLineArray_Add(&Clay__wrappedTextLines, CLAY__INIT(Clay__WrappedTextLine) { { measuredWord->width, lineHeight }, { .length = measuredWord->length, .chars = &textElementData->text.chars[measuredWord->startOffset] } });
+                Clay__WrappedTextLineArray_Add(&context->wrappedTextLines, CLAY__INIT(Clay__WrappedTextLine) { { measuredWord->width, lineHeight }, { .length = measuredWord->length, .chars = &textElementData->text.chars[measuredWord->startOffset] } });
                 textElementData->wrappedLines.length++;
                 wordIndex = measuredWord->next;
                 lineStartOffset = measuredWord->startOffset + measuredWord->length;
@@ -2412,7 +2486,7 @@ void Clay__CalculateFinalLayout(void) {
             // measuredWord->length == 0 means a newline character
             else if (measuredWord->length == 0 || lineWidth + measuredWord->width > containerElement->dimensions.width) {
                 // Wrapped text lines list has overflowed, just render out the line
-                Clay__WrappedTextLineArray_Add(&Clay__wrappedTextLines, CLAY__INIT(Clay__WrappedTextLine) { { lineWidth, lineHeight }, { .length = lineLengthChars, .chars = &textElementData->text.chars[lineStartOffset] } });
+                Clay__WrappedTextLineArray_Add(&context->wrappedTextLines, CLAY__INIT(Clay__WrappedTextLine) { { lineWidth, lineHeight }, { .length = lineLengthChars, .chars = &textElementData->text.chars[lineStartOffset] } });
                 textElementData->wrappedLines.length++;
                 if (lineLengthChars == 0 || measuredWord->length == 0) {
                     wordIndex = measuredWord->next;
@@ -2427,32 +2501,32 @@ void Clay__CalculateFinalLayout(void) {
             }
         }
         if (lineLengthChars > 0) {
-            Clay__WrappedTextLineArray_Add(&Clay__wrappedTextLines, CLAY__INIT(Clay__WrappedTextLine) { { lineWidth, lineHeight }, {.length = lineLengthChars, .chars = &textElementData->text.chars[lineStartOffset] } });
+            Clay__WrappedTextLineArray_Add(&context->wrappedTextLines, CLAY__INIT(Clay__WrappedTextLine) { { lineWidth, lineHeight }, {.length = lineLengthChars, .chars = &textElementData->text.chars[lineStartOffset] } });
             textElementData->wrappedLines.length++;
         }
         containerElement->dimensions.height = lineHeight * (float)textElementData->wrappedLines.length;
     }
 
     // Scale vertical image heights according to aspect ratio
-    for (int32_t i = 0; i < Clay__imageElementPointers.length; ++i) {
-        Clay_LayoutElement* imageElement = Clay__LayoutElementPointerArray_Get(&Clay__imageElementPointers, i);
+    for (int32_t i = 0; i < context->imageElementPointers.length; ++i) {
+        Clay_LayoutElement* imageElement = Clay__LayoutElementPointerArray_Get(&context->imageElementPointers, i);
         Clay_ImageElementConfig *config = Clay__FindElementConfigWithType(imageElement, CLAY__ELEMENT_CONFIG_TYPE_IMAGE).imageElementConfig;
         imageElement->dimensions.height = (config->sourceDimensions.height / CLAY__MAX(config->sourceDimensions.width, 1)) * imageElement->dimensions.width;
     }
 
     // Propagate effect of text wrapping, image aspect scaling etc. on height of parents
-    Clay__LayoutElementTreeNodeArray dfsBuffer = Clay__layoutElementTreeNodeArray1;
+    Clay__LayoutElementTreeNodeArray dfsBuffer = context->layoutElementTreeNodeArray1;
     dfsBuffer.length = 0;
-    for (int32_t i = 0; i < Clay__layoutElementTreeRoots.length; ++i) {
-        Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&Clay__layoutElementTreeRoots, i);
-        Clay__treeNodeVisited.internalArray[dfsBuffer.length] = false;
-        Clay__LayoutElementTreeNodeArray_Add(&dfsBuffer, CLAY__INIT(Clay__LayoutElementTreeNode) { .layoutElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, (int)root->layoutElementIndex) });
+    for (int32_t i = 0; i < context->layoutElementTreeRoots.length; ++i) {
+        Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&context->layoutElementTreeRoots, i);
+        context->treeNodeVisited.internalArray[dfsBuffer.length] = false;
+        Clay__LayoutElementTreeNodeArray_Add(&dfsBuffer, CLAY__INIT(Clay__LayoutElementTreeNode) { .layoutElement = Clay_LayoutElementArray_Get(&context->layoutElements, (int)root->layoutElementIndex) });
     }
     while (dfsBuffer.length > 0) {
         Clay__LayoutElementTreeNode *currentElementTreeNode = Clay__LayoutElementTreeNodeArray_Get(&dfsBuffer, (int)dfsBuffer.length - 1);
         Clay_LayoutElement *currentElement = currentElementTreeNode->layoutElement;
-        if (!Clay__treeNodeVisited.internalArray[dfsBuffer.length - 1]) {
-            Clay__treeNodeVisited.internalArray[dfsBuffer.length - 1] = true;
+        if (!context->treeNodeVisited.internalArray[dfsBuffer.length - 1]) {
+            context->treeNodeVisited.internalArray[dfsBuffer.length - 1] = true;
             // If the element has no children or is the container for a text element, don't bother inspecting it
             if (Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_TEXT) || currentElement->childrenOrTextContent.children.length == 0) {
                 dfsBuffer.length--;
@@ -2460,8 +2534,8 @@ void Clay__CalculateFinalLayout(void) {
             }
             // Add the children to the DFS buffer (needs to be pushed in reverse so that stack traversal is in correct layout order)
             for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; i++) {
-                Clay__treeNodeVisited.internalArray[dfsBuffer.length] = false;
-                Clay__LayoutElementTreeNodeArray_Add(&dfsBuffer, CLAY__INIT(Clay__LayoutElementTreeNode) { .layoutElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, currentElement->childrenOrTextContent.children.elements[i]) });
+                context->treeNodeVisited.internalArray[dfsBuffer.length] = false;
+                Clay__LayoutElementTreeNodeArray_Add(&dfsBuffer, CLAY__INIT(Clay__LayoutElementTreeNode) { .layoutElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]) });
             }
             continue;
         }
@@ -2475,7 +2549,7 @@ void Clay__CalculateFinalLayout(void) {
         if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
             // Resize any parent containers that have grown in height along their non layout axis
             for (int32_t j = 0; j < currentElement->childrenOrTextContent.children.length; ++j) {
-                Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, currentElement->childrenOrTextContent.children.elements[j]);
+                Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[j]);
                 float childHeightWithPadding = CLAY__MAX(childElement->dimensions.height + layoutConfig->padding.y * 2, currentElement->dimensions.height);
                 currentElement->dimensions.height = CLAY__MIN(CLAY__MAX(childHeightWithPadding, layoutConfig->sizing.height.size.minMax.min), layoutConfig->sizing.height.size.minMax.max);
             }
@@ -2483,7 +2557,7 @@ void Clay__CalculateFinalLayout(void) {
             // Resizing along the layout axis
             float contentHeight = (float)layoutConfig->padding.y * 2;
             for (int32_t j = 0; j < currentElement->childrenOrTextContent.children.length; ++j) {
-                Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, currentElement->childrenOrTextContent.children.elements[j]);
+                Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[j]);
                 contentHeight += childElement->dimensions.height;
             }
             contentHeight += (float)(CLAY__MAX(currentElement->childrenOrTextContent.children.length - 1, 0) * layoutConfig->childGap);
@@ -2495,12 +2569,12 @@ void Clay__CalculateFinalLayout(void) {
     Clay__SizeContainersAlongAxis(false);
 
     // Calculate final positions and generate render commands
-    Clay__renderCommands.length = 0;
+    context->renderCommands.length = 0;
     dfsBuffer.length = 0;
-    for (int32_t rootIndex = 0; rootIndex < Clay__layoutElementTreeRoots.length; ++rootIndex) {
+    for (int32_t rootIndex = 0; rootIndex < context->layoutElementTreeRoots.length; ++rootIndex) {
         dfsBuffer.length = 0;
-        Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&Clay__layoutElementTreeRoots, rootIndex);
-        Clay_LayoutElement *rootElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, (int)root->layoutElementIndex);
+        Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&context->layoutElementTreeRoots, rootIndex);
+        Clay_LayoutElement *rootElement = Clay_LayoutElementArray_Get(&context->layoutElements, (int)root->layoutElementIndex);
         Clay_Vector2 rootPosition = CLAY__DEFAULT_STRUCT;
         Clay_LayoutElementHashMapItem *parentHashMapItem = Clay__GetHashMapItem(root->parentId);
         // Position root floating containers
@@ -2562,10 +2636,10 @@ void Clay__CalculateFinalLayout(void) {
             Clay_LayoutElementHashMapItem *clipHashMapItem = Clay__GetHashMapItem(root->clipElementId);
             if (clipHashMapItem) {
                 // Floating elements that are attached to scrolling contents won't be correctly positioned if external scroll handling is enabled, fix here
-                if (Clay__externalScrollHandlingEnabled) {
+                if (context->externalScrollHandlingEnabled) {
                     Clay_ScrollElementConfig *scrollConfig = Clay__FindElementConfigWithType(clipHashMapItem->layoutElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER).scrollElementConfig;
-                    for (int32_t i = 0; i < Clay__scrollContainerDatas.length; i++) {
-                        Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&Clay__scrollContainerDatas, i);
+                    for (int32_t i = 0; i < context->scrollContainerDatas.length; i++) {
+                        Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
                         if (mapping->layoutElement == clipHashMapItem->layoutElement) {
                             root->pointerOffset = mapping->scrollPosition;
                             if (scrollConfig->horizontal) {
@@ -2588,7 +2662,7 @@ void Clay__CalculateFinalLayout(void) {
         }
         Clay__LayoutElementTreeNodeArray_Add(&dfsBuffer, CLAY__INIT(Clay__LayoutElementTreeNode) { .layoutElement = rootElement, .position = rootPosition, .nextChildOffset = { .x = (float)rootElement->layoutConfig->padding.x, .y = (float)rootElement->layoutConfig->padding.y } });
 
-        Clay__treeNodeVisited.internalArray[0] = false;
+        context->treeNodeVisited.internalArray[0] = false;
         while (dfsBuffer.length > 0) {
             Clay__LayoutElementTreeNode *currentElementTreeNode = Clay__LayoutElementTreeNodeArray_Get(&dfsBuffer, (int)dfsBuffer.length - 1);
             Clay_LayoutElement *currentElement = currentElementTreeNode->layoutElement;
@@ -2596,8 +2670,8 @@ void Clay__CalculateFinalLayout(void) {
             Clay_Vector2 scrollOffset = CLAY__DEFAULT_STRUCT;
 
             // This will only be run a single time for each element in downwards DFS order
-            if (!Clay__treeNodeVisited.internalArray[dfsBuffer.length - 1]) {
-                Clay__treeNodeVisited.internalArray[dfsBuffer.length - 1] = true;
+            if (!context->treeNodeVisited.internalArray[dfsBuffer.length - 1]) {
+                context->treeNodeVisited.internalArray[dfsBuffer.length - 1] = true;
 
                 Clay_BoundingBox currentElementBoundingBox = { currentElementTreeNode->position.x, currentElementTreeNode->position.y, currentElement->dimensions.width, currentElement->dimensions.height };
                 if (Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER)) {
@@ -2615,8 +2689,8 @@ void Clay__CalculateFinalLayout(void) {
                     Clay_ScrollElementConfig *scrollConfig = Clay__FindElementConfigWithType(currentElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER).scrollElementConfig;
 
                     // This linear scan could theoretically be slow under very strange conditions, but I can't imagine a real UI with more than a few 10's of scroll containers
-                    for (int32_t i = 0; i < Clay__scrollContainerDatas.length; i++) {
-                        Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&Clay__scrollContainerDatas, i);
+                    for (int32_t i = 0; i < context->scrollContainerDatas.length; i++) {
+                        Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
                         if (mapping->layoutElement == currentElement) {
                             scrollContainerData = mapping;
                             mapping->boundingBox = currentElementBoundingBox;
@@ -2626,7 +2700,7 @@ void Clay__CalculateFinalLayout(void) {
                             if (scrollConfig->vertical) {
                                 scrollOffset.y = mapping->scrollPosition.y;
                             }
-                            if (Clay__externalScrollHandlingEnabled) {
+                            if (context->externalScrollHandlingEnabled) {
                                 scrollOffset = CLAY__INIT(Clay_Vector2) CLAY__DEFAULT_STRUCT;
                             }
                             break;
@@ -2719,7 +2793,7 @@ void Clay__CalculateFinalLayout(void) {
                                 });
                                 yPosition += finalLineHeight;
 
-                                if (!Clay__disableCulling && (currentElementBoundingBox.y + yPosition > Clay__layoutDimensions.height)) {
+                                if (!context->disableCulling && (currentElementBoundingBox.y + yPosition > context->layoutDimensions.height)) {
                                     break;
                                 }
                             }
@@ -2746,7 +2820,7 @@ void Clay__CalculateFinalLayout(void) {
                     Clay_Dimensions contentSize = {0,0};
                     if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
                         for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; ++i) {
-                            Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
+                            Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
                             contentSize.width += childElement->dimensions.width;
                             contentSize.height = CLAY__MAX(contentSize.height, childElement->dimensions.height);
                         }
@@ -2760,7 +2834,7 @@ void Clay__CalculateFinalLayout(void) {
                         currentElementTreeNode->nextChildOffset.x += extraSpace;
                     } else {
                         for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; ++i) {
-                            Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
+                            Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
                             contentSize.width = CLAY__MAX(contentSize.width, childElement->dimensions.width);
                             contentSize.height += childElement->dimensions.height;
                         }
@@ -2785,12 +2859,12 @@ void Clay__CalculateFinalLayout(void) {
                 if (Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER)) {
                     closeScrollElement = true;
                     Clay_ScrollElementConfig *scrollConfig = Clay__FindElementConfigWithType(currentElement, CLAY__ELEMENT_CONFIG_TYPE_SCROLL_CONTAINER).scrollElementConfig;
-                    for (int32_t i = 0; i < Clay__scrollContainerDatas.length; i++) {
-                        Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&Clay__scrollContainerDatas, i);
+                    for (int32_t i = 0; i < context->scrollContainerDatas.length; i++) {
+                        Clay__ScrollContainerDataInternal *mapping = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
                         if (mapping->layoutElement == currentElement) {
                             if (scrollConfig->horizontal) { scrollOffset.x = mapping->scrollPosition.x; }
                             if (scrollConfig->vertical) { scrollOffset.y = mapping->scrollPosition.y; }
-                            if (Clay__externalScrollHandlingEnabled) {
+                            if (context->externalScrollHandlingEnabled) {
                                 scrollOffset = CLAY__INIT(Clay_Vector2) CLAY__DEFAULT_STRUCT;
                             }
                             break;
@@ -2817,7 +2891,7 @@ void Clay__CalculateFinalLayout(void) {
                             Clay_Vector2 borderOffset = { (float)layoutConfig->padding.x, (float)layoutConfig->padding.y };
                             if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
                                 for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; ++i) {
-                                    Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
+                                    Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
                                     if (i > 0) {
                                         Clay__AddRenderCommand(CLAY__INIT(Clay_RenderCommand) {
                                             .boundingBox = { currentElementBoundingBox.x + borderOffset.x + scrollOffset.x, currentElementBoundingBox.y + scrollOffset.y, (float)borderConfig->betweenChildren.width, currentElement->dimensions.height },
@@ -2830,7 +2904,7 @@ void Clay__CalculateFinalLayout(void) {
                                 }
                             } else {
                                 for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; ++i) {
-                                    Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
+                                    Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
                                     if (i > 0) {
                                         Clay__AddRenderCommand(CLAY__INIT(Clay_RenderCommand) {
                                                 .boundingBox = { currentElementBoundingBox.x + scrollOffset.x, currentElementBoundingBox.y + borderOffset.y + scrollOffset.y, currentElement->dimensions.width, (float)borderConfig->betweenChildren.width },
@@ -2861,7 +2935,7 @@ void Clay__CalculateFinalLayout(void) {
             if (!Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_TEXT)) {
                 dfsBuffer.length += currentElement->childrenOrTextContent.children.length;
                 for (int32_t i = 0; i < currentElement->childrenOrTextContent.children.length; ++i) {
-                    Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
+                    Clay_LayoutElement *childElement = Clay_LayoutElementArray_Get(&context->layoutElements, currentElement->childrenOrTextContent.children.elements[i]);
                     // Alignment along non layout axis
                     if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
                         currentElementTreeNode->nextChildOffset.y = currentElement->layoutConfig->padding.y;
@@ -2893,7 +2967,7 @@ void Clay__CalculateFinalLayout(void) {
                         .position = { childPosition.x, childPosition.y },
                         .nextChildOffset = { .x = (float)childElement->layoutConfig->padding.x, .y = (float)childElement->layoutConfig->padding.y },
                     };
-                    Clay__treeNodeVisited.internalArray[newNodeIndex] = false;
+                    context->treeNodeVisited.internalArray[newNodeIndex] = false;
 
                     // Update parent offsets
                     if (layoutConfig->layoutDirection == CLAY_LEFT_TO_RIGHT) {
@@ -2912,37 +2986,40 @@ void Clay__CalculateFinalLayout(void) {
 }
 
 void Clay__AttachId(Clay_ElementId elementId) {
-    if (Clay__booleanWarnings.maxElementsExceeded) {
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->booleanWarnings.maxElementsExceeded) {
         return;
     }
     Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
     openLayoutElement->id = elementId.id;
     Clay__AddHashMapItem(elementId, openLayoutElement);
-    Clay__StringArray_Add(&Clay__layoutElementIdStrings, elementId.stringId);
+    Clay__StringArray_Add(&context->layoutElementIdStrings, elementId.stringId);
 }
 
 void Clay__AttachLayoutConfig(Clay_LayoutConfig *config) {
-    if (Clay__booleanWarnings.maxElementsExceeded) {
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->booleanWarnings.maxElementsExceeded) {
         return;
     }
     Clay__GetOpenLayoutElement()->layoutConfig = config;
 }
 void Clay__AttachElementConfig(Clay_ElementConfigUnion config, Clay__ElementConfigType type) {
-    if (Clay__booleanWarnings.maxElementsExceeded) {
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->booleanWarnings.maxElementsExceeded) {
         return;
     }
     Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
     openLayoutElement->elementConfigs.length++;
-    Clay__ElementConfigArray_Add(&Clay__elementConfigBuffer, CLAY__INIT(Clay_ElementConfig) { .type = type, .config = config });
+    Clay__ElementConfigArray_Add(&context->elementConfigBuffer, CLAY__INIT(Clay_ElementConfig) { .type = type, .config = config });
 }
-Clay_LayoutConfig * Clay__StoreLayoutConfig(Clay_LayoutConfig config) {  return Clay__booleanWarnings.maxElementsExceeded ? &CLAY_LAYOUT_DEFAULT : Clay__LayoutConfigArray_Add(&Clay__layoutConfigs, config); }
-Clay_RectangleElementConfig * Clay__StoreRectangleElementConfig(Clay_RectangleElementConfig config) {  return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__RECTANGLE_ELEMENT_CONFIG_DEFAULT : Clay__RectangleElementConfigArray_Add(&Clay__rectangleElementConfigs, config); }
-Clay_TextElementConfig * Clay__StoreTextElementConfig(Clay_TextElementConfig config) {  return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__TEXT_ELEMENT_CONFIG_DEFAULT : Clay__TextElementConfigArray_Add(&Clay__textElementConfigs, config); }
-Clay_ImageElementConfig * Clay__StoreImageElementConfig(Clay_ImageElementConfig config) {  return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__IMAGE_ELEMENT_CONFIG_DEFAULT : Clay__ImageElementConfigArray_Add(&Clay__imageElementConfigs, config); }
-Clay_FloatingElementConfig * Clay__StoreFloatingElementConfig(Clay_FloatingElementConfig config) {  return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__FLOATING_ELEMENT_CONFIG_DEFAULT : Clay__FloatingElementConfigArray_Add(&Clay__floatingElementConfigs, config); }
-Clay_CustomElementConfig * Clay__StoreCustomElementConfig(Clay_CustomElementConfig config) {  return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__CUSTOM_ELEMENT_CONFIG_DEFAULT : Clay__CustomElementConfigArray_Add(&Clay__customElementConfigs, config); }
-Clay_ScrollElementConfig * Clay__StoreScrollElementConfig(Clay_ScrollElementConfig config) {  return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__SCROLL_ELEMENT_CONFIG_DEFAULT : Clay__ScrollElementConfigArray_Add(&Clay__scrollElementConfigs, config); }
-Clay_BorderElementConfig * Clay__StoreBorderElementConfig(Clay_BorderElementConfig config) {  return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__BORDER_ELEMENT_CONFIG_DEFAULT : Clay__BorderElementConfigArray_Add(&Clay__borderElementConfigs, config); }
+Clay_LayoutConfig * Clay__StoreLayoutConfig(Clay_LayoutConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &CLAY_LAYOUT_DEFAULT : Clay__LayoutConfigArray_Add(&Clay_GetCurrentContext()->layoutConfigs, config); }
+Clay_RectangleElementConfig * Clay__StoreRectangleElementConfig(Clay_RectangleElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &CLAY__RECTANGLE_ELEMENT_CONFIG_DEFAULT : Clay__RectangleElementConfigArray_Add(&Clay_GetCurrentContext()->rectangleElementConfigs, config); }
+Clay_TextElementConfig * Clay__StoreTextElementConfig(Clay_TextElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &CLAY__TEXT_ELEMENT_CONFIG_DEFAULT : Clay__TextElementConfigArray_Add(&Clay_GetCurrentContext()->textElementConfigs, config); }
+Clay_ImageElementConfig * Clay__StoreImageElementConfig(Clay_ImageElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &CLAY__IMAGE_ELEMENT_CONFIG_DEFAULT : Clay__ImageElementConfigArray_Add(&Clay_GetCurrentContext()->imageElementConfigs, config); }
+Clay_FloatingElementConfig * Clay__StoreFloatingElementConfig(Clay_FloatingElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &CLAY__FLOATING_ELEMENT_CONFIG_DEFAULT : Clay__FloatingElementConfigArray_Add(&Clay_GetCurrentContext()->floatingElementConfigs, config); }
+Clay_CustomElementConfig * Clay__StoreCustomElementConfig(Clay_CustomElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &CLAY__CUSTOM_ELEMENT_CONFIG_DEFAULT : Clay__CustomElementConfigArray_Add(&Clay_GetCurrentContext()->customElementConfigs, config); }
+Clay_ScrollElementConfig * Clay__StoreScrollElementConfig(Clay_ScrollElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &CLAY__SCROLL_ELEMENT_CONFIG_DEFAULT : Clay__ScrollElementConfigArray_Add(&Clay_GetCurrentContext()->scrollElementConfigs, config); }
+Clay_BorderElementConfig * Clay__StoreBorderElementConfig(Clay_BorderElementConfig config) {  return Clay_GetCurrentContext()->booleanWarnings.maxElementsExceeded ? &CLAY__BORDER_ELEMENT_CONFIG_DEFAULT : Clay__BorderElementConfigArray_Add(&Clay_GetCurrentContext()->borderElementConfigs, config); }
 
 #pragma region DebugTools
 Clay_Color CLAY__DEBUGVIEW_COLOR_1 = {58, 56, 52, 255};
@@ -2982,7 +3059,8 @@ CLAY__TYPEDEF(Clay__RenderDebugLayoutData, struct {
 
 // Returns row count
 Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialRootsLength, int32_t highlightedRowIndex) {
-    Clay__int32_tArray dfsBuffer = Clay__reusableElementIndexBuffer;
+    Clay_Context* context = Clay_GetCurrentContext();
+    Clay__int32_tArray dfsBuffer = context->reusableElementIndexBuffer;
     Clay__DebugView_ScrollViewItemLayoutConfig = CLAY__INIT(Clay_LayoutConfig) { .sizing = { .height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT) }, .childGap = 6, .childAlignment = { .y = CLAY_ALIGN_Y_CENTER }};
     Clay__RenderDebugLayoutData layoutData = CLAY__DEFAULT_STRUCT;
 
@@ -2990,9 +3068,9 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
 
     for (int32_t rootIndex = 0; rootIndex < initialRootsLength; ++rootIndex) {
         dfsBuffer.length = 0;
-        Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&Clay__layoutElementTreeRoots, rootIndex);
+        Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&context->layoutElementTreeRoots, rootIndex);
         Clay__int32_tArray_Add(&dfsBuffer, (int32_t)root->layoutElementIndex);
-        Clay__treeNodeVisited.internalArray[0] = false;
+        context->treeNodeVisited.internalArray[0] = false;
         if (rootIndex > 0) {
             CLAY(CLAY_IDI("Clay__DebugView_EmptyRowOuter", rootIndex), CLAY_LAYOUT({ .sizing = {.width = CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT)}, .padding = {CLAY__DEBUGVIEW_INDENT_WIDTH / 2, 0} })) {
                 CLAY(CLAY_IDI("Clay__DebugView_EmptyRow", rootIndex), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), .height = CLAY_SIZING_FIXED((float)CLAY__DEBUGVIEW_ROW_HEIGHT) }}), CLAY_BORDER({ .top = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 } })) {}
@@ -3001,8 +3079,8 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
         }
         while (dfsBuffer.length > 0) {
             int32_t currentElementIndex = Clay__int32_tArray_Get(&dfsBuffer, (int)dfsBuffer.length - 1);
-            Clay_LayoutElement *currentElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, (int)currentElementIndex);
-            if (Clay__treeNodeVisited.internalArray[dfsBuffer.length - 1]) {
+            Clay_LayoutElement *currentElement = Clay_LayoutElementArray_Get(&context->layoutElements, (int)currentElementIndex);
+            if (context->treeNodeVisited.internalArray[dfsBuffer.length - 1]) {
                 if (!Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_TEXT) && currentElement->childrenOrTextContent.children.length > 0) {
                     Clay__CloseElement();
                     Clay__CloseElement();
@@ -3013,16 +3091,16 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
             }
 
             if (highlightedRowIndex == layoutData.rowCount) {
-                if (Clay__pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
-                    Clay__debugSelectedElementId = currentElement->id;
+                if (context->pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
+                    context->debugSelectedElementId = currentElement->id;
                 }
                 highlightedElementId = currentElement->id;
             }
 
-            Clay__treeNodeVisited.internalArray[dfsBuffer.length - 1] = true;
+            context->treeNodeVisited.internalArray[dfsBuffer.length - 1] = true;
             Clay_LayoutElementHashMapItem *currentElementData = Clay__GetHashMapItem(currentElement->id);
             bool offscreen = Clay__ElementIsOffscreen(&currentElementData->boundingBox);
-            if (Clay__debugSelectedElementId == currentElement->id) {
+            if (context->debugSelectedElementId == currentElement->id) {
                 layoutData.selectedElementRowIndex = layoutData.rowCount;
             }
             CLAY(CLAY_IDI("Clay__DebugView_ElementOuter", currentElement->id), Clay__AttachLayoutConfig(&Clay__DebugView_ScrollViewItemLayoutConfig)) {
@@ -3052,7 +3130,7 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
                         }
                     }
                 }
-                Clay_String idString = Clay__layoutElementIdStrings.internalArray[currentElementIndex];
+                Clay_String idString = context->layoutElementIdStrings.internalArray[currentElementIndex];
                 if (idString.length > 0) {
                     CLAY_TEXT(idString, offscreen ? CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16 }) : &Clay__DebugView_TextNameConfig);
                 }
@@ -3098,16 +3176,16 @@ Clay__RenderDebugLayoutData Clay__RenderDebugLayoutElementsList(int32_t initialR
             if (!(Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_TEXT) || (currentElementData && currentElementData->debugData->collapsed))) {
                 for (int32_t i = currentElement->childrenOrTextContent.children.length - 1; i >= 0; --i) {
                     Clay__int32_tArray_Add(&dfsBuffer, currentElement->childrenOrTextContent.children.elements[i]);
-                    Clay__treeNodeVisited.internalArray[dfsBuffer.length - 1] = false; // TODO needs to be ranged checked
+                    context->treeNodeVisited.internalArray[dfsBuffer.length - 1] = false; // TODO needs to be ranged checked
                 }
             }
         }
     }
 
-    if (Clay__pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
+    if (context->pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
         Clay_ElementId collapseButtonId = Clay__HashString(CLAY_STRING("Clay__DebugView_CollapseElement"), 0, 0);
-        for (int32_t i = (int)Clay__pointerOverIds.length - 1; i >= 0; i--) {
-            Clay_ElementId *elementId = Clay__ElementIdArray_Get(&Clay__pointerOverIds, i);
+        for (int32_t i = (int)context->pointerOverIds.length - 1; i >= 0; i--) {
+            Clay_ElementId *elementId = Clay__ElementIdArray_Get(&context->pointerOverIds, i);
             if (elementId->baseId == collapseButtonId.baseId) {
                 Clay_LayoutElementHashMapItem *highlightedItem = Clay__GetHashMapItem(elementId->offset);
                 highlightedItem->debugData->collapsed = !highlightedItem->debugData->collapsed;
@@ -3206,49 +3284,51 @@ void Clay__RenderDebugViewBorder(int32_t index, Clay_Border border, Clay_TextEle
 }
 
 void HandleDebugViewCloseButtonInteraction(Clay_ElementId elementId, Clay_PointerData pointerInfo, intptr_t userData) {
+    Clay_Context* context = Clay_GetCurrentContext();
     (void) elementId; (void) pointerInfo; (void) userData;
     if (pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
-        Clay__debugModeEnabled = false;
+        context->debugModeEnabled = false;
     }
 }
 
-void Clay__RenderDebugView(void) {
+void Clay__RenderDebugView() {
+    Clay_Context* context = Clay_GetCurrentContext();
     Clay_ElementId closeButtonId = Clay__HashString(CLAY_STRING("Clay__DebugViewTopHeaderCloseButtonOuter"), 0, 0);
-    if (Clay__pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
-        for (int32_t i = 0; i < Clay__pointerOverIds.length; ++i) {
-            Clay_ElementId *elementId = Clay__ElementIdArray_Get(&Clay__pointerOverIds, i);
+    if (context->pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
+        for (int32_t i = 0; i < context->pointerOverIds.length; ++i) {
+            Clay_ElementId *elementId = Clay__ElementIdArray_Get(&context->pointerOverIds, i);
             if (elementId->id == closeButtonId.id) {
-                Clay__debugModeEnabled = false;
+                context->debugModeEnabled = false;
                 return;
             }
         }
     }
 
-    uint32_t initialRootsLength = Clay__layoutElementTreeRoots.length;
-    uint32_t initialElementsLength = Clay__layoutElements.length;
+    uint32_t initialRootsLength = context->layoutElementTreeRoots.length;
+    uint32_t initialElementsLength = context->layoutElements.length;
     Clay_TextElementConfig *infoTextConfig = CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_4, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE });
     Clay_TextElementConfig *infoTitleConfig = CLAY_TEXT_CONFIG({ .textColor = CLAY__DEBUGVIEW_COLOR_3, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE });
     Clay_ElementId scrollId = Clay__HashString(CLAY_STRING("Clay__DebugViewOuterScrollPane"), 0, 0);
     float scrollYOffset = 0;
-    for (int32_t i = 0; i < Clay__scrollContainerDatas.length; ++i) {
-        Clay__ScrollContainerDataInternal *scrollContainerData = Clay__ScrollContainerDataInternalArray_Get(&Clay__scrollContainerDatas, i);
+    for (int32_t i = 0; i < context->scrollContainerDatas.length; ++i) {
+        Clay__ScrollContainerDataInternal *scrollContainerData = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
         if (scrollContainerData->elementId == scrollId.id) {
-            if (!Clay__externalScrollHandlingEnabled) {
+            if (!context->externalScrollHandlingEnabled) {
                 scrollYOffset = scrollContainerData->scrollPosition.y;
             }
             break;
         }
     }
-    int32_t highlightedRow = Clay__pointerInfo.position.y < Clay__layoutDimensions.height - 300
-            ? (int32_t)((Clay__pointerInfo.position.y - scrollYOffset) / (float)CLAY__DEBUGVIEW_ROW_HEIGHT) - 1
+    int32_t highlightedRow = context->pointerInfo.position.y < context->layoutDimensions.height - 300
+            ? (int32_t)((context->pointerInfo.position.y - scrollYOffset) / (float)CLAY__DEBUGVIEW_ROW_HEIGHT) - 1
             : -1;
-    if (Clay__pointerInfo.position.x < Clay__layoutDimensions.width - (float)Clay__debugViewWidth) {
+    if (context->pointerInfo.position.x < context->layoutDimensions.width - (float)Clay__debugViewWidth) {
         highlightedRow = -1;
     }
     Clay__RenderDebugLayoutData layoutData = CLAY__DEFAULT_STRUCT;
     CLAY(CLAY_ID("Clay__DebugView"),
         CLAY_FLOATING({ .parentId = Clay__HashString(CLAY_STRING("Clay__RootContainer"), 0, 0).id, .attachment = { .element = CLAY_ATTACH_POINT_LEFT_CENTER, .parent = CLAY_ATTACH_POINT_RIGHT_CENTER }}),
-        CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED((float)Clay__debugViewWidth) , CLAY_SIZING_FIXED(Clay__layoutDimensions.height) }, .layoutDirection = CLAY_TOP_TO_BOTTOM }),
+        CLAY_LAYOUT({ .sizing = { CLAY_SIZING_FIXED((float)Clay__debugViewWidth) , CLAY_SIZING_FIXED(context->layoutDimensions.height) }, .layoutDirection = CLAY_TOP_TO_BOTTOM }),
         CLAY_BORDER({ .bottom = { .width = 1, .color = CLAY__DEBUGVIEW_COLOR_3 }})
     ) {
         CLAY(CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_2 })) {
@@ -3290,8 +3370,8 @@ void Clay__RenderDebugView(void) {
             }
         }
         CLAY(CLAY_LAYOUT({ .sizing = {.width = CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), .height = CLAY_SIZING_FIXED(1)} }), CLAY_RECTANGLE({ .color = CLAY__DEBUGVIEW_COLOR_3 })) {}
-        if (Clay__debugSelectedElementId != 0) {
-            Clay_LayoutElementHashMapItem *selectedItem = Clay__GetHashMapItem(Clay__debugSelectedElementId);
+        if (context->debugSelectedElementId != 0) {
+            Clay_LayoutElementHashMapItem *selectedItem = Clay__GetHashMapItem(context->debugSelectedElementId);
             CLAY(
                 CLAY_SCROLL({ .vertical = true }),
                 CLAY_LAYOUT({ .sizing = {CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), CLAY_SIZING_FIXED(300)}, .layoutDirection = CLAY_TOP_TO_BOTTOM }),
@@ -3516,9 +3596,9 @@ void Clay__RenderDebugView(void) {
                     CLAY_TEXT(CLAY_STRING("Warnings"), warningConfig);
                 }
                 CLAY(CLAY_ID("Clay__DebugViewWarningsTopBorder"), CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(CLAY__DEFAULT_STRUCT), .height = CLAY_SIZING_FIXED(1)} }), CLAY_RECTANGLE({ .color = {200, 200, 200, 255} })) {}
-                int32_t previousWarningsLength = (int)Clay_warnings.length;
+                int32_t previousWarningsLength = (int)context->warnings.length;
                 for (int32_t i = 0; i < previousWarningsLength; i++) {
-                    Clay__Warning warning = Clay_warnings.internalArray[i];
+                    Clay__Warning warning = context->warnings.internalArray[i];
                     CLAY(CLAY_IDI("Clay__DebugViewWarningItem", i), CLAY_LAYOUT({ .sizing = {.height = CLAY_SIZING_FIXED(CLAY__DEBUGVIEW_ROW_HEIGHT)}, .padding = {CLAY__DEBUGVIEW_OUTER_PADDING, 0}, .childGap = 8, .childAlignment = {.y = CLAY_ALIGN_Y_CENTER} })) {
                         CLAY_TEXT(warning.baseMessage, warningConfig);
                         if (warning.dynamicMessage.length > 0) {
@@ -3532,11 +3612,21 @@ void Clay__RenderDebugView(void) {
 }
 #pragma endregion
 
+uint32_t Clay__debugViewWidth = 400;
+Clay_Color Clay__debugViewHighlightColor = { 168, 66, 28, 100 };
+
 // PUBLIC API FROM HERE ---------------------------------------
 
 CLAY_WASM_EXPORT("Clay_MinMemorySize")
-uint32_t Clay_MinMemorySize(void) {
-    Clay_Arena fakeArena = { .capacity = SIZE_MAX };
+uint32_t Clay_MinMemorySize() {
+    Clay_Context fakeContext = {};
+    Clay_Arena fakeArena = {
+        .maxElementCount = Clay__nextInitMaxElementCount,
+        .maxMeasureTextCacheWordCount = Clay__nextInitMaxMeasureTextCacheWordCount,
+        .capacity = SIZE_MAX,
+        .memory = (char*)&fakeContext,
+    };
+    Clay__Context_Allocate_Arena(&fakeArena);
     Clay__InitializePersistentMemory(&fakeArena);
     Clay__InitializeEphemeralMemory(&fakeArena);
     return fakeArena.nextAllocation;
@@ -3562,30 +3652,31 @@ void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)
 
 CLAY_WASM_EXPORT("Clay_SetLayoutDimensions")
 void Clay_SetLayoutDimensions(Clay_Dimensions dimensions) {
-    Clay__layoutDimensions = dimensions;
+    Clay_GetCurrentContext()->layoutDimensions = dimensions;
 }
 
 CLAY_WASM_EXPORT("Clay_SetPointerState")
 void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) {
-    if (Clay__booleanWarnings.maxElementsExceeded) {
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->booleanWarnings.maxElementsExceeded) {
         return;
     }
-    Clay__pointerInfo.position = position;
-    Clay__pointerOverIds.length = 0;
-    Clay__int32_tArray dfsBuffer = Clay__layoutElementChildrenBuffer;
-    for (int32_t rootIndex = Clay__layoutElementTreeRoots.length - 1; rootIndex >= 0; --rootIndex) {
+    context->pointerInfo.position = position;
+    context->pointerOverIds.length = 0;
+    Clay__int32_tArray dfsBuffer = context->layoutElementChildrenBuffer;
+    for (int32_t rootIndex = context->layoutElementTreeRoots.length - 1; rootIndex >= 0; --rootIndex) {
         dfsBuffer.length = 0;
-        Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&Clay__layoutElementTreeRoots, rootIndex);
+        Clay__LayoutElementTreeRoot *root = Clay__LayoutElementTreeRootArray_Get(&context->layoutElementTreeRoots, rootIndex);
         Clay__int32_tArray_Add(&dfsBuffer, (int32_t)root->layoutElementIndex);
-        Clay__treeNodeVisited.internalArray[0] = false;
+        context->treeNodeVisited.internalArray[0] = false;
         bool found = false;
         while (dfsBuffer.length > 0) {
-            if (Clay__treeNodeVisited.internalArray[dfsBuffer.length - 1]) {
+            if (context->treeNodeVisited.internalArray[dfsBuffer.length - 1]) {
                 dfsBuffer.length--;
                 continue;
             }
-            Clay__treeNodeVisited.internalArray[dfsBuffer.length - 1] = true;
-            Clay_LayoutElement *currentElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, Clay__int32_tArray_Get(&dfsBuffer, (int)dfsBuffer.length - 1));
+            context->treeNodeVisited.internalArray[dfsBuffer.length - 1] = true;
+            Clay_LayoutElement *currentElement = Clay_LayoutElementArray_Get(&context->layoutElements, Clay__int32_tArray_Get(&dfsBuffer, (int)dfsBuffer.length - 1));
             Clay_LayoutElementHashMapItem *mapItem = Clay__GetHashMapItem(currentElement->id); // TODO think of a way around this, maybe the fact that it's essentially a binary tree limits the cost, but the worst case is not great
             Clay_BoundingBox elementBox = mapItem->boundingBox;
             elementBox.x -= root->pointerOffset.x;
@@ -3593,9 +3684,9 @@ void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) {
             if (mapItem) {
                 if ((Clay__PointIsInsideRect(position, elementBox))) {
                     if (mapItem->onHoverFunction) {
-                        mapItem->onHoverFunction(mapItem->elementId, Clay__pointerInfo, mapItem->hoverFunctionUserData);
+                        mapItem->onHoverFunction(mapItem->elementId, context->pointerInfo, mapItem->hoverFunctionUserData);
                     }
-                    Clay__ElementIdArray_Add(&Clay__pointerOverIds, mapItem->elementId);
+                    Clay__ElementIdArray_Add(&context->pointerOverIds, mapItem->elementId);
                     found = true;
                 }
                 if (Clay__ElementHasConfig(currentElement, CLAY__ELEMENT_CONFIG_TYPE_TEXT)) {
@@ -3604,14 +3695,14 @@ void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) {
                 }
                 for (int32_t i = currentElement->childrenOrTextContent.children.length - 1; i >= 0; --i) {
                     Clay__int32_tArray_Add(&dfsBuffer, currentElement->childrenOrTextContent.children.elements[i]);
-                    Clay__treeNodeVisited.internalArray[dfsBuffer.length - 1] = false; // TODO needs to be ranged checked
+                    context->treeNodeVisited.internalArray[dfsBuffer.length - 1] = false; // TODO needs to be ranged checked
                 }
             } else {
                 dfsBuffer.length--;
             }
         }
 
-        Clay_LayoutElement *rootElement = Clay_LayoutElementArray_Get(&Clay__layoutElements, root->layoutElementIndex);
+        Clay_LayoutElement *rootElement = Clay_LayoutElementArray_Get(&context->layoutElements, root->layoutElementIndex);
         if (found && Clay__ElementHasConfig(rootElement, CLAY__ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER) &&
                 Clay__FindElementConfigWithType(rootElement, CLAY__ELEMENT_CONFIG_TYPE_FLOATING_CONTAINER).floatingElementConfig->pointerCaptureMode == CLAY_POINTER_CAPTURE_MODE_CAPTURE) {
             break;
@@ -3619,55 +3710,75 @@ void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) {
     }
 
     if (isPointerDown) {
-        if (Clay__pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
-            Clay__pointerInfo.state = CLAY_POINTER_DATA_PRESSED;
-        } else if (Clay__pointerInfo.state != CLAY_POINTER_DATA_PRESSED) {
-            Clay__pointerInfo.state = CLAY_POINTER_DATA_PRESSED_THIS_FRAME;
+        if (context->pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME) {
+            context->pointerInfo.state = CLAY_POINTER_DATA_PRESSED;
+        } else if (context->pointerInfo.state != CLAY_POINTER_DATA_PRESSED) {
+            context->pointerInfo.state = CLAY_POINTER_DATA_PRESSED_THIS_FRAME;
         }
     } else {
-        if (Clay__pointerInfo.state == CLAY_POINTER_DATA_RELEASED_THIS_FRAME) {
-            Clay__pointerInfo.state = CLAY_POINTER_DATA_RELEASED;
-        } else if (Clay__pointerInfo.state != CLAY_POINTER_DATA_RELEASED)  {
-            Clay__pointerInfo.state = CLAY_POINTER_DATA_RELEASED_THIS_FRAME;
+        if (context->pointerInfo.state == CLAY_POINTER_DATA_RELEASED_THIS_FRAME) {
+            context->pointerInfo.state = CLAY_POINTER_DATA_RELEASED;
+        } else if (context->pointerInfo.state != CLAY_POINTER_DATA_RELEASED)  {
+            context->pointerInfo.state = CLAY_POINTER_DATA_RELEASED_THIS_FRAME;
         }
     }
 }
 
 CLAY_WASM_EXPORT("Clay_Initialize")
-void Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler) {
-    Clay__internalArena = arena;
-    Clay__InitializePersistentMemory(&Clay__internalArena);
-    Clay__InitializeEphemeralMemory(&Clay__internalArena);
-    for (int32_t i = 0; i < Clay__layoutElementsHashMap.capacity; ++i) {
-        Clay__layoutElementsHashMap.internalArray[i] = -1;
+Clay_Context* Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler) {
+    arena.maxElementCount = Clay__nextInitMaxElementCount;
+    arena.maxMeasureTextCacheWordCount = Clay__nextInitMaxMeasureTextCacheWordCount;
+    Clay_Context* context = Clay__Context_Allocate_Arena(&arena);
+    if (context == NULL)
+    {
+        return NULL;
     }
-    for (int32_t i = 0; i < Clay__measureTextHashMap.capacity; ++i) {
-        Clay__measureTextHashMap.internalArray[i] = 0;
+    Clay_SetCurrentContext(context);
+    context->internalArena = arena;
+    Clay__InitializePersistentMemory(&context->internalArena);
+    Clay__InitializeEphemeralMemory(&context->internalArena);
+    for (int32_t i = 0; i < context->layoutElementsHashMap.capacity; ++i) {
+        context->layoutElementsHashMap.internalArray[i] = -1;
     }
-    Clay__measureTextHashMapInternal.length = 1; // Reserve the 0 value to mean "no next element"
-    Clay__layoutDimensions = layoutDimensions;
+    for (int32_t i = 0; i < context->measureTextHashMap.capacity; ++i) {
+        context->measureTextHashMap.internalArray[i] = 0;
+    }
+    context->measureTextHashMapInternal.length = 1; // Reserve the 0 value to mean "no next element"
+    context->layoutDimensions = layoutDimensions;
     if (errorHandler.errorHandlerFunction) {
-        Clay__errorHandler = errorHandler;
+        arena.context->errorHandler = errorHandler;
     }
+    return context;
+}
+
+CLAY_WASM_EXPORT("Clay_GetCurrentContext")
+Clay_Context* Clay_GetCurrentContext() {
+    return Clay__currentContext;
+}
+
+CLAY_WASM_EXPORT("Clay_SetCurrentContext")
+void Clay_SetCurrentContext(Clay_Context* context) {
+    Clay__currentContext = context;
 }
 
 CLAY_WASM_EXPORT("Clay_UpdateScrollContainers")
 void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime) {
-    bool isPointerActive = enableDragScrolling && (Clay__pointerInfo.state == CLAY_POINTER_DATA_PRESSED || Clay__pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME);
+    Clay_Context* context = Clay_GetCurrentContext();
+    bool isPointerActive = enableDragScrolling && (context->pointerInfo.state == CLAY_POINTER_DATA_PRESSED || context->pointerInfo.state == CLAY_POINTER_DATA_PRESSED_THIS_FRAME);
     // Don't apply scroll events to ancestors of the inner element
     int32_t highestPriorityElementIndex = -1;
     Clay__ScrollContainerDataInternal *highestPriorityScrollData = CLAY__NULL;
-    for (int32_t i = 0; i < Clay__scrollContainerDatas.length; i++) {
-        Clay__ScrollContainerDataInternal *scrollData = Clay__ScrollContainerDataInternalArray_Get(&Clay__scrollContainerDatas, i);
+    for (int32_t i = 0; i < context->scrollContainerDatas.length; i++) {
+        Clay__ScrollContainerDataInternal *scrollData = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
         if (!scrollData->openThisFrame) {
-            Clay__ScrollContainerDataInternalArray_RemoveSwapback(&Clay__scrollContainerDatas, i);
+            Clay__ScrollContainerDataInternalArray_RemoveSwapback(&context->scrollContainerDatas, i);
             continue;
         }
         scrollData->openThisFrame = false;
         Clay_LayoutElementHashMapItem *hashMapItem = Clay__GetHashMapItem(scrollData->elementId);
         // Element isn't rendered this frame but scroll offset has been retained
         if (!hashMapItem) {
-            Clay__ScrollContainerDataInternalArray_RemoveSwapback(&Clay__scrollContainerDatas, i);
+            Clay__ScrollContainerDataInternalArray_RemoveSwapback(&context->scrollContainerDatas, i);
             continue;
         }
 
@@ -3704,8 +3815,8 @@ void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDe
         }
         scrollData->scrollPosition.y = CLAY__MIN(CLAY__MAX(scrollData->scrollPosition.y, -(CLAY__MAX(scrollData->contentSize.height - scrollData->layoutElement->dimensions.height, 0))), 0);
 
-        for (int32_t j = 0; j < Clay__pointerOverIds.length; ++j) { // TODO n & m are small here but this being n*m gives me the creeps
-            if (scrollData->layoutElement->id == Clay__ElementIdArray_Get(&Clay__pointerOverIds, j)->id) {
+        for (int32_t j = 0; j < context->pointerOverIds.length; ++j) { // TODO n & m are small here but this being n*m gives me the creeps
+            if (scrollData->layoutElement->id == Clay__ElementIdArray_Get(&context->pointerOverIds, j)->id) {
                 highestPriorityElementIndex = j;
                 highestPriorityScrollData = scrollData;
             }
@@ -3728,26 +3839,26 @@ void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDe
         if (isPointerActive) {
             highestPriorityScrollData->scrollMomentum = CLAY__INIT(Clay_Vector2)CLAY__DEFAULT_STRUCT;
             if (!highestPriorityScrollData->pointerScrollActive) {
-                highestPriorityScrollData->pointerOrigin = Clay__pointerInfo.position;
+                highestPriorityScrollData->pointerOrigin = context->pointerInfo.position;
                 highestPriorityScrollData->scrollOrigin = highestPriorityScrollData->scrollPosition;
                 highestPriorityScrollData->pointerScrollActive = true;
             } else {
                 float scrollDeltaX = 0, scrollDeltaY = 0;
                 if (canScrollHorizontally) {
                     float oldXScrollPosition = highestPriorityScrollData->scrollPosition.x;
-                    highestPriorityScrollData->scrollPosition.x = highestPriorityScrollData->scrollOrigin.x + (Clay__pointerInfo.position.x - highestPriorityScrollData->pointerOrigin.x);
+                    highestPriorityScrollData->scrollPosition.x = highestPriorityScrollData->scrollOrigin.x + (context->pointerInfo.position.x - highestPriorityScrollData->pointerOrigin.x);
                     highestPriorityScrollData->scrollPosition.x = CLAY__MAX(CLAY__MIN(highestPriorityScrollData->scrollPosition.x, 0), -(highestPriorityScrollData->contentSize.width - highestPriorityScrollData->boundingBox.width));
                     scrollDeltaX = highestPriorityScrollData->scrollPosition.x - oldXScrollPosition;
                 }
                 if (canScrollVertically) {
                     float oldYScrollPosition = highestPriorityScrollData->scrollPosition.y;
-                    highestPriorityScrollData->scrollPosition.y = highestPriorityScrollData->scrollOrigin.y + (Clay__pointerInfo.position.y - highestPriorityScrollData->pointerOrigin.y);
+                    highestPriorityScrollData->scrollPosition.y = highestPriorityScrollData->scrollOrigin.y + (context->pointerInfo.position.y - highestPriorityScrollData->pointerOrigin.y);
                     highestPriorityScrollData->scrollPosition.y = CLAY__MAX(CLAY__MIN(highestPriorityScrollData->scrollPosition.y, 0), -(highestPriorityScrollData->contentSize.height - highestPriorityScrollData->boundingBox.height));
                     scrollDeltaY = highestPriorityScrollData->scrollPosition.y - oldYScrollPosition;
                 }
                 if (scrollDeltaX > -0.1f && scrollDeltaX < 0.1f && scrollDeltaY > -0.1f && scrollDeltaY < 0.1f && highestPriorityScrollData->momentumTime > 0.15f) {
                     highestPriorityScrollData->momentumTime = 0;
-                    highestPriorityScrollData->pointerOrigin = Clay__pointerInfo.position;
+                    highestPriorityScrollData->pointerOrigin = context->pointerInfo.position;
                     highestPriorityScrollData->scrollOrigin = highestPriorityScrollData->scrollPosition;
                 } else {
                      highestPriorityScrollData->momentumTime += deltaTime;
@@ -3765,42 +3876,44 @@ void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDe
 }
 
 CLAY_WASM_EXPORT("Clay_BeginLayout")
-void Clay_BeginLayout(void) {
-    Clay__InitializeEphemeralMemory(&Clay__internalArena);
-    Clay__generation++;
-    Clay__dynamicElementIndex = 0;
+void Clay_BeginLayout() {
+    Clay_Context* context = Clay_GetCurrentContext();
+    Clay__InitializeEphemeralMemory(&context->internalArena);
+    context->generation++;
+    context->dynamicElementIndex = 0;
     // Set up the root container that covers the entire window
-    Clay_Dimensions rootDimensions = {Clay__layoutDimensions.width, Clay__layoutDimensions.height};
-    if (Clay__debugModeEnabled) {
+    Clay_Dimensions rootDimensions = {context->layoutDimensions.width, context->layoutDimensions.height};
+    if (context->debugModeEnabled) {
         rootDimensions.width -= (float)Clay__debugViewWidth;
     }
-    Clay__booleanWarnings.maxElementsExceeded = false;
-    Clay__booleanWarnings.maxTextMeasureCacheExceeded = false;
-    Clay__booleanWarnings.maxRenderCommandsExceeded = false;
+    context->booleanWarnings.maxElementsExceeded = false;
+    context->booleanWarnings.maxTextMeasureCacheExceeded = false;
+    context->booleanWarnings.maxRenderCommandsExceeded = false;
     Clay__OpenElement();
     CLAY_ID("Clay__RootContainer");
     CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED((rootDimensions.width)), CLAY_SIZING_FIXED(rootDimensions.height)} });
     Clay__ElementPostConfiguration();
-    Clay__int32_tArray_Add(&Clay__openLayoutElementStack, 0);
-    Clay__LayoutElementTreeRootArray_Add(&Clay__layoutElementTreeRoots, CLAY__INIT(Clay__LayoutElementTreeRoot) { .layoutElementIndex = 0 });
+    Clay__int32_tArray_Add(&context->openLayoutElementStack, 0);
+    Clay__LayoutElementTreeRootArray_Add(&context->layoutElementTreeRoots, CLAY__INIT(Clay__LayoutElementTreeRoot) { .layoutElementIndex = 0 });
 }
 
 Clay_TextElementConfig Clay__DebugView_ErrorTextConfig = {.textColor = {255, 0, 0, 255}, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE };
 
 CLAY_WASM_EXPORT("Clay_EndLayout")
-Clay_RenderCommandArray Clay_EndLayout(void) {
+Clay_RenderCommandArray Clay_EndLayout() {
+    Clay_Context* context = Clay_GetCurrentContext();
     Clay__CloseElement();
-    if (Clay__debugModeEnabled) {
-        Clay__warningsEnabled = false;
+    if (context->debugModeEnabled) {
+        context->warningsEnabled = false;
         Clay__RenderDebugView();
-        Clay__warningsEnabled = true;
+        context->warningsEnabled = true;
     }
-    if (Clay__booleanWarnings.maxElementsExceeded) {
-        Clay__AddRenderCommand(CLAY__INIT(Clay_RenderCommand ) { .boundingBox = { Clay__layoutDimensions.width / 2 - 59 * 4, Clay__layoutDimensions.height / 2, 0, 0 },  .config = { .textElementConfig = &Clay__DebugView_ErrorTextConfig }, .text = CLAY_STRING("Clay Error: Layout elements exceeded Clay__maxElementCount"), .commandType = CLAY_RENDER_COMMAND_TYPE_TEXT });
+    if (context->booleanWarnings.maxElementsExceeded) {
+        Clay__AddRenderCommand(CLAY__INIT(Clay_RenderCommand ) { .boundingBox = { context->layoutDimensions.width / 2 - 59 * 4, context->layoutDimensions.height / 2, 0, 0 },  .config = { .textElementConfig = &Clay__DebugView_ErrorTextConfig }, .text = CLAY_STRING("Clay Error: Layout elements exceeded Clay__maxElementCount"), .commandType = CLAY_RENDER_COMMAND_TYPE_TEXT });
     } else {
         Clay__CalculateFinalLayout();
     }
-    return Clay__renderCommands;
+    return context->renderCommands;
 }
 
 CLAY_WASM_EXPORT("Clay_GetElementId")
@@ -3813,8 +3926,9 @@ Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index)
     return Clay__HashString(idString, index, 0);
 }
 
-bool Clay_Hovered(void) {
-    if (Clay__booleanWarnings.maxElementsExceeded) {
+bool Clay_Hovered() {
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->booleanWarnings.maxElementsExceeded) {
         return false;
     }
     Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
@@ -3822,8 +3936,8 @@ bool Clay_Hovered(void) {
     if (openLayoutElement->id == 0) {
         Clay__GenerateIdForAnonymousElement(openLayoutElement);
     }
-    for (int32_t i = 0; i < Clay__pointerOverIds.length; ++i) {
-        if (Clay__ElementIdArray_Get(&Clay__pointerOverIds, i)->id == openLayoutElement->id) {
+    for (int32_t i = 0; i < context->pointerOverIds.length; ++i) {
+        if (Clay__ElementIdArray_Get(&context->pointerOverIds, i)->id == openLayoutElement->id) {
             return true;
         }
     }
@@ -3831,7 +3945,8 @@ bool Clay_Hovered(void) {
 }
 
 void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerInfo, intptr_t userData), intptr_t userData) {
-    if (Clay__booleanWarnings.maxElementsExceeded) {
+    Clay_Context* context = Clay_GetCurrentContext();
+    if (context->booleanWarnings.maxElementsExceeded) {
         return;
     }
     Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
@@ -3845,8 +3960,9 @@ void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_Pointer
 
 CLAY_WASM_EXPORT("Clay_PointerOver")
 bool Clay_PointerOver(Clay_ElementId elementId) { // TODO return priority for separating multiple results
-    for (int32_t i = 0; i < Clay__pointerOverIds.length; ++i) {
-        if (Clay__ElementIdArray_Get(&Clay__pointerOverIds, i)->id == elementId.id) {
+    Clay_Context* context = Clay_GetCurrentContext();
+    for (int32_t i = 0; i < context->pointerOverIds.length; ++i) {
+        if (Clay__ElementIdArray_Get(&context->pointerOverIds, i)->id == elementId.id) {
             return true;
         }
     }
@@ -3855,8 +3971,9 @@ bool Clay_PointerOver(Clay_ElementId elementId) { // TODO return priority for se
 
 CLAY_WASM_EXPORT("Clay_GetScrollContainerData")
 Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id) {
-    for (int32_t i = 0; i < Clay__scrollContainerDatas.length; ++i) {
-        Clay__ScrollContainerDataInternal *scrollContainerData = Clay__ScrollContainerDataInternalArray_Get(&Clay__scrollContainerDatas, i);
+    Clay_Context* context = Clay_GetCurrentContext();
+    for (int32_t i = 0; i < context->scrollContainerDatas.length; ++i) {
+        Clay__ScrollContainerDataInternal *scrollContainerData = Clay__ScrollContainerDataInternalArray_Get(&context->scrollContainerDatas, i);
         if (scrollContainerData->elementId == id.id) {
             return CLAY__INIT(Clay_ScrollContainerData) {
                 .scrollPosition = &scrollContainerData->scrollPosition,
@@ -3872,32 +3989,36 @@ Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id) {
 
 CLAY_WASM_EXPORT("Clay_SetDebugModeEnabled")
 void Clay_SetDebugModeEnabled(bool enabled) {
-    Clay__debugModeEnabled = enabled;
+    Clay_Context* context = Clay_GetCurrentContext();
+    context->debugModeEnabled = enabled;
 }
 
 CLAY_WASM_EXPORT("Clay_IsDebugModeEnabled")
-bool Clay_IsDebugModeEnabled(void) {
-    return Clay__debugModeEnabled;
+bool Clay_IsDebugModeEnabled() {
+    Clay_Context* context = Clay_GetCurrentContext();
+    return context->debugModeEnabled;
 }
 
 CLAY_WASM_EXPORT("Clay_SetCullingEnabled")
 void Clay_SetCullingEnabled(bool enabled) {
-    Clay__disableCulling = !enabled;
+    Clay_Context* context = Clay_GetCurrentContext();
+    context->disableCulling = !enabled;
 }
 
 CLAY_WASM_EXPORT("Clay_SetExternalScrollHandlingEnabled")
 void Clay_SetExternalScrollHandlingEnabled(bool enabled) {
-    Clay__externalScrollHandlingEnabled = enabled;
+    Clay_Context* context = Clay_GetCurrentContext();
+    context->externalScrollHandlingEnabled = enabled;
 }
 
 CLAY_WASM_EXPORT("Clay_SetMaxElementCount")
 void Clay_SetMaxElementCount(int32_t maxElementCount) {
-    Clay__maxElementCount = maxElementCount;
+    Clay__nextInitMaxElementCount = maxElementCount;
 }
 
 CLAY_WASM_EXPORT("Clay_SetMaxMeasureTextCacheWordCount")
 void Clay_SetMaxMeasureTextCacheWordCount(int32_t maxMeasureTextCacheWordCount) {
-    Clay__maxMeasureTextCacheWordCount = maxMeasureTextCacheWordCount;
+    Clay__nextInitMaxMeasureTextCacheWordCount = maxMeasureTextCacheWordCount;
 }
 
 #endif // CLAY_IMPLEMENTATION