diff --git a/bindings/odin/README.md b/bindings/odin/README.md
index e69de29..30404ce 100644
--- a/bindings/odin/README.md
+++ b/bindings/odin/README.md
@@ -0,0 +1 @@
+TODO
\ No newline at end of file
diff --git a/bindings/odin/clay-odin/clay.odin b/bindings/odin/clay-odin/clay.odin
index d705fda..c3ef0dd 100644
--- a/bindings/odin/clay-odin/clay.odin
+++ b/bindings/odin/clay-odin/clay.odin
@@ -5,429 +5,423 @@ import "core:strings"
 foreign import Clay "clay.a"
 
 String :: struct {
-	length: c.int,
-	chars:  [^]c.char,
+    length: c.int,
+    chars:  [^]c.char,
 }
 
 Vector2 :: struct {
-	x: c.float,
-	y: c.float,
+    x: c.float,
+    y: c.float,
 }
 
 Dimensions :: struct {
-	width:  c.float,
-	height: c.float,
+    width:  c.float,
+    height: c.float,
 }
 
 Arena :: struct {
-	label:          String,
-	nextAllocation: c.uint64_t,
-	capacity:       c.uint64_t,
-	memory:         [^]c.char,
+    label:          String,
+    nextAllocation: c.uint64_t,
+    capacity:       c.uint64_t,
+    memory:         [^]c.char,
 }
 
 BoundingBox :: struct {
-	x:      c.float,
-	y:      c.float,
-	width:  c.float,
-	height: c.float,
+    x:      c.float,
+    y:      c.float,
+    width:  c.float,
+    height: c.float,
 }
 
 Color :: struct {
-	r: c.float,
-	g: c.float,
-	b: c.float,
-	a: c.float,
+    r: c.float,
+    g: c.float,
+    b: c.float,
+    a: c.float,
 }
 
 CornerRadius :: struct {
-	topLeft:     c.float,
-	topRight:    c.float,
-	bottomLeft:  c.float,
-	bottomRight: c.float,
+    topLeft:     c.float,
+    topRight:    c.float,
+    bottomLeft:  c.float,
+    bottomRight: c.float,
 }
 
 BorderData :: struct {
-	width: c.uint32_t,
-	color: Color,
+    width: c.uint32_t,
+    color: Color,
 }
 
 RenderCommandType :: enum u8 {
-	None,
-	Rectangle,
-	Border,
-	Text,
-	Image,
-	ScissorStart,
-	ScissorEnd,
-	Custom,
+    None,
+    Rectangle,
+    Border,
+    Text,
+    Image,
+    ScissorStart,
+    ScissorEnd,
+    Custom,
 }
 
 RectangleElementConfig :: struct {
-	color:        Color,
-	cornerRadius: CornerRadius,
+    color:        Color,
+    cornerRadius: CornerRadius,
 }
 
 TextElementConfig :: struct {
-	textColor:     Color,
-	fontId:        c.uint16_t,
-	fontSize:      c.uint16_t,
-	letterSpacing: c.uint16_t,
-	lineSpacing:   c.uint16_t,
+    textColor:     Color,
+    fontId:        c.uint16_t,
+    fontSize:      c.uint16_t,
+    letterSpacing: c.uint16_t,
+    lineSpacing:   c.uint16_t,
 }
 
 ImageElementConfig :: struct {
-	imageData:        rawptr,
-	sourceDimensions: Dimensions,
+    imageData:        rawptr,
+    sourceDimensions: Dimensions,
 }
 
 CustomElementConfig :: struct {
-	customData: rawptr,
+    customData: rawptr,
 }
 
 BorderElementConfig :: struct {
-	left:            BorderData,
-	right:           BorderData,
-	top:             BorderData,
-	bottom:          BorderData,
-	betweenChildren: BorderData,
-	cornerRadius:    CornerRadius,
+    left:            BorderData,
+    right:           BorderData,
+    top:             BorderData,
+    bottom:          BorderData,
+    betweenChildren: BorderData,
+    cornerRadius:    CornerRadius,
 }
 
 ScrollElementConfig :: struct {
-	horizontal: c.bool,
-	vertical:   c.bool,
+    horizontal: c.bool,
+    vertical:   c.bool,
 }
 
 FloatingAttachPointType :: enum u8 {
-	LEFT_TOP,
-	LEFT_CENTER,
-	LEFT_BOTTOM,
-	CENTER_TOP,
-	CENTER_CENTER,
-	CENTER_BOTTOM,
-	RIGHT_TOP,
-	RIGHT_CENTER,
-	RIGHT_BOTTOM,
+    LEFT_TOP,
+    LEFT_CENTER,
+    LEFT_BOTTOM,
+    CENTER_TOP,
+    CENTER_CENTER,
+    CENTER_BOTTOM,
+    RIGHT_TOP,
+    RIGHT_CENTER,
+    RIGHT_BOTTOM,
 }
 
 FloatingAttachPoints :: struct {
-	element: FloatingAttachPointType,
-	parent:  FloatingAttachPointType,
+    element: FloatingAttachPointType,
+    parent:  FloatingAttachPointType,
 }
 
 FloatingElementConfig :: struct {
-	offset:     Vector2,
-	expand:     Dimensions,
-	zIndex:     c.uint16_t,
-	parentId:   c.uint32_t,
-	attachment: FloatingAttachPoints,
+    offset:     Vector2,
+    expand:     Dimensions,
+    zIndex:     c.uint16_t,
+    parentId:   c.uint32_t,
+    attachment: FloatingAttachPoints,
 }
 
 ElementConfigUnion :: struct #raw_union {
-	rectangleElementConfig: ^RectangleElementConfig,
-	textElementConfig:      ^TextElementConfig,
-	imageElementConfig:     ^ImageElementConfig,
-	customElementConfig:    ^CustomElementConfig,
-	borderElementConfig:    ^BorderElementConfig,
+    rectangleElementConfig: ^RectangleElementConfig,
+    textElementConfig:      ^TextElementConfig,
+    imageElementConfig:     ^ImageElementConfig,
+    customElementConfig:    ^CustomElementConfig,
+    borderElementConfig:    ^BorderElementConfig,
 }
 
 RenderCommand :: struct {
-	boundingBox: BoundingBox,
-	config:      ElementConfigUnion,
-	text:        String,
-	id:          c.uint32_t,
-	commandType: RenderCommandType,
+    boundingBox: BoundingBox,
+    config:      ElementConfigUnion,
+    text:        String,
+    id:          c.uint32_t,
+    commandType: RenderCommandType,
 }
 
 ScrollContainerData :: struct {
-	// Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout.
-	// Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
-	scrollPosition:            ^Vector2,
-	scrollContainerDimensions: Dimensions,
-	contentDimensions:         Dimensions,
-	config:                    ScrollElementConfig,
-	// Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
-	found:                     c.bool,
+    // Note: This is a pointer to the real internal scroll position, mutating it may cause a change in final layout.
+    // Intended for use with external functionality that modifies scroll position, such as scroll bars or auto scrolling.
+    scrollPosition:            ^Vector2,
+    scrollContainerDimensions: Dimensions,
+    contentDimensions:         Dimensions,
+    config:                    ScrollElementConfig,
+    // Indicates whether an actual scroll container matched the provided ID or if the default struct was returned.
+    found:                     c.bool,
 }
 
 SizingType :: enum u8 {
-	FIT,
-	GROW,
-	PERCENT,
+    FIT,
+    GROW,
+    PERCENT,
+}
+
+SizingConstraintsMinMax :: struct {
+    min: c.float,
+    max: c.float,
+}
+
+SizingConstraints :: struct #raw_union {
+    sizeMinMax:  SizingConstraintsMinMax,
+    sizePercent: c.float,
 }
 
 SizingAxis :: struct {
-	// Note: `min` is used for CLAY_SIZING_PERCENT, slightly different to clay.h due to lack of C anonymous unions
-	min:  c.float,
-	max:  c.float,
-	type: SizingType,
+    // Note: `min` is used for CLAY_SIZING_PERCENT, slightly different to clay.h due to lack of C anonymous unions
+    constraints: SizingConstraints,
+    type:        SizingType,
 }
 
 Sizing :: struct {
-	width:  SizingAxis,
-	height: SizingAxis,
+    width:  SizingAxis,
+    height: SizingAxis,
 }
 
 Padding :: struct {
-	x: c.uint16_t,
-	y: c.uint16_t,
+    x: c.uint16_t,
+    y: c.uint16_t,
 }
 
 LayoutDirection :: enum u8 {
-	LEFT_TO_RIGHT,
-	TOP_TO_BOTTOM,
+    LEFT_TO_RIGHT,
+    TOP_TO_BOTTOM,
 }
 
 LayoutAlignmentX :: enum u8 {
-	LEFT,
-	RIGHT,
-	CENTER,
+    LEFT,
+    RIGHT,
+    CENTER,
 }
 
 LayoutAlignmentY :: enum u8 {
-	TOP,
-	BOTTOM,
-	CENTER,
+    TOP,
+    BOTTOM,
+    CENTER,
 }
 
 ChildAlignment :: struct {
-	x: LayoutAlignmentX,
-	y: LayoutAlignmentY,
+    x: LayoutAlignmentX,
+    y: LayoutAlignmentY,
 }
 
 LayoutConfig :: struct {
-	sizing:          Sizing,
-	padding:         Padding,
-	childGap:        c.uint16_t,
-	layoutDirection: LayoutDirection,
-	childAlignment:  ChildAlignment,
+    sizing:          Sizing,
+    padding:         Padding,
+    childGap:        c.uint16_t,
+    layoutDirection: LayoutDirection,
+    childAlignment:  ChildAlignment,
 }
 
 ClayArray :: struct($type: typeid) {
-	capacity:      c.uint32_t,
-	length:        c.uint32_t,
-	internalArray: [^]type,
+    capacity:      c.uint32_t,
+    length:        c.uint32_t,
+    internalArray: [^]type,
 }
 
+@(link_prefix = "Clay_")
 foreign Clay {
-	Clay_MinMemorySize :: proc() -> c.uint32_t ---
-	Clay_CreateArenaWithCapacityAndMemory :: proc(capacity: c.uint32_t, offset: [^]u8) -> Arena ---
-	Clay_SetPointerPosition :: proc(position: Vector2) ---
-	Clay_Initialize :: proc(arena: Arena) ---
-	Clay_UpdateScrollContainers :: proc(isPointerActive: c.bool, scrollDelta: Vector2, deltaTime: c.float) ---
-	Clay_BeginLayout :: proc(screenWidth: c.int, screenHeight: c.int) ---
-	Clay_EndLayout :: proc(screenWidth: c.int, screenHeight: c.int) -> ClayArray(RenderCommand) ---
-	Clay_PointerOver :: proc(id: c.uint32_t) -> c.bool ---
-	Clay_GetScrollContainerData :: proc(id: c.uint32_t) -> ScrollContainerData ---
-	Clay_SetMeasureTextFunction :: proc(measureTextFunction: proc(text: [^]String, config: [^]TextElementConfig) -> Dimensions) ---
-	Clay__OpenContainerElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) ---
-	Clay__OpenRectangleElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) ---
-	Clay__OpenTextElement :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) ---
-	Clay__OpenImageElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) ---
-	Clay__OpenScrollElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ScrollElementConfig) ---
-	Clay__OpenFloatingElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^FloatingElementConfig) ---
-	Clay__OpenBorderElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^BorderElementConfig) ---
-	Clay__OpenCustomElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^CustomElementConfig) ---
-	Clay__CloseElementWithChildren :: proc() ---
-	Clay__CloseScrollElement :: proc() ---
-	Clay__CloseFloatingElement :: proc() ---
-	Clay__layoutConfigs: ClayArray(LayoutConfig)
-	Clay__LayoutConfigArray_Add :: proc(array: ^ClayArray(LayoutConfig), config: LayoutConfig) -> ^LayoutConfig ---
-	Clay__rectangleElementConfigs: ClayArray(RectangleElementConfig)
-	Clay__RectangleElementConfigArray_Add :: proc(array: ^ClayArray(RectangleElementConfig), config: RectangleElementConfig) -> ^RectangleElementConfig ---
-	Clay__textElementConfigs: ClayArray(TextElementConfig)
-	Clay__TextElementConfigArray_Add :: proc(array: ^ClayArray(TextElementConfig), config: TextElementConfig) -> ^TextElementConfig ---
-	Clay__imageElementConfigs: ClayArray(ImageElementConfig)
-	Clay__ImageElementConfigArray_Add :: proc(array: ^ClayArray(ImageElementConfig), config: ImageElementConfig) -> ^ImageElementConfig ---
-	Clay__floatingElementConfigs: ClayArray(FloatingElementConfig)
-	Clay__FloatingElementConfigArray_Add :: proc(array: ^ClayArray(FloatingElementConfig), config: FloatingElementConfig) -> ^FloatingElementConfig ---
-	Clay__customElementConfigs: ClayArray(CustomElementConfig)
-	Clay__CustomElementConfigArray_Add :: proc(array: ^ClayArray(CustomElementConfig), config: CustomElementConfig) -> ^CustomElementConfig ---
-	Clay__scrollElementConfigs: ClayArray(ScrollElementConfig)
-	Clay__ScrollElementConfigArray_Add :: proc(array: ^ClayArray(ScrollElementConfig), config: ScrollElementConfig) -> ^ScrollElementConfig ---
-	Clay__borderElementConfigs: ClayArray(BorderElementConfig)
-	Clay__BorderElementConfigArray_Add :: proc(array: ^ClayArray(BorderElementConfig), config: BorderElementConfig) -> ^BorderElementConfig ---
-	Clay__HashString :: proc(toHash: String, index: c.uint32_t) -> c.uint32_t ---
+    MinMemorySize :: proc() -> c.uint32_t ---
+    CreateArenaWithCapacityAndMemory :: proc(capacity: c.uint32_t, offset: [^]u8) -> Arena ---
+    SetPointerPosition :: proc(position: Vector2) ---
+    Initialize :: proc(arena: Arena) ---
+    UpdateScrollContainers :: proc(isPointerActive: c.bool, scrollDelta: Vector2, deltaTime: c.float) ---
+    BeginLayout :: proc(screenWidth: c.int, screenHeight: c.int) ---
+    EndLayout :: proc(screenWidth: c.int, screenHeight: c.int) -> ClayArray(RenderCommand) ---
+    PointerOver :: proc(id: c.uint32_t) -> c.bool ---
+    GetScrollContainerData :: proc(id: c.uint32_t) -> ScrollContainerData ---
+    SetMeasureTextFunction :: proc(measureTextFunction: proc(text: ^String, config: ^TextElementConfig) -> Dimensions) ---
+    RenderCommandArray_Get :: proc(array: ^ClayArray(RenderCommand), index: c.int32_t) -> ^RenderCommand ---
+    @(private)
+    _OpenContainerElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) ---
+    @(private)
+    _OpenRectangleElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) ---
+    @(private)
+    _OpenTextElement :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) ---
+    @(private)
+    _OpenImageElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) ---
+    @(private)
+    _OpenScrollElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ScrollElementConfig) ---
+    @(private)
+    _OpenFloatingElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^FloatingElementConfig) ---
+    @(private)
+    _OpenBorderElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^BorderElementConfig) ---
+    @(private)
+    _OpenCustomElement :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^CustomElementConfig) ---
+    @(private)
+    _CloseElementWithChildren :: proc() ---
+    @(private)
+    _CloseScrollElement :: proc() ---
+    @(private)
+    _CloseFloatingElement :: proc() ---
+    @(private)
+    _layoutConfigs: ClayArray(LayoutConfig)
+    @(private)
+    _LayoutConfigArray_Add :: proc(array: ^ClayArray(LayoutConfig), config: LayoutConfig) -> ^LayoutConfig ---
+    @(private)
+    _rectangleElementConfigs: ClayArray(RectangleElementConfig)
+    @(private)
+    _RectangleElementConfigArray_Add :: proc(array: ^ClayArray(RectangleElementConfig), config: RectangleElementConfig) -> ^RectangleElementConfig ---
+    @(private)
+    _textElementConfigs: ClayArray(TextElementConfig)
+    @(private)
+    _TextElementConfigArray_Add :: proc(array: ^ClayArray(TextElementConfig), config: TextElementConfig) -> ^TextElementConfig ---
+    @(private)
+    _imageElementConfigs: ClayArray(ImageElementConfig)
+    @(private)
+    _ImageElementConfigArray_Add :: proc(array: ^ClayArray(ImageElementConfig), config: ImageElementConfig) -> ^ImageElementConfig ---
+    @(private)
+    _floatingElementConfigs: ClayArray(FloatingElementConfig)
+    @(private)
+    _FloatingElementConfigArray_Add :: proc(array: ^ClayArray(FloatingElementConfig), config: FloatingElementConfig) -> ^FloatingElementConfig ---
+    @(private)
+    _customElementConfigs: ClayArray(CustomElementConfig)
+    @(private)
+    _CustomElementConfigArray_Add :: proc(array: ^ClayArray(CustomElementConfig), config: CustomElementConfig) -> ^CustomElementConfig ---
+    @(private)
+    _scrollElementConfigs: ClayArray(ScrollElementConfig)
+    @(private)
+    _ScrollElementConfigArray_Add :: proc(array: ^ClayArray(ScrollElementConfig), config: ScrollElementConfig) -> ^ScrollElementConfig ---
+    @(private)
+    _borderElementConfigs: ClayArray(BorderElementConfig)
+    @(private)
+    _BorderElementConfigArray_Add :: proc(array: ^ClayArray(BorderElementConfig), config: BorderElementConfig) -> ^BorderElementConfig ---
+    @(private)
+    _HashString :: proc(toHash: String, index: c.uint32_t) -> c.uint32_t ---
 }
 
-MinMemorySize :: proc() -> c.uint32_t {
-	return Clay_MinMemorySize()
-}
 
-CreateArenaWithCapacityAndMemory :: proc(capacity: c.uint32_t, offset: [^]u8) -> Arena {
-	return Clay_CreateArenaWithCapacityAndMemory(capacity, offset)
-}
-
-SetPointerPosition :: proc(position: Vector2) {
-	Clay_SetPointerPosition(position)
-}
-
-Initialize :: proc(arena: Arena) {
-	Clay_Initialize(arena)
-}
-
-UpdateScrollContainers :: proc(isPointerActive: c.bool, scrollDelta: Vector2, deltaTime: c.float) {
-	Clay_UpdateScrollContainers(isPointerActive, scrollDelta, deltaTime)
-}
-
-BeginLayout :: proc(screenWidth: c.int, screenHeight: c.int) {
-	Clay_BeginLayout(screenWidth, screenHeight)
-}
-
-EndLayout :: proc(screenWidth: c.int, screenHeight: c.int) -> ClayArray(RenderCommand) {
-	return Clay_EndLayout(screenWidth, screenHeight)
-}
-
-PointerOver :: proc(id: c.uint32_t) -> c.bool {
-	return Clay_PointerOver(id)
-}
-
-GetScrollContainerData :: proc(id: c.uint32_t) -> ScrollContainerData {
-	return Clay_GetScrollContainerData(id)
-}
-
-@(deferred_none = Clay__CloseElementWithChildren)
+@(require_results, deferred_none = _CloseElementWithChildren)
 Container :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig) -> bool {
-	Clay__OpenContainerElement(id, layoutConfig)
-	return true
+    _OpenContainerElement(id, layoutConfig)
+    return true
 }
 
-@(deferred_none = Clay__CloseElementWithChildren)
-Rectangle :: proc(
-	id: c.uint32_t,
-	layoutConfig: ^LayoutConfig,
-	rectangleConfig: ^RectangleElementConfig,
-) -> bool {
-	Clay__OpenRectangleElement(id, layoutConfig, rectangleConfig)
-	return true
+@(require_results, deferred_none = _CloseElementWithChildren)
+Rectangle :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, rectangleConfig: ^RectangleElementConfig) -> bool {
+    _OpenRectangleElement(id, layoutConfig, rectangleConfig)
+    return true
 }
 
 Text :: proc(id: c.uint32_t, text: String, textConfig: ^TextElementConfig) -> bool {
-	Clay__OpenTextElement(id, text, textConfig)
-	return true
+    _OpenTextElement(id, text, textConfig)
+    return true
 }
 
-@(deferred_none = Clay__CloseElementWithChildren)
-Image :: proc(
-	id: c.uint32_t,
-	layoutConfig: ^LayoutConfig,
-	imageConfig: ^ImageElementConfig,
-) -> bool {
-	Clay__OpenImageElement(id, layoutConfig, imageConfig)
-	return true
+@(require_results, deferred_none = _CloseElementWithChildren)
+Image :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, imageConfig: ^ImageElementConfig) -> bool {
+    _OpenImageElement(id, layoutConfig, imageConfig)
+    return true
 }
 
-@(deferred_none = Clay__CloseScrollElement)
-Scroll :: proc(
-	id: c.uint32_t,
-	layoutConfig: ^LayoutConfig,
-	scrollConfig: ^ScrollElementConfig,
-) -> bool {
-	Clay__OpenScrollElement(id, layoutConfig, scrollConfig)
-	return true
+@(require_results, deferred_none = _CloseScrollElement)
+Scroll :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, scrollConfig: ^ScrollElementConfig) -> bool {
+    _OpenScrollElement(id, layoutConfig, scrollConfig)
+    return true
 }
 
-@(deferred_none = Clay__CloseFloatingElement)
-Floating :: proc(
-	id: c.uint32_t,
-	layoutConfig: ^LayoutConfig,
-	floatingConfig: ^FloatingElementConfig,
-) -> bool {
-	Clay__OpenFloatingElement(id, layoutConfig, floatingConfig)
-	return true
+@(require_results, deferred_none = _CloseFloatingElement)
+Floating :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, floatingConfig: ^FloatingElementConfig) -> bool {
+    _OpenFloatingElement(id, layoutConfig, floatingConfig)
+    return true
 }
 
-@(deferred_none = Clay__CloseElementWithChildren)
-Border :: proc(
-	id: c.uint32_t,
-	layoutConfig: ^LayoutConfig,
-	borderConfig: ^BorderElementConfig,
-) -> bool {
-	Clay__OpenBorderElement(id, layoutConfig, borderConfig)
-	return true
+@(require_results, deferred_none = _CloseElementWithChildren)
+Border :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, borderConfig: ^BorderElementConfig) -> bool {
+    _OpenBorderElement(id, layoutConfig, borderConfig)
+    return true
 }
 
-@(deferred_none = Clay__CloseElementWithChildren)
-Custom :: proc(
-	id: c.uint32_t,
-	layoutConfig: ^LayoutConfig,
-	customConfig: ^CustomElementConfig,
-) -> bool {
-	Clay__OpenCustomElement(id, layoutConfig, customConfig)
-	return true
+@(require_results, deferred_none = _CloseElementWithChildren)
+Custom :: proc(id: c.uint32_t, layoutConfig: ^LayoutConfig, customConfig: ^CustomElementConfig) -> bool {
+    _OpenCustomElement(id, layoutConfig, customConfig)
+    return true
 }
 
 Layout :: proc(config: LayoutConfig) -> ^LayoutConfig {
-	return Clay__LayoutConfigArray_Add(&Clay__layoutConfigs, config)
+    return _LayoutConfigArray_Add(&_layoutConfigs, config)
 }
 
 RectangleConfig :: proc(config: RectangleElementConfig) -> ^RectangleElementConfig {
-	return Clay__RectangleElementConfigArray_Add(&Clay__rectangleElementConfigs, config)
+    return _RectangleElementConfigArray_Add(&_rectangleElementConfigs, config)
 }
 
 TextConfig :: proc(config: TextElementConfig) -> ^TextElementConfig {
-	return Clay__TextElementConfigArray_Add(&Clay__textElementConfigs, config)
+    return _TextElementConfigArray_Add(&_textElementConfigs, config)
 }
 
 ImageConfig :: proc(config: ImageElementConfig) -> ^ImageElementConfig {
-	return Clay__ImageElementConfigArray_Add(&Clay__imageElementConfigs, config)
+    return _ImageElementConfigArray_Add(&_imageElementConfigs, config)
 }
 
 FloatingConfig :: proc(config: FloatingElementConfig) -> ^FloatingElementConfig {
-	return Clay__FloatingElementConfigArray_Add(&Clay__floatingElementConfigs, config)
+    return _FloatingElementConfigArray_Add(&_floatingElementConfigs, config)
 }
 
 Custom_elementConfig :: proc(config: CustomElementConfig) -> ^CustomElementConfig {
-	return Clay__CustomElementConfigArray_Add(&Clay__customElementConfigs, config)
+    return _CustomElementConfigArray_Add(&_customElementConfigs, config)
 }
 
 ScrollConfig :: proc(config: ScrollElementConfig) -> ^ScrollElementConfig {
-	return Clay__ScrollElementConfigArray_Add(&Clay__scrollElementConfigs, config)
+    return _ScrollElementConfigArray_Add(&_scrollElementConfigs, config)
 }
 
 BorderConfig :: proc(config: BorderElementConfig) -> ^BorderElementConfig {
-	return Clay__BorderElementConfigArray_Add(&Clay__borderElementConfigs, config)
+    return _BorderElementConfigArray_Add(&_borderElementConfigs, config)
 }
 
 BorderConfigOutside :: proc(outsideBorders: BorderData) -> ^BorderElementConfig {
-	return Clay__BorderElementConfigArray_Add(
-		&Clay__borderElementConfigs,
-		(BorderElementConfig) {
-			left = outsideBorders,
-			right = outsideBorders,
-			top = outsideBorders,
-			bottom = outsideBorders,
-		},
-	)
+    return _BorderElementConfigArray_Add(
+        &_borderElementConfigs,
+        (BorderElementConfig){left = outsideBorders, right = outsideBorders, top = outsideBorders, bottom = outsideBorders},
+    )
 }
 
-// BorderConfig_outside_radius :: proc(width, color, radius)  Clay_BorderElementConfigArray_Add(&Clay__borderElementConfigs, (Clay_BorderElementConfig ) { .left = { width, color }, .right = { width, color }, .top = { width, color }, .bottom = { width, color }, .cornerRadius = { radius, radius, radius, radius } })) -> CLAY_BORDER_CONFIG_OUTSIDE_RADIUS
+BorderConfigOutsideRadius :: proc(outsideBorders: BorderData, radius: f32) -> ^BorderElementConfig {
+    return _BorderElementConfigArray_Add(
+        &_borderElementConfigs,
+        (BorderElementConfig){left = outsideBorders, right = outsideBorders, top = outsideBorders, bottom = outsideBorders, cornerRadius = {radius, radius, radius, radius}},
+    )
+}
 
-// BorderConfig_all :: proc(...)  Clay_BorderElementConfigArray_Add(&Clay__borderElementConfigs, (Clay_BorderElementConfig ) { .left = { __VA_ARGS__ }, .right = { __VA_ARGS__ }, .top = { __VA_ARGS__ }, .bottom = { __VA_ARGS__ }, .betweenChildren = { __VA_ARGS__ } })) -> CLAY_BORDER_CONFIG_ALL
+BorderConfigAll :: proc(allBorders: BorderData) -> ^BorderElementConfig {
+    return _BorderElementConfigArray_Add(
+        &_borderElementConfigs,
+        (BorderElementConfig){left = allBorders, right = allBorders, top = allBorders, bottom = allBorders, betweenChildren = allBorders},
+    )
+}
 
-// BorderConfig_all_radius :: proc(width, color, radius)  Clay_BorderElementConfigArray_Add(&Clay__borderElementConfigs, (Clay_BorderElementConfig ) { .left = { __VA_ARGS__ }, .right = { __VA_ARGS__ }, .top = { __VA_ARGS__ }, .bottom = { __VA_ARGS__ }, .betweenChildren = { __VA_ARGS__ }, .cornerRadius = { radius, radius, radius, radius }})) -> CLAY_BORDER_CONFIG_ALL_RADIUS
+BorderConfigAllRadius :: proc(allBorders: BorderData, radius: f32) -> ^BorderElementConfig {
+    return _BorderElementConfigArray_Add(
+        &_borderElementConfigs,
+        (BorderElementConfig){left = allBorders, right = allBorders, top = allBorders, bottom = allBorders, cornerRadius = {radius, radius, radius, radius}},
+    )
+}
 
-// Corner_radius :: proc(radius) (Clay_CornerRadius) { radius, radius, radius, radius }) -> CLAY_CORNER_RADIUS
+SizingFit :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis {
+    return SizingAxis{type = SizingType.FIT, constraints = {sizeMinMax = sizeMinMax}}
+}
 
-// Sizing_fit :: proc(...) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_FIT, .sizeMinMax = (Clay_SizingMinMax) {__VA_ARGS__} }) -> CLAY_SIZING_FIT
+SizingGrow :: proc(sizeMinMax: SizingConstraintsMinMax) -> SizingAxis {
+    return SizingAxis{type = SizingType.GROW, constraints = {sizeMinMax = sizeMinMax}}
+}
 
-// Sizing_grow :: proc(...) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_GROW, .sizeMinMax = (Clay_SizingMinMax) {__VA_ARGS__} }) -> CLAY_SIZING_GROW
+SizingFixed :: proc(size: c.float) -> SizingAxis {
+    return SizingAxis{type = SizingType.FIT, constraints = {sizeMinMax = {size, size}}}
+}
 
-// Sizing_fixed :: proc(fixedSize) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_GROW, .sizeMinMax = { fixedSize, fixedSize } }) -> CLAY_SIZING_FIXED
+SizingPercent :: proc(sizePercent: c.float) -> SizingAxis {
+    return SizingAxis{type = SizingType.PERCENT, constraints = {sizePercent = sizePercent}}
+}
 
-// Sizing_percent :: proc(percentOfParent) (Clay_SizingAxis) { .type = CLAY__SIZING_TYPE_PERCENT, .sizePercent = percentOfParent }) -> CLAY_SIZING_PERCENT
-
-ClayString :: proc(label: string) -> String {
-	return String{chars = raw_data(label), length = cast(c.int)len(label)}
+MakeString :: proc(label: string) -> String {
+    return String{chars = raw_data(label), length = cast(c.int)len(label)}
 }
 
 ID :: proc(label: string) -> c.uint32_t {
-	return Clay__HashString(ClayString(label), 0)
+    return _HashString(MakeString(label), 0)
 }
 
 IDI :: proc(label: string, index: u32) -> c.uint32_t {
-	return Clay__HashString(ClayString(label), index)
+    return _HashString(MakeString(label), index)
 }
-
-// _string_length :: proc(s) ((sizeof(s) / sizeof(s[0])) - sizeof(s[0]))) -> CLAY__STRING_LENGTH
diff --git a/bindings/odin/clay_renderer_raylib.odin b/bindings/odin/clay_renderer_raylib.odin
new file mode 100644
index 0000000..5a01534
--- /dev/null
+++ b/bindings/odin/clay_renderer_raylib.odin
@@ -0,0 +1,224 @@
+package main
+
+import clay "clay-odin"
+import "core:math"
+import "vendor:raylib"
+
+RaylibFont :: struct {
+    fontId: u32,
+    font:   raylib.Font,
+}
+
+clayColorToRaylibColor :: proc(color: clay.Color) -> raylib.Color {
+    return raylib.Color{cast(u8)color.r, cast(u8)color.g, cast(u8)color.b, cast(u8)color.a}
+}
+
+raylibFonts := [10]RaylibFont{}
+
+measureText :: proc "c" (text: ^clay.String, config: ^clay.TextElementConfig) -> clay.Dimensions {
+    // Measure string size for Font
+    textSize: clay.Dimensions = {0, 0}
+
+    maxTextWidth: f32 = 0
+    lineTextWidth: f32 = 0
+
+    textHeight: f32 = cast(f32)config.fontSize
+    fontToUse: raylib.Font = raylibFonts[config.fontId].font
+
+    for i := 0; i < cast(int)text.length; i += 1 {
+        if (text.chars[i] == '\n') {
+            maxTextWidth = math.max(maxTextWidth, lineTextWidth)
+            lineTextWidth = 0
+            continue
+        }
+        index: i32 = cast(i32)text.chars[i] - 32
+        if (fontToUse.glyphs[index].advanceX != 0) {
+            lineTextWidth += cast(f32)fontToUse.glyphs[index].advanceX
+        } else {
+            lineTextWidth += (fontToUse.recs[index].width + cast(f32)fontToUse.glyphs[index].offsetX)
+        }
+    }
+
+    maxTextWidth = math.max(maxTextWidth, lineTextWidth)
+
+    textSize.width = maxTextWidth / 2
+    textSize.height = textHeight
+
+    return textSize
+}
+
+clayRaylibRender :: proc(renderCommands: ^clay.ClayArray(clay.RenderCommand)) {
+    for i := 0; i < cast(int)renderCommands.length; i += 1 {
+        renderCommand: ^clay.RenderCommand = clay.RenderCommandArray_Get(renderCommands, cast(i32)i)
+        boundingBox: clay.BoundingBox = renderCommand.boundingBox
+        switch (renderCommand.commandType) 
+        {
+        case clay.RenderCommandType.None:
+            {
+                break
+            }
+        case clay.RenderCommandType.Text:
+            {
+                // Raylib uses standard C strings so isn't compatible with cheap slices, we need to clone the string to append null terminator
+                text: clay.String = renderCommand.text
+                cloned: []u8 = make([]u8, text.length + 1)
+                copy(cloned[0:text.length], text.chars[0:text.length])
+                cloned[text.length] = 0
+                fontToUse: raylib.Font = raylibFonts[renderCommand.config.textElementConfig.fontId].font
+                raylib.DrawTextEx(
+                    fontToUse,
+                    cstring(raw_data(cloned)),
+                    raylib.Vector2{boundingBox.x, boundingBox.y},
+                    cast(f32)renderCommand.config.textElementConfig.fontSize,
+                    cast(f32)renderCommand.config.textElementConfig.letterSpacing,
+                    clayColorToRaylibColor(renderCommand.config.textElementConfig.textColor),
+                )
+                delete(cloned)
+                break
+            }
+        case clay.RenderCommandType.Image:
+            {
+                imageTexture: ^raylib.Texture2D = cast(^raylib.Texture2D)renderCommand.config.imageElementConfig.imageData
+                raylib.DrawTextureEx(imageTexture^, raylib.Vector2{boundingBox.x, boundingBox.y}, 0, boundingBox.width / cast(f32)imageTexture.width, raylib.WHITE)
+                break
+            }
+        case clay.RenderCommandType.ScissorStart:
+            {
+                raylib.BeginScissorMode(
+                    cast(i32)math.round(boundingBox.x),
+                    cast(i32)math.round(boundingBox.y),
+                    cast(i32)math.round(boundingBox.width),
+                    cast(i32)math.round(boundingBox.height),
+                )
+                break
+            }
+        case clay.RenderCommandType.ScissorEnd:
+            {
+                raylib.EndScissorMode()
+                break
+            }
+        case clay.RenderCommandType.Rectangle:
+            {
+                config: ^clay.RectangleElementConfig = renderCommand.config.rectangleElementConfig
+                if (config.cornerRadius.topLeft > 0) {
+                    radius: f32 = (config.cornerRadius.topLeft * 2) / (boundingBox.width > boundingBox.height ? boundingBox.height : boundingBox.width)
+                    raylib.DrawRectangleRounded(
+                        raylib.Rectangle{boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height},
+                        radius,
+                        8,
+                        clayColorToRaylibColor(config.color),
+                    )
+                } else {
+                    raylib.DrawRectangle(
+                        cast(i32)boundingBox.x,
+                        cast(i32)boundingBox.y,
+                        cast(i32)boundingBox.width,
+                        cast(i32)boundingBox.height,
+                        clayColorToRaylibColor(config.color),
+                    )
+                }
+                break
+            }
+        case clay.RenderCommandType.Border:
+            {
+                config: ^clay.BorderElementConfig = renderCommand.config.borderElementConfig
+                // Left border
+                if (config.left.width > 0) {
+                    raylib.DrawRectangle(
+                        cast(i32)math.round(boundingBox.x),
+                        cast(i32)math.round(boundingBox.y + config.cornerRadius.topLeft),
+                        cast(i32)config.left.width,
+                        cast(i32)math.round(boundingBox.height - config.cornerRadius.topLeft - config.cornerRadius.bottomLeft),
+                        clayColorToRaylibColor(config.left.color),
+                    )
+                }
+                // Right border
+                if (config.right.width > 0) {
+                    raylib.DrawRectangle(
+                        cast(i32)math.round(boundingBox.x + boundingBox.width - cast(f32)config.right.width),
+                        cast(i32)math.round(boundingBox.y + config.cornerRadius.topRight),
+                        cast(i32)config.right.width,
+                        cast(i32)math.round(boundingBox.height - config.cornerRadius.topRight - config.cornerRadius.bottomRight),
+                        clayColorToRaylibColor(config.right.color),
+                    )
+                }
+                // Top border
+                if (config.top.width > 0) {
+                    raylib.DrawRectangle(
+                        cast(i32)math.round(boundingBox.x + config.cornerRadius.topLeft),
+                        cast(i32)math.round(boundingBox.y),
+                        cast(i32)math.round(boundingBox.width - config.cornerRadius.topLeft - config.cornerRadius.topRight),
+                        cast(i32)config.top.width,
+                        clayColorToRaylibColor(config.top.color),
+                    )
+                }
+                // Bottom border
+                if (config.bottom.width > 0) {
+                    raylib.DrawRectangle(
+                        cast(i32)math.round(boundingBox.x + config.cornerRadius.bottomLeft),
+                        cast(i32)math.round(boundingBox.y + boundingBox.height - cast(f32)config.bottom.width),
+                        cast(i32)math.round(boundingBox.width - config.cornerRadius.bottomLeft - config.cornerRadius.bottomRight),
+                        cast(i32)config.bottom.width,
+                        clayColorToRaylibColor(config.bottom.color),
+                    )
+                }
+                if (config.cornerRadius.topLeft > 0) {
+                    raylib.DrawRing(
+                        raylib.Vector2{math.round(boundingBox.x + config.cornerRadius.topLeft), math.round(boundingBox.y + config.cornerRadius.topLeft)},
+                        math.round(config.cornerRadius.topLeft - cast(f32)config.top.width),
+                        config.cornerRadius.topLeft,
+                        180,
+                        270,
+                        10,
+                        clayColorToRaylibColor(config.top.color),
+                    )
+                }
+                if (config.cornerRadius.topRight > 0) {
+                    raylib.DrawRing(
+                        raylib.Vector2{math.round(boundingBox.x + boundingBox.width - config.cornerRadius.topRight), math.round(boundingBox.y + config.cornerRadius.topRight)},
+                        math.round(config.cornerRadius.topRight - cast(f32)config.top.width),
+                        config.cornerRadius.topRight,
+                        270,
+                        360,
+                        10,
+                        clayColorToRaylibColor(config.top.color),
+                    )
+                }
+                if (config.cornerRadius.bottomLeft > 0) {
+                    raylib.DrawRing(
+                        raylib.Vector2 {
+                            math.round(boundingBox.x + config.cornerRadius.bottomLeft),
+                            math.round(boundingBox.y + boundingBox.height - config.cornerRadius.bottomLeft),
+                        },
+                        math.round(config.cornerRadius.bottomLeft - cast(f32)config.top.width),
+                        config.cornerRadius.bottomLeft,
+                        90,
+                        180,
+                        10,
+                        clayColorToRaylibColor(config.bottom.color),
+                    )
+                }
+                if (config.cornerRadius.bottomRight > 0) {
+                    raylib.DrawRing(
+                        raylib.Vector2 {
+                            math.round(boundingBox.x + boundingBox.width - config.cornerRadius.bottomRight),
+                            math.round(boundingBox.y + boundingBox.height - config.cornerRadius.bottomRight),
+                        },
+                        math.round(config.cornerRadius.bottomRight - cast(f32)config.bottom.width),
+                        config.cornerRadius.bottomRight,
+                        0.1,
+                        90,
+                        10,
+                        clayColorToRaylibColor(config.bottom.color),
+                    )
+                }
+                break
+            }
+        case clay.RenderCommandType.Custom:
+            {
+                // Implement custom element rendering here
+                break
+            }
+        }
+    }
+}
diff --git a/bindings/odin/example.odin b/bindings/odin/example.odin
new file mode 100644
index 0000000..fa572a5
--- /dev/null
+++ b/bindings/odin/example.odin
@@ -0,0 +1,54 @@
+package main
+
+import clay "clay-odin"
+import "core:c"
+import "core:fmt"
+import "vendor:raylib"
+
+createLayout :: proc() -> clay.ClayArray(clay.RenderCommand) {
+    clay.BeginLayout(1024, 768)
+    layoutConfig: clay.LayoutConfig = clay.LayoutConfig {
+        sizing = {width = {type = clay.SizingType.GROW}, height = {type = clay.SizingType.GROW}},
+        padding = {16, 16},
+    }
+    rectangleConfig: clay.RectangleElementConfig = clay.RectangleElementConfig {
+        cornerRadius = {topLeft = 5},
+    }
+
+    if clay.Rectangle(
+        clay.ID("Outer Container"),
+        clay.Layout({sizing = {width = {type = clay.SizingType.GROW}, height = {type = clay.SizingType.GROW}}, padding = {16, 16}}),
+        clay.RectangleConfig({cornerRadius = {topLeft = 5}}),
+    ) {
+        if clay.Rectangle(clay.ID("Inner Container"), &layoutConfig, &rectangleConfig) {
+            if clay.Rectangle(clay.ID("percentContainer"), clay.Layout({sizing = {width = clay.SizingPercent(0.5)}}), clay.RectangleConfig({})) {}
+            if clay.Rectangle(clay.ID("growContainer"), clay.Layout({sizing = {width = clay.SizingGrow({max = 200})}}), clay.RectangleConfig({})) {}
+            clay.Text(clay.ID("textfield"), clay.MakeString("Texti"), clay.TextConfig({fontId = 0, fontSize = 24, textColor = {255, 255, 255, 255}}))
+        }
+    }
+
+    return clay.EndLayout(1024, 768)
+}
+
+main :: proc() {
+    minMemorySize: c.uint32_t = clay.MinMemorySize()
+    memory := make([^]u8, minMemorySize)
+    arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, memory)
+    clay.SetMeasureTextFunction(measureText)
+    clay.Initialize(arena)
+
+    raylib.InitWindow(1024, 768, "Raylib Odin Example")
+
+    raylibFonts[0] = RaylibFont {
+        font   = raylib.LoadFontEx("resources/Roboto-Regular.ttf", 32, nil, 0),
+        fontId = 0,
+    }
+    raylib.SetTextureFilter(raylibFonts[0].font.texture, raylib.TextureFilter.TRILINEAR)
+
+    for !raylib.WindowShouldClose() {
+        renderCommands: clay.ClayArray(clay.RenderCommand) = createLayout()
+        raylib.BeginDrawing()
+        clayRaylibRender(&renderCommands)
+        raylib.EndDrawing()
+    }
+}
diff --git a/bindings/odin/main.odin b/bindings/odin/main.odin
deleted file mode 100644
index fd1e403..0000000
--- a/bindings/odin/main.odin
+++ /dev/null
@@ -1,45 +0,0 @@
-package main
-
-import clay "clay-odin"
-import "core:c"
-import "core:fmt"
-
-measureText :: proc(text: [^]clay.String, config: [^]clay.TextElementConfig) -> clay.Dimensions {
-	return clay.Dimensions{20, 20}
-}
-
-main :: proc() {
-	minMemorySize: c.uint32_t = clay.MinMemorySize()
-	memory := make([^]u8, minMemorySize)
-	arena: clay.Arena = clay.CreateArenaWithCapacityAndMemory(minMemorySize, memory)
-	clay.Initialize(arena)
-	clay.BeginLayout(1024, 768)
-	layoutConfig: clay.LayoutConfig = clay.LayoutConfig {
-		sizing = {width = {type = clay.SizingType.GROW}, height = {type = clay.SizingType.GROW}},
-		padding = {16, 16},
-	}
-	rectangleConfig: clay.RectangleElementConfig = clay.RectangleElementConfig {
-		cornerRadius = {topLeft = 5},
-	}
-
-	if clay.Rectangle(
-		clay.ID("Outer Container"),
-		clay.Layout(
-			{
-				sizing = {
-					width = {type = clay.SizingType.GROW},
-					height = {type = clay.SizingType.GROW},
-				},
-				padding = {16, 16},
-			},
-		),
-		clay.RectangleConfig({cornerRadius = {topLeft = 5}}),
-	) {
-		if clay.Rectangle(clay.ID("Inner Container"), &layoutConfig, &rectangleConfig) {
-
-		}
-	}
-
-	renderCommands: clay.ClayArray(clay.RenderCommand) = clay.EndLayout(1024, 768)
-	x: int = 5
-}
diff --git a/bindings/odin/odinfmt.json b/bindings/odin/odinfmt.json
new file mode 100644
index 0000000..ee3d563
--- /dev/null
+++ b/bindings/odin/odinfmt.json
@@ -0,0 +1,6 @@
+{
+	"$schema": "https://raw.githubusercontent.com/DanielGavin/ols/master/misc/odinfmt.schema.json",
+	"character_width": 180,
+	"sort_imports": true,
+	"tabs": false
+}
\ No newline at end of file
diff --git a/bindings/odin/resources/Roboto-Regular.ttf b/bindings/odin/resources/Roboto-Regular.ttf
new file mode 100644
index 0000000..ddf4bfa
Binary files /dev/null and b/bindings/odin/resources/Roboto-Regular.ttf differ