I want to make ECS using wasm component model
I can't figure out how to make function which accepts different components (records)
The only approach I see is to use variants:
record a {
a: u32
}
record b {
b: u32
}
variant components {
a(a),
b(b)
}
spawn: func(components: list<components>);
Is there any other way to achieve similar effect (list<components>) without using variants (because of repeated names), something similar to unions (removed in 2023), builder pattern is possible, but not preferred
I think a variant is the best option. It is very likely that a union without some sort of discriminator does not exist, variant makes this explicit and portable across languages. I would assume that name spaces give a way to distinguish the elements of the same name (there might be a limitation of the language binding you are using).
Unions got removed because of security concerns and not being used in practice.
Yeah, unions were removed because many (most?) languages would require awkward-at-best name generation for cases like list<u8>. IMO a little redundancy in the WIT is worth it to make the mappings easier to follow in general.
The only way to store named fields is record, and the only way to have unions is variant. Both of them are named
For example rust can store named fields inside enums
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
Can WIT support something similar to that?
In my opinion this covers most, if not all use cases of unions
For languages which can't support this style in any way, WIT can potentially use A(A) as a fallback
wit doesn't support Rust style named fields inside enums, because the goal of wit is to target many different programming languages, and very few have that capability natively, so they'd have to emulate it with a combination of their variant and record constructions. The goal of wit and wit-bindgen isn't to produce perfect idiomatic code in the language of your choice, and we expect that to produce ideal code in your given language you will need to add some hand-written code on top of the types output by wit-bindgen, or otherwise customize your wit-bindgen
Sorry for misunderstanding. I thought the entire point of WIT is to not write hand-written code and have good enough code generation without compromises (because why even use wit then). I think my use case isn't covered by WIT and I am ready to help with the design of the idea (to the best of my ability)
Are there wit-bindgen methods/separate projects to customize wit generation? Maybe alternatives to wit?
wit is the language which is specified in the component-model standard, wit-bindgen is a generator created by the bytecode alliance that makes bindings from the canonical ABI to bindings for a given language. the two projects are distinct, though the people who contribute to them are often the same - but the spec of wit and components exists separately so that anyone can write their own tools that take the place of wit-bindgen.
the wit language is designed to balance making the best possible bindings in some given language with being accessible to a very wide range of languages, and tries not to unnecessarily privilege some languages over others where possible. We have already had complaints from various users that wit is too rust-like and languages that lack Algebraic Datatypes (ADTs), which rust calls enum, have a harder time using it. so, I personally would be against making wit develop even more language features that are not even specific to ADTs but to a small number of languages's implementations of ADTs.
the alternative approach you could take here is to work on wit-bindgen to make it even more clever when it comes to generating rust bindings. You could add a pass that looks to see if a record definition is only used in variant variations, and then expand those variant variations to use those record fields as named fields, instead of defininig an intermediate record. this would make no difference to either the canonical abi lowering or, likely, to any sort of performance in the Rust, since the representation would be the same and any accesses would inline to the same, but it might make the bindings look more idiomatic if that makes a huge difference to you. my judgement is thats a lot of work for a small benefit, but if it matters to you, you can open issues or PRs on wit-bindgen to discuss or submit an implementation.
I'd suggest an issue or discussion in #wit-bindgen before a PR for major feature changes :slight_smile:
Last updated: Dec 06 2025 at 05:03 UTC