# flexible.Struct - a FlexibleStruct/Array alternative

**URL:** <https://ziggit.dev/t/flexible-struct-a-flexiblestruct-array-alternative/17905>\
**Category:** Showcase\
**Created:** [October 10, 2026, 9:21am UTC](https://ziggit.dev/t/flexible-struct-a-flexiblestruct-array-alternative/17905 "2026-10-10T09:21:35Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Travis](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/bbce88/32.png) [@Travis](https://ziggit.dev/u/Travis)\
**Post date:** [October 10, 2026, 9:21am UTC](https://ziggit.dev/t/flexible-struct-a-flexiblestruct-array-alternative/17905/1 "2026-10-10T09:21:35Z")

</div>

# [flexible.Struct](https://github.com/archaistvolts/flexible-struct/)

Hello. I’m hoping for some feedback on this alternative to the [FlexibleStruct/FlexibleArray pull request](https://codeberg.org/ziglang/zig/pulls/30823). Its similar but adds lots of stuff like a user `Layout` API, size and offset helpers and additions to the Self API (`value(), ptr(), slice(), sliceField(), sliceLen()`).

I haven’t benchmarked it yet 😅 but its designed to be faster than the orignal with flexible fields after Layout fields and sorted by alignment. WIth this, we can simd prefix sum the aligned sizes in constant time. It does trade some possible padding after Layout for this so beware.

I’ve been using it in my toy roaring bitmap project and it seems pretty decent so far. Lots of things I want to do with including moving the repo to Codeberg. So give it a try. We can make small and fast designs with flexible arrays.

I’m hoping for criticism to improve this including the decision to add computed methods (which may be slower than fixed field access) and the additional padding tradeoff. I’m considering turning this into an alternative to the zig FlexibleStruct PR above since it sounds like Andrew is interested in it.

@tristanpemble I’m interested to hear from original author and maybe work together toward getting something merged. Let me know if you have a minute. I’ve also commented on that issue as archaistvolts. Thanks for the original! I love the idea.

* * *

* * *

# [flexible.Struct](https://github.com/archaistvolts/flexible-struct/)

* * *

A single buffer layout library for structs with flexible fields.

# About

User defined `Layout` fields are first in memory with order determined by Zig. Flexible fields are second and sorted by descending alignment. With no padding, flexible offsets can be calculated in constant time (see `calcOffsets()`).

# Features

1. Support all structs: auto, extern, packed
2. Constant time field access.
3. APIs: Layout, Self and bytes. Users can ptrCast between them.
4. Computed fields.
5. LSP cooperation. Avoid created/refified types which break autocomplete.

## Docs

> **[Zig Documentation](https://archaistvolts.github.io/flexible-struct/)**

## Usage

Add a `pub const flexible_array_capacities` decl to your `Layout` which maps flexible array fields to their capacities.

```zig
const Layout = struct {
        capacity: u8,
        flexible: [*]u8 = undefined,
        computed: [*]u8 = undefined,

        pub const flexible_array_capacities = .{
            .flexible = .capacity,
            .computed = .computedLen,
        };

        pub fn computedLen(_: *const @This()) usize {
            return 68;
        }
    };

    const Model = Struct(Layout, .{});
    const initlayout = Layout{ .capacity = 42 };
    var buf: Model.Buf(&initlayout) align(Model.ALIGN) = undefined; // buffer must be aligned
    const model = try Model.initBuffer(&buf, &initlayout);
    try testing.expectEqual(42, model.value(.capacity));
    try testing.expectEqual(42, model.slice(.flexible).len);
    try testing.expectEqual(42, model.asLayout().capacity); // Self <-> Layout
    try testing.expectEqual(42, Model.fromLayout(model.asLayout()).value(.capacity));
    try testing.expectEqual(68, model.slice(.computed).len);
    try testing.expectEqual(136, model.sizeInBytes()); // 24+42+68(~8)=134(~8)=136
}

```

### Supported Zig versions

0.16. 0.17 coming soon.
