Hi everyone. I'm wondering if there are specific/well-known/standard OCI artifact types that differ WIT interfaces from component implementations. Does anyone know?
At present, AFAIK there is no distinction between an WIT-only component and a WIT + implementation component as far as OCI artifacts types are concerned.
There is only the one media type so far:
https://tag-runtime.cncf.io/wgs/wasm/deliverables/wasm-oci-artifact/
IF you are trying to gather imports/exports AFAICT that information should be present in the metadata if you can retrieve it from the registry, but you need (for example skopeo inspect does not yet support the wasm media type)
IIRC the OCI artifact came into being before we even had WIT-as-components, so I'm not sure that could have happened at the time without some faith and foresight.
That said, sufficiently intelligent proxies or registries can differentiate between a interface-only component and components that contain implementations with a bit of extra work, though I'm not sure if that's a reasonable solution for your use case!
Would you mind sharing a bit more about why you'd want this distinction/what you're trying to do with the distinction? Is knowing interfaces enough? Are you trying to avoid potential waste of bandwidth?
it is entirely possible to extract and then attach the wit as a referrer to the component artifact as well, so as ONLY to pull that metadata without any artifact if it's necessary. but if you are searching for some component in OCI that api hasn't yet been agreed upon......
do you KNOW the component wit you want, or do you NOT know but might examine many?
Thanks Victor and Ralph! That helps a lot.
@Ralph we are currently implementing the referrer approach I believe. So clients should be able to discover WIT via the referrers API without pulling the full component.
For the artifact types, I'm planning to use:
I suppose the main benefit of going with distinct types really is the referrers API filtering.
I just hope it won't be a pain to use existing tooling with... :grinning_face_with_smiling_eyes:
tagging @Josh Dolitsky and @Yosh Wuyts for viz
we're working on existing tooling and more robust OCI search support in dist as well, but that takes some time. :-)
Awesome! From what I've gathered so far, I think having a standard vnd type for WASM Components vs WIT may be a good thing long term...
There's this: https://component-model.bytecodealliance.org/composing-and-distributing/distributing.html
and that refers to the formal guidelines for now: https://tag-runtime.cncf.io/wgs/wasm/deliverables/wasm-oci-artifact/
note, however, that nothing refers to how you can USE or extend it -- for example, with referrers. That makes a lot of sense, as you can also embed SBOM information in a component, and extract that and push that as a referrer: Vimeo - sboms
Finally, also realize that though components have this format, it's not a complete "spec" yet though most runtimes and tools involving components use it. Therefore, if you think it should be modified, make a suggestion!
app hosting platforms like spin or wasmcloud for example may use a different format as a wrapper, because they're also pushing and pulling an entire solution including config files, for example. But it's all currently based upon that guideline document, and your favorite OCI tool CAN interact right now (including docker).
Ralph said:
tagging Josh Dolitsky and Yosh Wuyts for viz
cc/ @Josh Duffney ?
I haven't thought too much about this proposal, but yeah I can definitely see value in distinguishing in the metadata between a "shared, reusable interface" and "actual runnable program"
One question though: how can we tell that distinction just from looking at a .wasm file?
one approach would be to say that the .wit is just metadata on its own; which is true. as a result, it would best be a referrer pointing at the implementing component.
however, a component with no implementation but containing the wit is simply the same thing, but with component wrapping
the diff is that with a referrer you can download ONLY the wit without any impl, but if left in the component, you MUST make two calls: one for the manifest, one for the artifact and THEN extract the wit.
I think the question is whether wit should be delivered as a "component"
past history: IDL for COM components was embedded in a typelib which was shipped as a .dll so that existing processes could load and read it. This is functionally equivalent of what we're doing at this point here.
it was essentially a traveling SDK that could be read by existing tooling
again, the same here
is there a scenario for .wit information outside of the component wrapping?
because the overhead of the component wrapping is quite minimal if there's no impl
and the only question I can see is how easy is it to find the WIT you're looking for?
OCI is not optimized for pure throughput or search, but it CAN work fine so long as you do not try to scan the entire registry for something
but again, that's something we could change. All registries do have the ability to scan artifacts and create a db of their contents, but that's computationally expensive and of course also has compliance issues: not all regions of the world would consider that a reasonable thing to do!
so my take is the following:
@Lorenzo Fontoura is doing the right thing to optimized the consumption of WIT by stashing it in the referrer (but it would also be in the component in any case). This would enable current tooling to examine the WIT without looking for the artifact itself.
nothing wrong with that, and it's merely and ADDITION to the registry retaining the component in any case.
but I'd love to hear what others think
Ralph said:
I think the question is whether wit should be delivered as a "component"
Not sure if I understand it correctly, as I'm not familiar with the spec of the wasm binary itself, but is it the case then that there's no way to tell it is a WIT-only file? It makes a lot of sense to me for there to be a flag or something in the wasm binary to indicate that it is a WIT-only file and has no component implementation. But in my specific case I suppose this isn't really required, as the artifact type already specifies it. I'd agree that for practical purposes the overhead is negligible in this case, but I don't have much context so my opinion here is probably not very meaningful!
well, no, it is important to design this experience as best we can. "components" are artifacts -- files -- that conform to the component specification-in-flight. what is inside them is left up to the discretion of the creator.
it is assumed that a component containing a module could only have any functionality if it had exports, and WIT is used to define those exports, therefore wit must be exposed (or imported).
but WIT isn't the component at least at first blush; it's a file (or some string representation thereof, like WAT)
OCI just says, "if you've got a mediaType I know, you can store it here." But that could quite literally be anything, so the guidance document is just a strong suggestion about that mediaType.
currently, we know the wit is already IN the component, so we have a wasm-tools command that extracts the WIT for you from that artifact. Of course in OCI, to get that you must download the component. :-)
now, nothing can change about that, but if you WANT to be able to download ONLY the wit directly from OCI, it can be:
which is what I believe you suggested you are doing, which is great
because the component remains there, unmodified, and if you KNOW there's the wit, you can actually just grab that from the referrer
our objective, ultimately, is to have the registry recognize components and expose their wit in the interface.
Right... I see your point.
Ralph said:
is there a scenario for .wit information outside of the component wrapping?
WIT read efficiency for OCI registries, at least :grinning_face_with_smiling_eyes:
Ralph said:
our objective, ultimately, is to have the registry recognize components and expose their wit in the interface.
Ah this makes sense. I suppose it's a question then of whether there are other scenarios where the wit by itself would be useful in the long term.
the wit is just the formal statement of imports and exports, so it will ALWAYS be in any component impl. The question is what if you need something YOU want to implement? How do you ship JUST that .wit file?
realistically, if all the tooling uses components with oci, just putting it in a component "package" is fine.
as far as WIT read efficiency, OCI isn't good for outbound at scale, definitely -- but it works!!! look at all the containers out there. :-)
the only scenario in which optimizing wit retrieval makes sense is in a scenario in which the WIT, relative to the componentizing of the WIT alone, has a massive difference. That's just not the case.
but if you had a pattern for the referrers wit, that would in theory eliminate one call. i doubt it's really worth it, but it will work...
Well my use case is a registry interface. So I'd like to render the WIT/imports/exports in a UI, and having to fetch all component implementation for that seems inefficient
e.g. search all components, look at their interfaces and dependency graphs
right! yeah, we'd like to get to that stage at some point, too.
unless you OWN the uploading to the registry and all components, you're going to have to extract wit somewhere, either on push or on search or just go ahead and scan them all and build your dep tree
how, precisely, would you expect a component FILE to indicate it was WIT only without parsing it anyway?
but if you REQUIRE wit pushed as a referrer, yes, that would definitely help you
you could have a task on push that did the same....
Sorry, I accidentally hit that!
Ralph said:
how, precisely, would you expect a component FILE to indicate it was WIT only without parsing it anyway?
I agree, my suggestion there was more me not understanding how the component wrapping worked I think. But I follow your logic. I wouldn't need that in my case anyway I don't think, the only nice-to-have in my situation would be for there to be standard artifact types.
if you wsanna propose a wit mediaType, nothing wrong with that
The "WIT" in a component is mostly just the type of that component, and there are still some component types that are valid but inexpressible in WIT (although we work to reduce that gap), so I would suggest thinking about just having a smaller binary with the (still binary-encoded) type of the component, instead of trying to turn it back into textual WIT that may or may not exist for a given component.
Another important consideration here: WIT is not going to have the same backward-compatibility guarantees as the binary format, at least in the medium-term I think. We distribute interfaces as binary component types in part because it is a more stable format.
that's a very good point.
Last updated: Jan 29 2026 at 13:25 UTC