Repository: bytecodealliance/wasm-tools
Pull request #1262 (2023-10-24 23:48:47)

Remove "interface imports" from binary syntax, expand accepted strings
This PR is the spiritual successor of https://github.com/bytecodealliance/wasm-tools/pull/1146 and is an implementation of these PRs together for this repository:

* https://github.com/WebAssembly/component-model/pull/222
* https://github.com/WebAssembly/component-model/pull/259
* https://github.com/WebAssembly/component-model/pull/263

This is technically a breaking change to the binary format, but the breaking change is so minor that a gradual rollout is implemented here. Previously import/export names had a discriminator byte of 0x00 or 0x01 depending on if they were a "plain name" or an "interface name". They no longer have a discriminator byte and instead always use 0x00. This means that old binaries are easily read by discarding the 0x00 or 0x01 byte. New binaries are, for now, temporarily created with the 0x01 byte still to ensure that binaries produced with this tooling is still compatible with older tooling. Once this tooling has permeated enough I plan to change the default emission to be 0x00 instead of 0x01.

The text syntax was changed in this PR as well. Previously where `(interface "a:b/c")` was printed only `"a:b/c"` is printed now. Like the binary format the text format still parses the old form with the intention of being deleted eventually.

Finally this PR additionally expands the set of accepted syntax within import and export strings. This now includes imports of implementations (locked/unlocked deps), imports of URLs (relative and not), and integrity-based imports.

alexcrichton: TODO items:

* [ ] Validate that exports can't use urls/implementations/etc, basically only imports get the new syntax
* [ ] Parsing `integrity-metadata` currently does nothing but is defined by w3c. Should figure out what to do in the component model
alexcrichton: Ok I've updated with parsing of what I believe is the format of `integrity-metadata` so this is good to go I think

Patch:
diff --git a/crates/wasm-compose/src/graph.rs b/crates/wasm-compose/src/graph.rs
index cc9e3f12..321b61bf 100644
--- a/crates/wasm-compose/src/graph.rs
+++ b/crates/wasm-compose/src/graph.rs
@@ -122,24 +122,14 @@ impl<'a> Component<'a> {
                                 Payload::ComponentImportSection(s) => {
                                     for import in s {
                                         let import = import?;
-                                        let name = match import.name {
-                                            wasmparser::ComponentExternName::Kebab(s)
-                                            | wasmparser::ComponentExternName::Interface(s) => {
-                                                s.to_string()
-                                            }
-                                        };
+                                        let name = import.name.0.to_string();
                                         imports.insert(name, import.ty);
                                     }
                                 }
                                 Payload::ComponentExportSection(s) => {
                                     for export in s {
                                         let export = export?;
-                                        let name = match export.name {
-                                            wasmparser::ComponentExternName::Kebab(s)
-                                            | wasmparser::ComponentExternName::Interface(s) => {
-                                                s.to_string()
-                                            }
-                                        };
+                                        let name = export.name.0.to_string();
                                         exports.insert(name, (export.kind, export.index));
                                     }
                                 }
diff --git a/crates/wasm-encoder/src/component/exports.rs b/crates/wasm-encoder/src/component/exports.rs
index 09f9e251..e4fcfee0 100644
--- a/crates/wasm-encoder/src/component/exports.rs
+++ b/crates/wasm-encoder/src/component/exports.rs
@@ -2,10 +2,7 @@ use super::{
     COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, FUNCTION_SORT, INSTANCE_SORT, TYPE_SORT,
     VALUE_SORT,
 };
-use crate::{
-    encode_section, AsComponentExternName, ComponentSection, ComponentSectionId, ComponentTypeRef,
-    Encode,
-};
+use crate::{encode_section, ComponentSection, ComponentSectionId, ComponentTypeRef, Encode};
 
 /// Represents the kind of an export from a WebAssembly component.
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -55,12 +52,11 @@ impl Encode for ComponentExportKind {
 /// # Example
 ///
 /// ```rust
-/// use wasm_encoder::{Component, ComponentExportSection, ComponentExportKind, ComponentExternName};
+/// use wasm_encoder::{Component, ComponentExportSection, ComponentExportKind};
 ///
 /// // This exports a function named "foo"
 /// let mut exports = ComponentExportSection::new();
-/// let name = ComponentExternName::Kebab("foo");
-/// exports.export(name, ComponentExportKind::Func, 0, None);
+/// exports.export("foo", ComponentExportKind::Func, 0, None);
 ///
 /// let mut component = Component::new();
 /// component.section(&exports);
@@ -92,12 +88,13 @@ impl ComponentExportSection {
     /// Define an export in the export section.
     pub fn export(
         &mut self,
-        name: impl AsComponentExternName,
+        name: &str,
         kind: ComponentExportKind,
         index: u32,
         ty: Option<ComponentTypeRef>,
     ) -> &mut Self {
-        name.as_component_extern_name().encode(&mut self.bytes);
+        crate::component::imports::push_extern_name_byte(&mut self.bytes, name);
+        name.encode(&mut self.bytes);
         kind.encode(&mut self.bytes);
         index.encode(&mut self.bytes);
         match ty {
diff --git a/crates/wasm-encoder/src/component/imports.rs b/crates/wasm-encoder/src/component/imports.rs
index fe611a01..6337a062 100644
--- a/crates/wasm-encoder/src/component/imports.rs
+++ b/crates/wasm-encoder/src/component/imports.rs
@@ -82,7 +82,7 @@ impl Encode for ComponentTypeRef {
 /// # Example
 ///
 /// ```rust
-/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType, ComponentImportSection, ComponentTypeRef, ComponentExternName};
+/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType, ComponentImportSection, ComponentTypeRef};
 ///
 /// let mut types = ComponentTypeSection::new();
 ///
@@ -99,8 +99,7 @@ impl Encode for ComponentTypeRef {
 ///
 /// // This imports a function named `f` with the type defined above
 /// let mut imports = ComponentImportSection::new();
-/// let name = ComponentExternName::Kebab("f");
-/// imports.import(name, ComponentTypeRef::Func(0));
+/// imports.import("f", ComponentTypeRef::Func(0));
 ///
 /// let mut component = Component::new();
 /// component.section(&types);
@@ -131,8 +130,9 @@ impl ComponentImportSection {
     }
 
     /// Define an import in the component import section.
-    pub fn import(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self {
-        name.as_component_extern_name().encode(&mut self.bytes);
+    pub fn import(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
+        push_extern_name_byte(&mut self.bytes, name);
+        name.encode(&mut self.bytes);
         ty.encode(&mut self.bytes);
         self.num_added += 1;
         self
@@ -151,50 +151,25 @@ impl ComponentSection for ComponentImportSection {
     }
 }
 
-/// The different names that can be assigned to component imports
-#[derive(Debug, Copy, Clone)]
-pub enum ComponentExternName<'a> {
-    /// This is a "kebab name" along the lines of "a-foo-bar"
-    Kebab(&'a str),
-    /// This is an ID along the lines of "wasi:http/types@2.0"
-    Interface(&'a str),
-}
-
-impl Encode for ComponentExternName<'_> {
-    fn encode(&self, sink: &mut Vec<u8>) {
-        match self {
-            ComponentExternName::Kebab(name) => {
-                sink.push(0x00);
-                name.encode(sink);
-            }
-            ComponentExternName::Interface(name) => {
-                sink.push(0x01);
-                name.encode(sink);
-            }
-        }
-    }
-}
-
-/// Helper trait to convert into a `ComponentExternName` either from that type
-/// or from a string.
-pub trait AsComponentExternName {
-    /// Converts this receiver into a `ComponentExternName`.
-    fn as_component_extern_name(&self) -> ComponentExternName<'_>;
-}
-
-impl AsComponentExternName for ComponentExternName<'_> {
-    fn as_component_extern_name(&self) -> ComponentExternName<'_> {
-        *self
-    }
-}
-
-impl<S: AsRef<str>> AsComponentExternName for S {
-    fn as_component_extern_name(&self) -> ComponentExternName<'_> {
-        let s = self.as_ref();
-        if s.contains("/") {
-            ComponentExternName::Interface(s)
-        } else {
-            ComponentExternName::Kebab(s)
-        }
+/// Prior to WebAssembly/component-model#263 import and export names were
+/// discriminated with a leading byte indicating what kind of import they are.
+/// After that PR though names are always prefixed with a 0x00 byte.
+///
+/// This function is a compatibility shim for the time being while this change
+/// is being rolled out. That PR is technically a spec-breaking change relative
+/// to prior but we want old tooling to continue to work with new modules. To
+/// handle that names that look like IDs, `a:b/c`, get an 0x01 prefix instead of
+/// the spec-defined 0x00 prefix. That makes components produced by current
+/// versions of this crate compatible with older parsers.
+///
+/// Note that wasmparser has a similar case where it parses either 0x01 or 0x00.
+/// That means that the selection of a byte here doesn't actually matter for
+/// wasmparser's own validation. Eventually this will go away and an 0x00 byte
+/// will always be emitted to align with the spec.
+pub(crate) fn push_extern_name_byte(bytes: &mut Vec<u8>, name: &str) {
+    if name.contains(':') {
+        bytes.push(0x01);
+    } else {
+        bytes.push(0x00);
     }
 }
diff --git a/crates/wasm-encoder/src/component/instances.rs b/crates/wasm-encoder/src/component/instances.rs
index d2a8e4e7..e0877d16 100644
--- a/crates/wasm-encoder/src/component/instances.rs
+++ b/crates/wasm-encoder/src/component/instances.rs
@@ -1,7 +1,6 @@
 use super::CORE_INSTANCE_SORT;
 use crate::{
-    encode_section, ComponentExportKind, ComponentExternName, ComponentSection, ComponentSectionId,
-    Encode, ExportKind,
+    encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, Encode, ExportKind,
 };
 
 /// Represents an argument to a module instantiation.
@@ -115,10 +114,10 @@ impl ComponentSection for InstanceSection {
 /// # Example
 ///
 /// ```rust
-/// use wasm_encoder::{Component, ComponentInstanceSection, ComponentExportKind, ComponentExternName};
+/// use wasm_encoder::{Component, ComponentInstanceSection, ComponentExportKind};
 ///
 /// let mut instances = ComponentInstanceSection::new();
-/// instances.export_items([(ComponentExternName::Kebab("foo"), ComponentExportKind::Func, 0)]);
+/// instances.export_items([("foo", ComponentExportKind::Func, 0)]);
 /// instances.instantiate(1, [("foo", ComponentExportKind::Instance, 0)]);
 ///
 /// let mut component = Component::new();
@@ -171,13 +170,14 @@ impl ComponentInstanceSection {
     /// Define an instance by exporting items.
     pub fn export_items<'a, E>(&mut self, exports: E) -> &mut Self
     where
-        E: IntoIterator<Item = (ComponentExternName<'a>, ComponentExportKind, u32)>,
+        E: IntoIterator<Item = (&'a str, ComponentExportKind, u32)>,
         E::IntoIter: ExactSizeIterator,
     {
         let exports = exports.into_iter();
         self.bytes.push(0x01);
         exports.len().encode(&mut self.bytes);
         for (name, kind, index) in exports {
+            crate::push_extern_name_byte(&mut self.bytes, name);
             name.encode(&mut self.bytes);
             kind.encode(&mut self.bytes);
             index.encode(&mut self.bytes);
diff --git a/crates/wasm-encoder/src/component/types.rs b/crates/wasm-encoder/src/component/types.rs
index ff3aacc2..159e1531 100644
--- a/crates/wasm-encoder/src/component/types.rs
+++ b/crates/wasm-encoder/src/component/types.rs
@@ -1,7 +1,7 @@
 use super::CORE_TYPE_SORT;
 use crate::{
-    encode_section, Alias, AsComponentExternName, ComponentExportKind, ComponentOuterAliasKind,
-    ComponentSection, ComponentSectionId, ComponentTypeRef, Encode, EntityType, ValType,
+    encode_section, Alias, ComponentExportKind, ComponentOuterAliasKind, ComponentSection,
+    ComponentSectionId, ComponentTypeRef, Encode, EntityType, ValType,
 };
 
 /// Represents the type of a core module.
@@ -20,7 +20,7 @@ impl ModuleType {
 
     /// Defines an import in this module type.
     pub fn import(&mut self, module: &str, name: &str, ty: EntityType) -> &mut Self {
-        self.bytes.push(0x00);
+        crate::component::imports::push_extern_name_byte(&mut self.bytes, name);
         module.encode(&mut self.bytes);
         name.encode(&mut self.bytes);
         ty.encode(&mut self.bytes);
@@ -250,9 +250,10 @@ impl ComponentType {
     }
 
     /// Defines an import in this component type.
-    pub fn import(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self {
+    pub fn import(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
         self.bytes.push(0x03);
-        name.as_component_extern_name().encode(&mut self.bytes);
+        crate::component::imports::push_extern_name_byte(&mut self.bytes, name);
+        name.encode(&mut self.bytes);
         ty.encode(&mut self.bytes);
         self.num_added += 1;
         match ty {
@@ -264,9 +265,10 @@ impl ComponentType {
     }
 
     /// Defines an export in this component type.
-    pub fn export(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self {
+    pub fn export(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
         self.bytes.push(0x04);
-        name.as_component_extern_name().encode(&mut self.bytes);
+        crate::component::imports::push_extern_name_byte(&mut self.bytes, name);
+        name.encode(&mut self.bytes);
         ty.encode(&mut self.bytes);
         self.num_added += 1;
         match ty {
@@ -335,7 +337,7 @@ impl InstanceType {
     }
 
     /// Defines an export in this instance type.
-    pub fn export(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self {
+    pub fn export(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
         self.0.export(name, ty);
         self
     }
diff --git a/crates/wasm-smith/src/component/encode.rs b/crates/wasm-smith/src/component/encode.rs
index c96f684a..3547fc07 100644
--- a/crates/wasm-smith/src/component/encode.rs
+++ b/crates/wasm-smith/src/component/encode.rs
@@ -73,7 +73,7 @@ impl ImportSection {
     fn encode(&self, component: &mut wasm_encoder::Component) {
         let mut sec = wasm_encoder::ComponentImportSection::new();
         for imp in &self.imports {
-            sec.import(wasm_encoder::ComponentExternName::Kebab(&imp.name), imp.ty);
+            sec.import(&imp.name, imp.ty);
         }
         component.section(&sec);
     }
@@ -180,10 +180,7 @@ impl Type {
                 for def in &comp_ty.defs {
                     match def {
                         ComponentTypeDef::Import(imp) => {
-                            enc_comp_ty.import(
-                                wasm_encoder::ComponentExternName::Kebab(&imp.name),
-                                imp.ty,
-                            );
+                            enc_comp_ty.import(&imp.name, imp.ty);
                         }
                         ComponentTypeDef::CoreType(ty) => {
                             ty.encode(enc_comp_ty.core_type());
@@ -192,7 +189,7 @@ impl Type {
                             ty.encode(enc_comp_ty.ty());
                         }
                         ComponentTypeDef::Export { name, url: _, ty } => {
-                            enc_comp_ty.export(wasm_encoder::ComponentExternName::Kebab(name), *ty);
+                            enc_comp_ty.export(name, *ty);
                         }
                         ComponentTypeDef::Alias(a) => {
                             enc_comp_ty.alias(translate_alias(a));
@@ -212,7 +209,7 @@ impl Type {
                             ty.encode(enc_inst_ty.ty());
                         }
                         InstanceTypeDecl::Export { name, url: _, ty } => {
-                            enc_inst_ty.export(wasm_encoder::ComponentExternName::Kebab(name), *ty);
+                            enc_inst_ty.export(name, *ty);
                         }
                         InstanceTypeDecl::Alias(a) => {
                             enc_inst_ty.alias(translate_alias(a));
diff --git a/crates/wasmparser/src/readers/component/exports.rs b/crates/wasmparser/src/readers/component/exports.rs
index 35c54394..74641ef0 100644
--- a/crates/wasmparser/src/readers/component/exports.rs
+++ b/crates/wasmparser/src/readers/component/exports.rs
@@ -1,6 +1,4 @@
-use crate::{
-    BinaryReader, ComponentExternName, ComponentTypeRef, FromReader, Result, SectionLimited,
-};
+use crate::{BinaryReader, ComponentTypeRef, FromReader, Result, SectionLimited};
 
 /// Represents the kind of an external items of a WebAssembly component.
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -69,7 +67,7 @@ impl ComponentExternalKind {
 #[derive(Debug, Clone)]
 pub struct ComponentExport<'a> {
     /// The name of the exported item.
-    pub name: ComponentExternName<'a>,
+    pub name: ComponentExportName<'a>,
     /// The kind of the export.
     pub kind: ComponentExternalKind,
     /// The index of the exported item.
@@ -115,3 +113,23 @@ impl<'a> FromReader<'a> for ComponentExternalKind {
         ComponentExternalKind::from_bytes(byte1, byte2, offset)
     }
 }
+
+/// Represents the name of a component export.
+#[derive(Debug, Copy, Clone)]
+#[allow(missing_docs)]
+pub struct ComponentExportName<'a>(pub &'a str);
+
+impl<'a> FromReader<'a> for ComponentExportName<'a> {
+    fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
+        match reader.read_u8()? {
+            0x00 => {}
+            // Historically export names used a discriminator byte of 0x01 to
+            // indicate an "interface" of the form `a:b/c` but nowadays that's
+            // inferred from string syntax. Ignore 0-vs-1 to continue to parse
+            // older binaries. Eventually this will go away.
+            0x01 => {}
+            x => return reader.invalid_leading_byte(x, "export name"),
+        }
+        Ok(ComponentExportName(reader.read_string()?))
+    }
+}
diff --git a/crates/wasmparser/src/readers/component/imports.rs b/crates/wasmparser/src/readers/component/imports.rs
index d5e09cbc..52a0f962 100644
--- a/crates/wasmparser/src/readers/component/imports.rs
+++ b/crates/wasmparser/src/readers/component/imports.rs
@@ -79,7 +79,7 @@ impl<'a> FromReader<'a> for ComponentTypeRef {
 #[derive(Debug, Copy, Clone)]
 pub struct ComponentImport<'a> {
     /// The name of the imported item.
-    pub name: ComponentExternName<'a>,
+    pub name: ComponentImportName<'a>,
     /// The type reference for the import.
     pub ty: ComponentTypeRef,
 }
@@ -111,27 +111,19 @@ pub type ComponentImportSectionReader<'a> = SectionLimited<'a, ComponentImport<'
 /// Represents the name of a component import.
 #[derive(Debug, Copy, Clone)]
 #[allow(missing_docs)]
-pub enum ComponentExternName<'a> {
-    Kebab(&'a str),
-    Interface(&'a str),
-}
+pub struct ComponentImportName<'a>(pub &'a str);
 
-impl<'a> ComponentExternName<'a> {
-    /// Returns the underlying string representing this name.
-    pub fn as_str(&self) -> &'a str {
-        match self {
-            ComponentExternName::Kebab(name) => name,
-            ComponentExternName::Interface(name) => name,
-        }
-    }
-}
-
-impl<'a> FromReader<'a> for ComponentExternName<'a> {
+impl<'a> FromReader<'a> for ComponentImportName<'a> {
     fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
-        Ok(match reader.read_u8()? {
-            0x00 => ComponentExternName::Kebab(reader.read()?),
-            0x01 => ComponentExternName::Interface(reader.read()?),
+        match reader.read_u8()? {
+            0x00 => {}
+            // Historically export names used a discriminator byte of 0x01 to
+            // indicate an "interface" of the form `a:b/c` but nowadays that's
+            // inferred from string syntax. Ignore 0-vs-1 to continue to parse
+            // older binaries. Eventually this will go away.
+            0x01 => {}
             x => return reader.invalid_leading_byte(x, "import name"),
-        })
+        }
+        Ok(ComponentImportName(reader.read_string()?))
     }
 }
diff --git a/crates/wasmparser/src/readers/component/types.rs b/crates/wasmparser/src/readers/component/types.rs
index 9a38ae7d..b2a79632 100644
--- a/crates/wasmparser/src/readers/component/types.rs
+++ b/crates/wasmparser/src/readers/component/types.rs
@@ -1,6 +1,6 @@
 use crate::limits::*;
 use crate::{
-    BinaryReader, ComponentAlias, ComponentExternName, ComponentImport, ComponentTypeRef,
+    BinaryReader, ComponentAlias, ComponentExportName, ComponentImport, ComponentTypeRef,
     FromReader, Import, Result, SectionLimited, SubType, TypeRef, ValType,
 };
 use std::fmt;
@@ -303,7 +303,7 @@ pub enum ComponentTypeDeclaration<'a> {
     /// The component type declaration is for an export.
     Export {
         /// The name of the export.
-        name: ComponentExternName<'a>,
+        name: ComponentExportName<'a>,
         /// The type reference for the export.
         ty: ComponentTypeRef,
     },
@@ -344,7 +344,7 @@ pub enum InstanceTypeDeclaration<'a> {
     /// The instance type declaration is for an export.
     Export {
         /// The name of the export.
-        name: ComponentExternName<'a>,
+        name: ComponentExportName<'a>,
         /// The type reference for the export.
         ty: ComponentTypeRef,
     },
diff --git a/crates/wasmparser/src/validator/component.rs b/crates/wasmparser/src/validator/component.rs
index 97e5ff88..0ab15fb9 100644
--- a/crates/wasmparser/src/validator/component.rs
+++ b/crates/wasmparser/src/validator/component.rs
@@ -10,7 +10,7 @@ use super::{
         ModuleType, RecordType, Remapping, ResourceId, TypeAlloc, TypeList, VariantCase,
     },
 };
-use crate::validator::names::{KebabName, KebabNameKind, KebabStr, KebabString};
+use crate::validator::names::{ComponentName, ComponentNameKind, KebabStr, KebabString};
 use crate::{
     limits::*,
     types::{
@@ -18,7 +18,7 @@ use crate::{
         ComponentEntityType, Context, CoreInstanceTypeKind, LoweringInfo, Remap, SubtypeCx,
         TupleType, TypeInfo, VariantType,
     },
-    BinaryReaderError, CanonicalOption, ComponentExternName, ComponentExternalKind,
+    BinaryReaderError, CanonicalOption, ComponentExportName, ComponentExternalKind,
     ComponentOuterAliasKind, ComponentTypeRef, CompositeType, ExternalKind, FuncType, GlobalType,
     InstantiationArgKind, MemoryType, RecGroup, Result, SubType, TableType, TypeBounds, ValType,
     WasmFeatures,
@@ -63,8 +63,9 @@ pub(crate) struct ComponentState {
     pub components: Vec<ComponentTypeId>,
 
     pub imports: IndexMap<String, ComponentEntityType>,
+    pub import_names: IndexSet<ComponentName>,
     pub exports: IndexMap<String, ComponentEntityType>,
-    pub kebab_named_externs: IndexSet<KebabName>,
+    pub export_names: IndexSet<ComponentName>,
 
     has_start: bool,
     type_info: TypeInfo,
@@ -165,10 +166,10 @@ pub(crate) struct ComponentState {
     /// Note that imports/exports have disjoint contexts to ensure that they're
     /// validated correctly. Namely you can't retroactively attach methods to an
     /// import, for example.
-    toplevel_exported_resources: KebabNameContext,
+    toplevel_exported_resources: ComponentNameContext,
 
     /// Same as `toplevel_exported_resources`, but for imports.
-    toplevel_imported_resources: KebabNameContext,
+    toplevel_imported_resources: ComponentNameContext,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -181,7 +182,7 @@ pub enum ComponentKind {
 /// Helper context used to track information about resource names for method
 /// name validation.
 #[derive(Default)]
-struct KebabNameContext {
+struct ComponentNameContext {
     /// A map from a resource type id to an index in the `all_resource_names`
     /// set for the name of that resource.
     resource_name_map: HashMap<AliasableResourceId, usize>,
@@ -226,7 +227,8 @@ impl ComponentState {
             components: Default::default(),
             imports: Default::default(),
             exports: Default::default(),
-            kebab_named_externs: Default::default(),
+            import_names: Default::default(),
+            export_names: Default::default(),
             has_start: Default::default(),
             type_info: TypeInfo::new(),
             imported_resources: Default::default(),
@@ -431,18 +433,18 @@ impl ComponentState {
         let mut entity = self.check_type_ref(&import.ty, features, types, offset)?;
         self.add_entity(
             &mut entity,
-            Some((import.name.as_str(), ExternKind::Import)),
+            Some((import.name.0, ExternKind::Import)),
             features,
             types,
             offset,
         )?;
         self.toplevel_imported_resources.validate_extern(
-            import.name,
-            "import",
+            import.name.0,
+            ExternKind::Import,
             &entity,
             types,
             offset,
-            &mut self.kebab_named_externs,
+            &mut self.import_names,
             &mut self.imports,
             &mut self.type_info,
         )?;
@@ -912,7 +914,7 @@ impl ComponentState {
 
     pub fn add_export(
         &mut self,
-        name: ComponentExternName<'_>,
+        name: ComponentExportName<'_>,
         mut ty: ComponentEntityType,
         features: &WasmFeatures,
         types: &mut TypeAlloc,
@@ -924,18 +926,18 @@ impl ComponentState {
         }
         self.add_entity(
             &mut ty,
-            Some((name.as_str(), ExternKind::Export)),
+            Some((name.0, ExternKind::Export)),
             features,
             types,
             offset,
         )?;
         self.toplevel_exported_resources.validate_extern(
-            name.into(),
-            "export",
+            name.0,
+            ExternKind::Export,
             &ty,
             types,
             offset,
-            &mut self.kebab_named_externs,
+            &mut self.export_names,
             &mut self.exports,
             &mut self.type_info,
         )?;
@@ -2049,12 +2051,12 @@ impl ComponentState {
         let mut info = TypeInfo::new();
         let mut inst_exports = IndexMap::new();
         let mut explicit_resources = IndexMap::new();
-        let mut kebab_names = IndexSet::new();
+        let mut export_names = IndexSet::new();
 
         // NB: It's intentional that this context is empty since no indices are
         // introduced in the bag-of-exports construct which means there's no
         // way syntactically to register something inside of this.
-        let names = KebabNameContext::default();
+        let names = ComponentNameContext::default();
 
         for export in exports {
             assert!(export.ty.is_none());
@@ -2110,12 +2112,12 @@ impl ComponentState {
             };
 
             names.validate_extern(
-                export.name.into(),
-                "instance export",
+                export.name.0,
+                ExternKind::Export,
                 &ty,
                 types,
                 offset,
-                &mut kebab_names,
+                &mut export_names,
                 &mut inst_exports,
                 &mut info,
             )?;
@@ -2961,7 +2963,7 @@ impl ComponentState {
     }
 }
 
-impl KebabNameContext {
+impl ComponentNameContext {
     /// Registers that the resource `id` is named `name` within this context.
     fn register(&mut self, name: &str, id: AliasableResourceId) {
         let idx = self.all_resource_names.len();
@@ -2975,47 +2977,61 @@ impl KebabNameContext {
 
     fn validate_extern(
         &self,
-        name: ComponentExternName<'_>,
-        desc: &str,
+        name: &str,
+        kind: ExternKind,
         ty: &ComponentEntityType,
         types: &TypeAlloc,
         offset: usize,
-        kebab_names: &mut IndexSet<KebabName>,
+        kind_names: &mut IndexSet<ComponentName>,
         items: &mut IndexMap<String, ComponentEntityType>,
         info: &mut TypeInfo,
     ) -> Result<()> {
         // First validate that `name` is even a valid kebab name, meaning it's
         // in kebab-case, is an ID, etc.
-        let kebab = KebabName::new(name, offset).with_context(|| {
-            format!("{desc} name `{}` is not a valid extern name", name.as_str())
-        })?;
+        let kebab = ComponentName::new(name, offset)
+            .with_context(|| format!("{} name `{name}` is not a valid extern name", kind.desc()))?;
+
+        if let ExternKind::Export = kind {
+            match kebab.kind() {
+                ComponentNameKind::Label(_)
+                | ComponentNameKind::Method(_)
+                | ComponentNameKind::Static(_)
+                | ComponentNameKind::Constructor(_)
+                | ComponentNameKind::Interface(_) => {}
+
+                ComponentNameKind::Hash(_)
+                | ComponentNameKind::Url(_)
+                | ComponentNameKind::Dependency(_) => {
+                    bail!(offset, "name `{name}` is not a valid export name")
+                }
+            }
+        }
 
         // Validate that the kebab name, if it has structure such as
         // `[method]a.b`, is indeed valid with respect to known resources.
         self.validate(&kebab, ty, types, offset)
-            .with_context(|| format!("{desc} name `{kebab}` is not valid"))?;
+            .with_context(|| format!("{} name `{kebab}` is not valid", kind.desc()))?;
 
         // Top-level kebab-names must all be unique, even between both imports
         // and exports ot a component. For those names consult the `kebab_names`
         // set.
-        if let ComponentExternName::Kebab(_) = name {
-            if let Some(prev) = kebab_names.replace(kebab.clone()) {
-                bail!(
-                    offset,
-                    "{desc} name `{kebab}` conflicts with previous name `{prev}`",
-                );
-            }
+        if let Some(prev) = kind_names.replace(kebab.clone()) {
+            bail!(
+                offset,
+                "{} name `{kebab}` conflicts with previous name `{prev}`",
+                kind.desc()
+            );
         }
 
         // Otherwise all strings must be unique, regardless of their name, so
         // consult the `items` set to ensure that we're not for example
         // importing the same interface ID twice.
-        match items.entry(kebab.into()) {
+        match items.entry(name.to_string()) {
             Entry::Occupied(e) => {
                 bail!(
                     offset,
-                    "{desc} name `{name}` conflicts with previous name `{prev}`",
-                    name = name.as_str(),
+                    "{kind} name `{name}` conflicts with previous name `{prev}`",
+                    kind = kind.desc(),
                     prev = e.key(),
                 );
             }
@@ -3030,7 +3046,7 @@ impl KebabNameContext {
     /// Validates that the `name` provided is allowed to have the type `ty`.
     fn validate(
         &self,
-        name: &KebabName,
+        name: &ComponentName,
         ty: &ComponentEntityType,
         types: &TypeAlloc,
         offset: usize,
@@ -3043,12 +3059,16 @@ impl KebabNameContext {
             Ok(&types[id])
         };
         match name.kind() {
-            // Normal kebab name or id? No validation necessary.
-            KebabNameKind::Normal(_) | KebabNameKind::Id { .. } => {}
+            // No validation necessary for these styles of names
+            ComponentNameKind::Label(_)
+            | ComponentNameKind::Interface(_)
+            | ComponentNameKind::Url(_)
+            | ComponentNameKind::Dependency(_)
+            | ComponentNameKind::Hash(_) => {}
 
             // Constructors must return `(own $resource)` and the `$resource`
             // must be named within this context to match `rname`
-            KebabNameKind::Constructor(rname) => {
+            ComponentNameKind::Constructor(rname) => {
                 let ty = func()?;
                 if ty.results.len() != 1 {
                     bail!(offset, "function should return one value");
@@ -3071,7 +3091,7 @@ impl KebabNameContext {
             // Methods must take `(param "self" (borrow $resource))` as the
             // first argument where `$resources` matches the name `resource` as
             // named in this context.
-            KebabNameKind::Method { resource, .. } => {
+            ComponentNameKind::Method(name) => {
                 let ty = func()?;
                 if ty.params.len() == 0 {
                     bail!(offset, "function should have at least one argument");
@@ -3097,15 +3117,15 @@ impl KebabNameContext {
                         "function should take a first argument of `(borrow $T)`"
                     ),
                 };
-                self.validate_resource_name(*id, resource, offset)?;
+                self.validate_resource_name(*id, name.resource(), offset)?;
             }
 
             // Static methods don't have much validation beyond that they must
             // be a function and the resource name referred to must already be
             // in this context.
-            KebabNameKind::Static { resource, .. } => {
+            ComponentNameKind::Static(name) => {
                 func()?;
-                if !self.all_resource_names.contains(resource.as_str()) {
+                if !self.all_resource_names.contains(name.resource().as_str()) {
                     bail!(offset, "static resource name is not known in this context");
                 }
             }
diff --git a/crates/wasmparser/src/validator/names.rs b/crates/wasmparser/src/validator/names.rs
index 0c3263b3..863e05b2 100644
--- a/crates/wasmparser/src/validator/names.rs
+++ b/crates/wasmparser/src/validator/names.rs
@@ -1,7 +1,7 @@
 //! Definitions of name-related helpers and newtypes, primarily for the
 //! component model.
 
-use crate::{ComponentExternName, Result};
+use crate::Result;
 use semver::Version;
 use std::borrow::Borrow;
 use std::fmt;
@@ -201,174 +201,102 @@ impl From<KebabString> for String {
     }
 }
 
-/// A "kebab name" in the component model which is backed by `T`, which defaults
-/// to `String`.
+/// An import or export name in the component model which is backed by `T`,
+/// which defaults to `String`.
 ///
 /// This name can be either:
 ///
-/// * a `KebabStr`: `a-b-c`
-/// * a method name : `[method]a-b.c-d`
-/// * a static method name : `[static]a-b.c-d`
-/// * a constructor: `[constructor]a-b`
+/// * a plain label or "kebab string": `a-b-c`
+/// * a plain method name : `[method]a-b.c-d`
+/// * a plain static method name : `[static]a-b.c-d`
+/// * a plain constructor: `[constructor]a-b`
+/// * an interface name: `wasi:cli/reactor@0.1.0`
+/// * a dependency name: `locked-dep=foo:bar/baz`
+/// * a URL name: `url=https://..`
+/// * a hash name: `integrity=sha256:...`
 ///
 /// # Equality and hashing
 ///
-/// Note that this type the `Method` and `Static` variants are considered equal
-/// and hash to the same value. This enables disallowing clashes between the two
-/// where method name overlap cannot happen.
+/// Note that this type the `[method]...` and `[static]...` variants are
+/// considered equal and hash to the same value. This enables disallowing
+/// clashes between the two where method name overlap cannot happen.
 #[derive(Clone)]
-pub struct KebabName {
+pub struct ComponentName {
     raw: String,
-    parsed: ParsedKebabName,
+    kind: ParsedComponentNameKind,
 }
 
 #[derive(Copy, Clone)]
-enum ParsedKebabName {
-    Normal,
+enum ParsedComponentNameKind {
+    Label,
     Constructor,
-    Method {
-        dot: u32,
-    },
-    Static {
-        dot: u32,
-    },
-    Id {
-        colon: u32,
-        slash: u32,
-        at: Option<u32>,
-    },
-}
-
-/// Created via [`KebabName::kind`] and classifies a name.
+    Method,
+    Static,
+    Interface,
+    Dependency,
+    Url,
+    Hash,
+}
+
+/// Created via [`ComponentName::kind`] and classifies a name.
 #[derive(Debug, Clone)]
-pub enum KebabNameKind<'a> {
+pub enum ComponentNameKind<'a> {
     /// `a-b-c`
-    Normal(&'a KebabStr),
+    Label(&'a KebabStr),
     /// `[constructor]a-b`
     Constructor(&'a KebabStr),
     /// `[method]a-b.c-d`
     #[allow(missing_docs)]
-    Method {
-        resource: &'a KebabStr,
-        name: &'a KebabStr,
-    },
+    Method(ResourceFunc<'a>),
     /// `[static]a-b.c-d`
     #[allow(missing_docs)]
-    Static {
-        resource: &'a KebabStr,
-        name: &'a KebabStr,
-    },
+    Static(ResourceFunc<'a>),
     /// `wasi:http/types@2.0`
     #[allow(missing_docs)]
-    Id {
-        namespace: &'a KebabStr,
-        package: &'a KebabStr,
-        interface: &'a KebabStr,
-        version: Option<Version>,
-    },
+    Interface(InterfaceName<'a>),
+    /// `locked-dep=foo:bar/baz`
+    #[allow(missing_docs)]
+    Dependency(DependencyName<'a>),
+    /// `url=https://...`
+    #[allow(missing_docs)]
+    Url(UrlName<'a>),
+    /// `integrity=sha256:...`
+    #[allow(missing_docs)]
+    Hash(HashName<'a>),
 }
 
 const CONSTRUCTOR: &str = "[constructor]";
 const METHOD: &str = "[method]";
 const STATIC: &str = "[static]";
 
-impl KebabName {
-    /// Attempts to parse `name` as a kebab name, returning `None` if it's not
-    /// valid.
-    pub fn new(name: ComponentExternName<'_>, offset: usize) -> Result<KebabName> {
-        let validate_kebab = |s: &str| {
-            if KebabStr::new(s).is_none() {
-                bail!(offset, "`{s}` is not in kebab case")
-            } else {
-                Ok(())
-            }
-        };
-        let find = |s: &str, c: char| match s.find(c) {
-            Some(i) => Ok(i),
-            None => bail!(offset, "failed to find `{c}` character"),
-        };
-        let parsed = match name {
-            ComponentExternName::Kebab(s) => {
-                if let Some(s) = s.strip_prefix(CONSTRUCTOR) {
-                    validate_kebab(s)?;
-                    ParsedKebabName::Constructor
-                } else if let Some(s) = s.strip_prefix(METHOD) {
-                    let dot = find(s, '.')?;
-                    validate_kebab(&s[..dot])?;
-                    validate_kebab(&s[dot + 1..])?;
-                    ParsedKebabName::Method { dot: dot as u32 }
-                } else if let Some(s) = s.strip_prefix(STATIC) {
-                    let dot = find(s, '.')?;
-                    validate_kebab(&s[..dot])?;
-                    validate_kebab(&s[dot + 1..])?;
-                    ParsedKebabName::Static { dot: dot as u32 }
-                } else {
-                    validate_kebab(s)?;
-                    ParsedKebabName::Normal
-                }
-            }
-            ComponentExternName::Interface(s) => {
-                let colon = find(s, ':')?;
-                validate_kebab(&s[..colon])?;
-                let slash = find(s, '/')?;
-                let at = s[slash..].find('@').map(|i| i + slash);
-                validate_kebab(&s[colon + 1..slash])?;
-                validate_kebab(&s[slash + 1..at.unwrap_or(s.len())])?;
-                if let Some(at) = at {
-                    let version = &s[at + 1..];
-                    if let Err(e) = version.parse::<Version>() {
-                        bail!(offset, "failed to parse version: {e}")
-                    }
-                }
-                ParsedKebabName::Id {
-                    colon: colon as u32,
-                    slash: slash as u32,
-                    at: at.map(|i| i as u32),
-                }
-            }
-        };
-        Ok(KebabName {
-            raw: name.as_str().to_string(),
-            parsed,
+impl ComponentName {
+    /// Attempts to parse `name` as a valid component name, returning `Err` if
+    /// it's not valid.
+    pub fn new(name: &str, offset: usize) -> Result<ComponentName> {
+        let mut parser = ComponentNameParser { next: name, offset };
+        let kind = parser.parse()?;
+        if !parser.next.is_empty() {
+            bail!(offset, "trailing characters found: `{}`", parser.next);
+        }
+        Ok(ComponentName {
+            raw: name.to_string(),
+            kind,
         })
     }
 
-    /// Returns the [`KebabNameKind`] corresponding to this name.
-    pub fn kind(&self) -> KebabNameKind<'_> {
-        match self.parsed {
-            ParsedKebabName::Normal => KebabNameKind::Normal(KebabStr::new_unchecked(&self.raw)),
-            ParsedKebabName::Constructor => {
-                let kebab = &self.raw[CONSTRUCTOR.len()..];
-                KebabNameKind::Constructor(KebabStr::new_unchecked(kebab))
-            }
-            ParsedKebabName::Method { dot } => {
-                let dotted = &self.raw[METHOD.len()..];
-                let resource = KebabStr::new_unchecked(&dotted[..dot as usize]);
-                let name = KebabStr::new_unchecked(&dotted[dot as usize + 1..]);
-                KebabNameKind::Method { resource, name }
-            }
-            ParsedKebabName::Static { dot } => {
-                let dotted = &self.raw[METHOD.len()..];
-                let resource = KebabStr::new_unchecked(&dotted[..dot as usize]);
-                let name = KebabStr::new_unchecked(&dotted[dot as usize + 1..]);
-                KebabNameKind::Static { resource, name }
-            }
-            ParsedKebabName::Id { colon, slash, at } => {
-                let colon = colon as usize;
-                let slash = slash as usize;
-                let at = at.map(|i| i as usize);
-                let namespace = KebabStr::new_unchecked(&self.raw[..colon]);
-                let package = KebabStr::new_unchecked(&self.raw[colon + 1..slash]);
-                let interface =
-                    KebabStr::new_unchecked(&self.raw[slash + 1..at.unwrap_or(self.raw.len())]);
-                let version = at.map(|i| Version::parse(&self.raw[i + 1..]).unwrap());
-                KebabNameKind::Id {
-                    namespace,
-                    package,
-                    interface,
-                    version,
-                }
-            }
+    /// Returns the [`ComponentNameKind`] corresponding to this name.
+    pub fn kind(&self) -> ComponentNameKind<'_> {
+        use ComponentNameKind::*;
+        use ParsedComponentNameKind as PK;
+        match self.kind {
+            PK::Label => Label(KebabStr::new_unchecked(&self.raw)),
+            PK::Constructor => Constructor(KebabStr::new_unchecked(&self.raw[CONSTRUCTOR.len()..])),
+            PK::Method => Method(ResourceFunc(&self.raw[METHOD.len()..])),
+            PK::Static => Static(ResourceFunc(&self.raw[STATIC.len()..])),
+            PK::Interface => Interface(InterfaceName(&self.raw)),
+            PK::Dependency => Dependency(DependencyName(&self.raw)),
+            PK::Url => Url(UrlName(&self.raw)),
+            PK::Hash => Hash(HashName(&self.raw)),
         }
     }
 
@@ -378,153 +306,478 @@ impl KebabName {
     }
 }
 
-impl From<KebabName> for String {
-    fn from(name: KebabName) -> String {
+impl From<ComponentName> for String {
+    fn from(name: ComponentName) -> String {
         name.raw
     }
 }
 
-impl Hash for KebabName {
+impl Hash for ComponentName {
     fn hash<H: Hasher>(&self, hasher: &mut H) {
         self.kind().hash(hasher)
     }
 }
 
-impl PartialEq for KebabName {
-    fn eq(&self, other: &KebabName) -> bool {
+impl PartialEq for ComponentName {
+    fn eq(&self, other: &ComponentName) -> bool {
         self.kind().eq(&other.kind())
     }
 }
 
-impl Eq for KebabName {}
+impl Eq for ComponentName {}
 
-impl fmt::Display for KebabName {
+impl fmt::Display for ComponentName {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.raw.fmt(f)
     }
 }
 
-impl fmt::Debug for KebabName {
+impl fmt::Debug for ComponentName {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.raw.fmt(f)
     }
 }
 
-impl Hash for KebabNameKind<'_> {
+impl Hash for ComponentNameKind<'_> {
     fn hash<H: Hasher>(&self, hasher: &mut H) {
+        use ComponentNameKind::*;
         match self {
-            KebabNameKind::Normal(name) => {
-                hasher.write_u8(0);
-                name.hash(hasher);
-            }
-            KebabNameKind::Constructor(name) => {
-                hasher.write_u8(1);
-                name.hash(hasher);
-            }
+            Label(name) => (0u8, name).hash(hasher),
+            Constructor(name) => (1u8, name).hash(hasher),
             // for hashing method == static
-            KebabNameKind::Method { resource, name } | KebabNameKind::Static { resource, name } => {
-                hasher.write_u8(2);
-                resource.hash(hasher);
-                name.hash(hasher);
-            }
-            KebabNameKind::Id {
-                namespace,
-                package,
-                interface,
-                version,
-            } => {
-                hasher.write_u8(3);
-                namespace.hash(hasher);
-                package.hash(hasher);
-                interface.hash(hasher);
-                version.hash(hasher);
-            }
+            Method(name) | Static(name) => (2u8, name).hash(hasher),
+            Interface(name) => (3u8, name).hash(hasher),
+            Dependency(name) => (4u8, name).hash(hasher),
+            Url(name) => (5u8, name).hash(hasher),
+            Hash(name) => (6u8, name).hash(hasher),
         }
     }
 }
 
-impl PartialEq for KebabNameKind<'_> {
-    fn eq(&self, other: &KebabNameKind<'_>) -> bool {
+impl PartialEq for ComponentNameKind<'_> {
+    fn eq(&self, other: &ComponentNameKind<'_>) -> bool {
+        use ComponentNameKind::*;
         match (self, other) {
-            (KebabNameKind::Normal(a), KebabNameKind::Normal(b)) => a == b,
-            (KebabNameKind::Normal(_), _) => false,
-            (KebabNameKind::Constructor(a), KebabNameKind::Constructor(b)) => a == b,
-            (KebabNameKind::Constructor(_), _) => false,
+            (Label(a), Label(b)) => a == b,
+            (Label(_), _) => false,
+            (Constructor(a), Constructor(b)) => a == b,
+            (Constructor(_), _) => false,
 
             // method == static for the purposes of hashing so equate them here
             // as well.
-            (
-                KebabNameKind::Method {
-                    resource: ar,
-                    name: an,
-                },
-                KebabNameKind::Method {
-                    resource: br,
-                    name: bn,
-                },
-            )
-            | (
-                KebabNameKind::Static {
-                    resource: ar,
-                    name: an,
-                },
-                KebabNameKind::Static {
-                    resource: br,
-                    name: bn,
-                },
-            )
-            | (
-                KebabNameKind::Method {
-                    resource: ar,
-                    name: an,
-                },
-                KebabNameKind::Static {
-                    resource: br,
-                    name: bn,
-                },
-            )
-            | (
-                KebabNameKind::Static {
-                    resource: ar,
-                    name: an,
-                },
-                KebabNameKind::Method {
-                    resource: br,
-                    name: bn,
-                },
-            ) => ar == br && an == bn,
-
-            (KebabNameKind::Method { .. }, _) => false,
-            (KebabNameKind::Static { .. }, _) => false,
-
-            (
-                KebabNameKind::Id {
-                    namespace: an,
-                    package: ap,
-                    interface: ai,
-                    version: av,
-                },
-                KebabNameKind::Id {
-                    namespace: bn,
-                    package: bp,
-                    interface: bi,
-                    version: bv,
-                },
-            ) => an == bn && ap == bp && ai == bi && av == bv,
-            (KebabNameKind::Id { .. }, _) => false,
-        }
-    }
-}
-
-impl Eq for KebabNameKind<'_> {}
+            (Method(a), Method(b))
+            | (Static(a), Static(b))
+            | (Method(a), Static(b))
+            | (Static(a), Method(b)) => a == b,
+
+            (Method(_), _) => false,
+            (Static(_), _) => false,
+
+            (Interface(a), Interface(b)) => a == b,
+            (Interface(_), _) => false,
+            (Dependency(a), Dependency(b)) => a == b,
+            (Dependency(_), _) => false,
+            (Url(a), Url(b)) => a == b,
+            (Url(_), _) => false,
+            (Hash(a), Hash(b)) => a == b,
+            (Hash(_), _) => false,
+        }
+    }
+}
+
+impl Eq for ComponentNameKind<'_> {}
+
+/// A resource name and its function, stored as `a.b`.
+#[derive(Debug, Clone, Hash, Eq, PartialEq)]
+pub struct ResourceFunc<'a>(&'a str);
+
+impl<'a> ResourceFunc<'a> {
+    /// Returns the the underlying string as `a.b`
+    pub fn as_str(&self) -> &'a str {
+        self.0
+    }
+
+    /// Returns the resource name or the `a` in `a.b`
+    pub fn resource(&self) -> &'a KebabStr {
+        let dot = self.0.find('.').unwrap();
+        KebabStr::new_unchecked(&self.0[..dot])
+    }
+}
+
+/// An interface name, stored as `a:b/c@1.2.3`
+#[derive(Debug, Clone, Hash, Eq, PartialEq)]
+pub struct InterfaceName<'a>(&'a str);
+
+impl<'a> InterfaceName<'a> {
+    /// Returns the entire underlying string.
+    pub fn as_str(&self) -> &'a str {
+        self.0
+    }
+
+    /// Returns the `a` in `a:b/c`
+    pub fn namespace(&self) -> &'a KebabStr {
+        let colon = self.0.find(':').unwrap();
+        KebabStr::new_unchecked(&self.0[..colon])
+    }
+
+    /// Returns the `b` in `a:b/c`
+    pub fn package(&self) -> &'a KebabStr {
+        let colon = self.0.find(':').unwrap();
+        let slash = self.0.find('/').unwrap();
+        KebabStr::new_unchecked(&self.0[colon + 1..slash])
+    }
+
+    /// Returns the `c` in `a:b/c`
+    pub fn interface(&self) -> &'a KebabStr {
+        let slash = self.0.find('/').unwrap();
+        let at = self.0.find('@').unwrap_or(self.0.len());
+        KebabStr::new_unchecked(&self.0[slash + 1..at])
+    }
+
+    /// Returns the `1.2.3` in `a:b/c@1.2.3`
+    pub fn version(&self) -> Option<Version> {
+        let at = self.0.find('@')?;
+        Some(Version::parse(&self.0[at + 1..]).unwrap())
+    }
+}
+
+/// A dependency on an implementation either as `locked-dep=...` or
+/// `unlocked-dep=...`
+#[derive(Debug, Clone, Hash, Eq, PartialEq)]
+pub struct DependencyName<'a>(&'a str);
+
+impl<'a> DependencyName<'a> {
+    /// Returns entire underlying import string
+    pub fn as_str(&self) -> &'a str {
+        self.0
+    }
+}
+
+/// A dependency on an implementation either as `url=...` or
+/// `relative-url=...`
+#[derive(Debug, Clone, Hash, Eq, PartialEq)]
+pub struct UrlName<'a>(&'a str);
+
+impl<'a> UrlName<'a> {
+    /// Returns entire underlying import string
+    pub fn as_str(&self) -> &'a str {
+        self.0
+    }
+}
+
+/// A dependency on an implementation either as `integrity=...`.
+#[derive(Debug, Clone, Hash, Eq, PartialEq)]
+pub struct HashName<'a>(&'a str);
+
+impl<'a> HashName<'a> {
+    /// Returns entire underlying import string.
+    pub fn as_str(&self) -> &'a str {
+        self.0
+    }
+}
+
+// A small helper structure to parse `self.next` which is an import or export
+// name.
+//
+// Methods will update `self.next` as they go along and `self.offset` is used
+// for error messages.
+struct ComponentNameParser<'a> {
+    next: &'a str,
+    offset: usize,
+}
+
+impl<'a> ComponentNameParser<'a> {
+    fn parse(&mut self) -> Result<ParsedComponentNameKind> {
+        if self.eat_str(CONSTRUCTOR) {
+            self.expect_kebab()?;
+            return Ok(ParsedComponentNameKind::Constructor);
+        }
+        if self.eat_str(METHOD) {
+            let resource = self.take_until('.')?;
+            self.kebab(resource)?;
+            self.expect_kebab()?;
+            return Ok(ParsedComponentNameKind::Method);
+        }
+        if self.eat_str(STATIC) {
+            let resource = self.take_until('.')?;
+            self.kebab(resource)?;
+            self.expect_kebab()?;
+            return Ok(ParsedComponentNameKind::Static);
+        }
+
+        // 'unlocked-dep=<' <pkgidset> '>'
+        if self.eat_str("unlocked-dep=") {
+            self.expect_str("<")?;
+            self.pkgidset_up_to('>')?;
+            self.expect_str(">")?;
+            return Ok(ParsedComponentNameKind::Dependency);
+        }
+
+        // 'locked-dep=<' <pkgid> '>' ( ',' <hashname> )?
+        if self.eat_str("locked-dep=") {
+            self.expect_str("<")?;
+            self.pkgid_up_to('>')?;
+            self.expect_str(">")?;
+            self.eat_optional_hash()?;
+            return Ok(ParsedComponentNameKind::Dependency);
+        }
+
+        // 'url=<' <nonbrackets> '>' (',' <hashname>)?
+        if self.eat_str("url=") {
+            self.expect_str("<")?;
+            let _url = self.take_up_to('>')?;
+            self.expect_str(">")?;
+            self.eat_optional_hash()?;
+            return Ok(ParsedComponentNameKind::Url);
+        }
+        // 'relative-url=<' <nonbrackets> '>' (',' <hashname>)?
+        if self.eat_str("relative-url=") {
+            self.expect_str("<")?;
+            let _url = self.take_up_to('>')?;
+            self.expect_str(">")?;
+            self.eat_optional_hash()?;
+            return Ok(ParsedComponentNameKind::Url);
+        }
+
+        // 'integrity=<' <integrity-metadata> '>'
+        if self.eat_str("integrity=") {
+            self.expect_str("<")?;
+            let _hash = self.parse_hash()?;
+            self.expect_str(">")?;
+            return Ok(ParsedComponentNameKind::Hash);
+        }
+
+        match self.eat_until(':') {
+            // interfacename ::= <namespace> <label> <projection> <version>?
+            Some(namespace) => {
+                self.kebab(namespace)?;
+                let pkg = self.take_until('/')?;
+                self.kebab(pkg)?;
+                match self.eat_until('@') {
+                    Some(interface) => {
+                        self.kebab(interface)?;
+                        let version = self.take_rest();
+                        self.semver(version)?;
+                    }
+                    None => {
+                        self.expect_kebab()?;
+                    }
+                }
+                Ok(ParsedComponentNameKind::Interface)
+            }
+            None => {
+                self.expect_kebab()?;
+                Ok(ParsedComponentNameKind::Label)
+            }
+        }
+    }
+
+    // pkgidset      ::= <pkgname> <verrange>?
+    // pkgname       ::= <namespace> <label>
+    // verrange      ::= '@*'
+    //                 | '@{' <verlower> '}'
+    //                 | '@{' <verupper> '}'
+    //                 | '@{' <verlower> ' ' <verupper> '}'
+    // verlower      ::= '>=' <valid semver>
+    // verupper      ::= '<' <valid semver>
+    fn pkgidset_up_to(&mut self, end: char) -> Result<()> {
+        let namespace = self.take_until(':')?;
+        self.kebab(namespace)?;
+        let name = match self.eat_until('@') {
+            Some(name) => name,
+            // a:b
+            None => {
+                let name = self.take_up_to(end)?;
+                self.kebab(name)?;
+                return Ok(());
+            }
+        };
+        self.kebab(name)?;
+
+        // a:b@*
+        if self.eat_str("*") {
+            return Ok(());
+        }
+        self.expect_str("{")?;
+        if self.eat_str(">=") {
+            match self.eat_until(' ') {
+                Some(lower) => {
+                    self.semver(lower)?;
+                }
+                // a:b@{>=1.2.3}
+                None => {
+                    let lower = self.take_until('}')?;
+                    self.semver(lower)?;
+                    return Ok(());
+                }
+            }
+        }
+
+        // a:b@{<1.2.3}
+        // .. or
+        // a:b@{<1.2.3 >=1.2.3}
+        self.expect_str("<")?;
+        let version = self.take_until('}')?;
+        self.semver(version)?;
+        Ok(())
+    }
+
+    // pkgid         ::= <pkgname> <version>?
+    fn pkgid_up_to(&mut self, end: char) -> Result<()> {
+        let namespace = self.take_until(':')?;
+        self.kebab(namespace)?;
+        match self.eat_until('@') {
+            // a:b@1.2.3
+            Some(name) => {
+                self.kebab(name)?;
+                let version = self.take_up_to(end)?;
+                self.semver(version)?;
+            }
+            // a:b
+            None => {
+                let name = self.take_up_to(end)?;
+                self.kebab(name)?;
+            }
+        }
+        Ok(())
+    }
+
+    fn parse_hash(&mut self) -> Result<&'a str> {
+        let integrity = self.take_up_to('>')?;
+        let mut any = false;
+        for hash in integrity.split_whitespace() {
+            any = true;
+            let rest = hash
+                .strip_prefix("sha256")
+                .or_else(|| hash.strip_prefix("sha384"))
+                .or_else(|| hash.strip_prefix("sha512"));
+            let rest = match rest {
+                Some(s) => s,
+                None => bail!(self.offset, "unrecognized hash algorithm: `{hash}`"),
+            };
+            let rest = match rest.strip_prefix('-') {
+                Some(s) => s,
+                None => bail!(self.offset, "expected `-` after hash algorithm: {hash}"),
+            };
+            let (base64, _options) = match rest.find('?') {
+                Some(i) => (&rest[..i], Some(&rest[i + 1..])),
+                None => (rest, None),
+            };
+            if !is_base64(base64) {
+                bail!(self.offset, "not valid base64: `{base64}`");
+            }
+        }
+        if !any {
+            bail!(self.offset, "integrity hash cannot be empty");
+        }
+        Ok(integrity)
+    }
+
+    fn eat_optional_hash(&mut self) -> Result<Option<&'a str>> {
+        if !self.eat_str(",") {
+            return Ok(None);
+        }
+        self.expect_str("integrity=<")?;
+        let ret = self.parse_hash()?;
+        self.expect_str(">")?;
+        Ok(Some(ret))
+    }
+
+    fn eat_str(&mut self, prefix: &str) -> bool {
+        match self.next.strip_prefix(prefix) {
+            Some(rest) => {
+                self.next = rest;
+                true
+            }
+            None => false,
+        }
+    }
+
+    fn expect_str(&mut self, prefix: &str) -> Result<()> {
+        if self.eat_str(prefix) {
+            Ok(())
+        } else {
+            bail!(self.offset, "expected `{prefix}` at `{}`", self.next);
+        }
+    }
+
+    fn eat_until(&mut self, c: char) -> Option<&'a str> {
+        let ret = self.eat_up_to(c);
+        if ret.is_some() {
+            self.next = &self.next[c.len_utf8()..];
+        }
+        ret
+    }
+
+    fn eat_up_to(&mut self, c: char) -> Option<&'a str> {
+        let i = self.next.find(c)?;
+        let (a, b) = self.next.split_at(i);
+        self.next = b;
+        Some(a)
+    }
+
+    fn kebab(&self, s: &'a str) -> Result<&'a KebabStr> {
+        match KebabStr::new(s) {
+            Some(name) => Ok(name),
+            None => bail!(self.offset, "`{s}` is not in kebab case"),
+        }
+    }
+
+    fn semver(&self, s: &str) -> Result<Version> {
+        match Version::parse(s) {
+            Ok(v) => Ok(v),
+            Err(e) => bail!(self.offset, "`{s}` is not a valid semver: {e}"),
+        }
+    }
+
+    fn take_until(&mut self, c: char) -> Result<&'a str> {
+        match self.eat_until(c) {
+            Some(s) => Ok(s),
+            None => bail!(self.offset, "failed to find `{c}` character"),
+        }
+    }
+
+    fn take_up_to(&mut self, c: char) -> Result<&'a str> {
+        match self.eat_up_to(c) {
+            Some(s) => Ok(s),
+            None => bail!(self.offset, "failed to find `{c}` character"),
+        }
+    }
+
+    fn take_rest(&mut self) -> &'a str {
+        let ret = self.next;
+        self.next = "";
+        ret
+    }
+
+    fn expect_kebab(&mut self) -> Result<&'a KebabStr> {
+        let s = self.take_rest();
+        self.kebab(s)
+    }
+}
+
+fn is_base64(s: &str) -> bool {
+    if s.is_empty() {
+        return false;
+    }
+    let mut equals = 0;
+    for (i, byte) in s.as_bytes().iter().enumerate() {
+        match byte {
+            b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' | b'+' | b'/' if equals == 0 => {}
+            b'=' if i > 0 && equals < 2 => equals += 1,
+            _ => return false,
+        }
+    }
+    true
+}
 
 #[cfg(test)]
 mod tests {
     use super::*;
     use std::collections::HashSet;
 
-    fn parse_kebab_name(s: &str) -> Option<KebabName> {
-        KebabName::new(ComponentExternName::Kebab(s), 0).ok()
+    fn parse_kebab_name(s: &str) -> Option<ComponentName> {
+        ComponentName::new(s, 0).ok()
     }
 
     #[test]
diff --git a/crates/wasmprinter/src/lib.rs b/crates/wasmprinter/src/lib.rs
index a5cdc8cf..5483631e 100644
--- a/crates/wasmprinter/src/lib.rs
+++ b/crates/wasmprinter/src/lib.rs
@@ -1692,7 +1692,7 @@ impl Printer {
                 ComponentTypeDeclaration::Export { name, ty } => {
                     self.start_group("export ");
                     self.print_component_kind_name(states.last_mut().unwrap(), ty.kind())?;
-                    self.print_component_import_name(name.into())?;
+                    self.print_str(name.0)?;
                     self.result.push(' ');
                     self.print_component_import_ty(states.last_mut().unwrap(), &ty, false)?;
                     self.end_group();
@@ -1726,7 +1726,7 @@ impl Printer {
                 InstanceTypeDeclaration::Export { name, ty } => {
                     self.start_group("export ");
                     self.print_component_kind_name(states.last_mut().unwrap(), ty.kind())?;
-                    self.print_component_import_name(name.into())?;
+                    self.print_str(name.0)?;
                     self.result.push(' ');
                     self.print_component_import_ty(states.last_mut().unwrap(), &ty, false)?;
                     self.end_group();
@@ -1890,25 +1890,13 @@ impl Printer {
         index: bool,
     ) -> Result<()> {
         self.start_group("import ");
-        self.print_component_import_name(import.name)?;
+        self.print_str(import.name.0)?;
         self.result.push(' ');
         self.print_component_import_ty(state, &import.ty, index)?;
         self.end_group();
         Ok(())
     }
 
-    fn print_component_import_name(&mut self, name: ComponentExternName<'_>) -> Result<()> {
-        match name {
-            ComponentExternName::Kebab(s) => self.print_str(s),
-            ComponentExternName::Interface(s) => {
-                self.start_group("interface ");
-                self.print_str(s)?;
-                self.end_group();
-                Ok(())
-            }
-        }
-    }
-
     fn print_component_import_ty(
         &mut self,
         state: &mut State,
@@ -2017,7 +2005,7 @@ impl Printer {
         if named {
             self.print_component_kind_name(state, export.kind)?;
         }
-        self.print_component_import_name(export.name.into())?;
+        self.print_str(export.name.0)?;
         self.result.push(' ');
         self.print_component_external_kind(state, export.kind, export.index)?;
         if let Some(ty) = &export.ty {
diff --git a/crates/wast/src/component/binary.rs b/crates/wast/src/component/binary.rs
index 24e45893..a57cc0f9 100644
--- a/crates/wast/src/component/binary.rs
+++ b/crates/wast/src/component/binary.rs
@@ -274,7 +274,7 @@ impl<'a> Encoder<'a> {
             InstanceKind::BundleOfExports(exports) => {
                 self.instances.export_items(exports.iter().map(|e| {
                     let (kind, index) = (&e.kind).into();
-                    (e.name.into(), kind, index)
+                    (e.name.0, kind, index)
                 }));
             }
         }
@@ -353,10 +353,8 @@ impl<'a> Encoder<'a> {
     fn encode_import(&mut self, import: &ComponentImport<'a>) {
         let name = get_name(&import.item.id, &import.item.name);
         self.names_for_item_kind(&import.item.kind).push(name);
-        self.imports.import(
-            wasm_encoder::ComponentExternName::from(import.name),
-            (&import.item.kind).into(),
-        );
+        self.imports
+            .import(import.name.0, (&import.item.kind).into());
         self.flush(Some(self.imports.id()));
     }
 
@@ -364,7 +362,7 @@ impl<'a> Encoder<'a> {
         let name = get_name(&export.id, &export.debug_name);
         let (kind, index) = (&export.kind).into();
         self.exports.export(
-            wasm_encoder::ComponentExternName::from(export.name),
+            export.name.0,
             kind,
             index,
             export.ty.as_ref().map(|ty| (&ty.0.kind).into()),
@@ -833,16 +831,10 @@ impl From<&ComponentType<'_>> for wasm_encoder::ComponentType {
                     encoded.alias((&a.target).into());
                 }
                 ComponentTypeDecl::Import(i) => {
-                    encoded.import(
-                        wasm_encoder::ComponentExternName::from(i.name),
-                        (&i.item.kind).into(),
-                    );
+                    encoded.import(i.name.0, (&i.item.kind).into());
                 }
                 ComponentTypeDecl::Export(e) => {
-                    encoded.export(
-                        wasm_encoder::ComponentExternName::from(e.name),
-                        (&e.item.kind).into(),
-                    );
+                    encoded.export(e.name.0, (&e.item.kind).into());
                 }
             }
         }
@@ -867,10 +859,7 @@ impl From<&InstanceType<'_>> for wasm_encoder::InstanceType {
                     encoded.alias((&a.target).into());
                 }
                 InstanceTypeDecl::Export(e) => {
-                    encoded.export(
-                        wasm_encoder::ComponentExternName::from(e.name),
-                        (&e.item.kind).into(),
-                    );
+                    encoded.export(e.name.0, (&e.item.kind).into());
                 }
             }
         }
@@ -1013,12 +1002,3 @@ impl<'a> From<&AliasTarget<'a>> for wasm_encoder::Alias<'a> {
         }
     }
 }
-
-impl<'a> From<ComponentExternName<'a>> for wasm_encoder::ComponentExternName<'a> {
-    fn from(name: ComponentExternName<'a>) -> Self {
-        match name {
-            ComponentExternName::Kebab(name) => Self::Kebab(name),
-            ComponentExternName::Interface(name) => Self::Interface(name),
-        }
-    }
-}
diff --git a/crates/wast/src/component/import.rs b/crates/wast/src/component/import.rs
index 0b83f0ff..6689f4a7 100644
--- a/crates/wast/src/component/import.rs
+++ b/crates/wast/src/component/import.rs
@@ -25,23 +25,25 @@ impl<'a> Parse<'a> for ComponentImport<'a> {
 
 /// The different ways an import can be named.
 #[derive(Debug, Copy, Clone)]
-pub enum ComponentExternName<'a> {
-    /// This is a kebab-named import where a top-level name is assigned.
-    Kebab(&'a str),
-    /// This is an interface import where the string is an ID.
-    Interface(&'a str),
-}
+pub struct ComponentExternName<'a>(pub &'a str);
 
 impl<'a> Parse<'a> for ComponentExternName<'a> {
     fn parse(parser: Parser<'a>) -> Result<Self> {
-        if parser.peek::<LParen>()? {
-            Ok(ComponentExternName::Interface(parser.parens(|p| {
+        // Prior to WebAssembly/component-model#263 the syntactic form
+        // `(interface "...")` was supported for interface names. This is no
+        // longer part of the syntax of the binary format nor the text format,
+        // but continue to parse this as "sugar" for the current format. This
+        // is intended to avoid breaking folks and provide a smoother transition
+        // forward.
+        let name = if parser.peek::<LParen>()? {
+            parser.parens(|p| {
                 p.parse::<kw::interface>()?;
                 p.parse()
-            })?))
+            })?
         } else {
-            Ok(ComponentExternName::Kebab(parser.parse()?))
-        }
+            parser.parse()?
+        };
+        Ok(ComponentExternName(name))
     }
 }
 
diff --git a/crates/wit-component/src/decoding.rs b/crates/wit-component/src/decoding.rs
index 47064a11..c4888cfe 100644
--- a/crates/wit-component/src/decoding.rs
+++ b/crates/wit-component/src/decoding.rs
@@ -3,9 +3,9 @@ use indexmap::{IndexMap, IndexSet};
 use std::collections::HashMap;
 use std::mem;
 use wasmparser::{
-    names::{KebabName, KebabNameKind},
-    types, ComponentExport, ComponentExternName, ComponentExternalKind, ComponentImport, Parser,
-    Payload, PrimitiveValType, ValidPayload, Validator, WasmFeatures,
+    names::{ComponentName, ComponentNameKind},
+    types, ComponentExport, ComponentExternalKind, ComponentImport, Parser, Payload,
+    PrimitiveValType, ValidPayload, Validator, WasmFeatures,
 };
 use wit_parser::*;
 
@@ -17,7 +17,7 @@ struct ComponentInfo<'a> {
     /// validated.
     types: types::Types,
     /// List of all imports and exports from this component.
-    externs: Vec<(ComponentExternName<'a>, Extern<'a>)>,
+    externs: Vec<(&'a str, Extern<'a>)>,
     /// Decoded package docs
     package_docs: Option<PackageDocs>,
 }
@@ -61,13 +61,13 @@ impl<'a> ComponentInfo<'a> {
                 Payload::ComponentImportSection(s) if depth == 1 => {
                     for import in s {
                         let import = import?;
-                        externs.push((import.name, Extern::Import(import)));
+                        externs.push((import.name.0, Extern::Import(import)));
                     }
                 }
                 Payload::ComponentExportSection(s) if depth == 1 => {
                     for export in s {
                         let export = export?;
-                        externs.push((export.name, Extern::Export(export)));
+                        externs.push((export.name.0, Extern::Export(export)));
                     }
                 }
                 Payload::CustomSection(s) if s.name() == PACKAGE_DOCS_SECTION_NAME => {
@@ -113,11 +113,11 @@ impl<'a> ComponentInfo<'a> {
         // strings for each component. The v1 format uses "<namespace>:<package>/wit" as the name
         // for the top-level exports, while the v2 format uses the unqualified name of the encoded
         // entity.
-        match KebabName::new(self.externs[0].0, 0).ok()?.kind() {
-            KebabNameKind::Id { interface, .. } if interface.as_str() == "wit" => {
+        match ComponentName::new(self.externs[0].0, 0).ok()?.kind() {
+            ComponentNameKind::Interface(name) if name.interface().as_str() == "wit" => {
                 Some(WitEncodingVersion::V1)
             }
-            KebabNameKind::Normal(_) => Some(WitEncodingVersion::V2),
+            ComponentNameKind::Label(_) => Some(WitEncodingVersion::V2),
             _ => None,
         }
     }
@@ -145,7 +145,7 @@ impl<'a> ComponentInfo<'a> {
             if pkg.is_some() {
                 bail!("more than one top-level exported component type found");
             }
-            let name = KebabName::new(*name, 0).unwrap();
+            let name = ComponentName::new(*name, 0).unwrap();
             pkg = Some(
                 decoder
                     .decode_v1_package(&name, ty)
@@ -399,7 +399,7 @@ struct WitPackageDecoder<'a> {
 impl WitPackageDecoder<'_> {
     fn decode_v1_package(
         &mut self,
-        name: &KebabName,
+        name: &ComponentName,
         ty: &types::ComponentType,
     ) -> Result<Package> {
         // Process all imports for this package first, where imports are
@@ -418,16 +418,9 @@ impl WitPackageDecoder<'_> {
             // where "wit" is just a placeholder for now. The package name in
             // this case would be `foo:bar`.
             name: match name.kind() {
-                KebabNameKind::Id {
-                    namespace,
-                    package,
-                    version,
-                    interface,
-                } if interface.as_str() == "wit" => PackageName {
-                    namespace: namespace.to_string(),
-                    name: package.to_string(),
-                    version,
-                },
+                ComponentNameKind::Interface(name) if name.interface().as_str() == "wit" => {
+                    name.to_package_name()
+                }
                 _ => bail!("package name is not a valid id: {name}"),
             },
             docs: Default::default(),
@@ -465,21 +458,12 @@ impl WitPackageDecoder<'_> {
         ty: &types::ComponentInstanceType,
         fields: &mut PackageFields<'a>,
     ) -> Result<PackageName> {
-        let kebab_name = self
-            .extract_kebab_name(name)
+        let component_name = self
+            .parse_component_name(name)
             .context("expected world name to have an ID form")?;
 
-        let package = match kebab_name.kind() {
-            KebabNameKind::Id {
-                namespace,
-                package,
-                version,
-                ..
-            } => PackageName {
-                namespace: namespace.to_string(),
-                name: package.to_string(),
-                version,
-            },
+        let package = match component_name.kind() {
+            ComponentNameKind::Interface(name) => name.to_package_name(),
             _ => bail!("expected world name to be fully qualified"),
         };
 
@@ -504,20 +488,11 @@ impl WitPackageDecoder<'_> {
         fields: &mut PackageFields<'a>,
     ) -> Result<PackageName> {
         let kebab_name = self
-            .extract_kebab_name(name)
+            .parse_component_name(name)
             .context("expected world name to have an ID form")?;
 
         let package = match kebab_name.kind() {
-            KebabNameKind::Id {
-                namespace,
-                package,
-                version,
-                ..
-            } => PackageName {
-                namespace: namespace.to_string(),
-                name: package.to_string(),
-                version,
-            },
+            ComponentNameKind::Interface(name) => name.to_package_name(),
             _ => bail!("expected world name to be fully qualified"),
         };
 
@@ -532,12 +507,12 @@ impl WitPackageDecoder<'_> {
         world: WorldId,
         package: &mut PackageFields<'a>,
     ) -> Result<()> {
-        let name = import.name.as_str();
+        let name = import.name.0;
         log::debug!("decoding component import `{name}`");
         let ty = self
             .info
             .types
-            .component_entity_type_of_import(import.name.as_str())
+            .component_entity_type_of_import(name)
             .unwrap();
         let owner = TypeOwner::World(world);
         let (name, item) = match ty {
@@ -581,7 +556,7 @@ impl WitPackageDecoder<'_> {
         world: WorldId,
         package: &mut PackageFields<'a>,
     ) -> Result<()> {
-        let name = export.name.as_str();
+        let name = export.name.0;
         log::debug!("decoding component export `{name}`");
         let types = &self.info.types;
         let ty = types.component_entity_type_of_export(name).unwrap();
@@ -757,26 +732,12 @@ impl WitPackageDecoder<'_> {
     /// This will parse the `name_string` as a component model ID string and
     /// ensure that there's an `InterfaceId` corresponding to its components.
     fn extract_dep_interface(&mut self, name_string: &str) -> Result<InterfaceId> {
-        let import_name = if name_string.contains('/') {
-            ComponentExternName::Interface(name_string)
-        } else {
-            ComponentExternName::Kebab(name_string)
-        };
-        let name = KebabName::new(import_name, 0).unwrap();
-        let (namespace, name, version, interface) = match name.kind() {
-            KebabNameKind::Id {
-                namespace,
-                package,
-                version,
-                interface,
-            } => (namespace, package, version, interface),
+        let name = ComponentName::new(name_string, 0).unwrap();
+        let name = match name.kind() {
+            ComponentNameKind::Interface(name) => name,
             _ => bail!("package name is not a valid id: {name_string}"),
         };
-        let package_name = PackageName {
-            name: name.to_string(),
-            namespace: namespace.to_string(),
-            version,
-        };
+        let package_name = name.to_package_name();
         // Lazily create a `Package` as necessary, along with the interface.
         let package = self
             .foreign_packages
@@ -789,10 +750,10 @@ impl WitPackageDecoder<'_> {
             });
         let interface = *package
             .interfaces
-            .entry(interface.to_string())
+            .entry(name.interface().to_string())
             .or_insert_with(|| {
                 self.resolve.interfaces.alloc(Interface {
-                    name: Some(interface.to_string()),
+                    name: Some(name.interface().to_string()),
                     docs: Default::default(),
                     types: IndexMap::default(),
                     functions: IndexMap::new(),
@@ -843,7 +804,7 @@ impl WitPackageDecoder<'_> {
         // If this is a bare kebab-name for an interface then the interface's
         // listed name is `None` and the name goes out through the key.
         // Otherwise this name is extracted from `name` interpreted as an ID.
-        let interface_name = self.extract_interface_name_from_kebab_name(name)?;
+        let interface_name = self.extract_interface_name_from_component_name(name)?;
 
         let mut interface = Interface {
             name: interface_name.clone(),
@@ -898,21 +859,16 @@ impl WitPackageDecoder<'_> {
         Ok((key, id))
     }
 
-    fn extract_kebab_name(&self, name: &str) -> Result<KebabName> {
-        let import_name = if name.contains('/') {
-            ComponentExternName::Interface(name)
-        } else {
-            ComponentExternName::Kebab(name)
-        };
-        KebabName::new(import_name, 0)
+    fn parse_component_name(&self, name: &str) -> Result<ComponentName> {
+        ComponentName::new(name, 0)
             .with_context(|| format!("cannot extract item name from: {name}"))
     }
 
-    fn extract_interface_name_from_kebab_name(&self, name: &str) -> Result<Option<String>> {
-        let kebab_name = self.extract_kebab_name(name)?;
-        match kebab_name.kind() {
-            KebabNameKind::Id { interface, .. } => Ok(Some(interface.to_string())),
-            KebabNameKind::Normal(_name) => Ok(None),
+    fn extract_interface_name_from_component_name(&self, name: &str) -> Result<Option<String>> {
+        let component_name = self.parse_component_name(name)?;
+        match component_name.kind() {
+            ComponentNameKind::Interface(name) => Ok(Some(name.interface().to_string())),
+            ComponentNameKind::Label(_name) => Ok(None),
             _ => bail!("cannot extract item name from: {name}"),
         }
     }
@@ -977,7 +933,7 @@ impl WitPackageDecoder<'_> {
         package: &mut PackageFields<'a>,
     ) -> Result<WorldId> {
         let name = self
-            .extract_interface_name_from_kebab_name(name)?
+            .extract_interface_name_from_component_name(name)?
             .context("expected world name to have an ID form")?;
         let mut world = World {
             name: name.clone(),
@@ -1068,7 +1024,7 @@ impl WitPackageDecoder<'_> {
         ty: &types::ComponentFuncType,
         owner: TypeOwner,
     ) -> Result<Function> {
-        let name = KebabName::new(ComponentExternName::Kebab(name), 0).unwrap();
+        let name = ComponentName::new(name, 0).unwrap();
         let params = ty
             .params
             .iter()
@@ -1097,19 +1053,22 @@ impl WitPackageDecoder<'_> {
         Ok(Function {
             docs: Default::default(),
             kind: match name.kind() {
-                KebabNameKind::Normal(_) => FunctionKind::Freestanding,
-                KebabNameKind::Constructor(resource) => {
+                ComponentNameKind::Label(_) => FunctionKind::Freestanding,
+                ComponentNameKind::Constructor(resource) => {
                     FunctionKind::Constructor(self.resources[&owner][resource.as_str()])
                 }
-                KebabNameKind::Method { resource, .. } => {
-                    FunctionKind::Method(self.resources[&owner][resource.as_str()])
+                ComponentNameKind::Method(name) => {
+                    FunctionKind::Method(self.resources[&owner][name.resource().as_str()])
                 }
-                KebabNameKind::Static { resource, .. } => {
-                    FunctionKind::Static(self.resources[&owner][resource.as_str()])
+                ComponentNameKind::Static(name) => {
+                    FunctionKind::Static(self.resources[&owner][name.resource().as_str()])
                 }
 
                 // Functions shouldn't have ID-based names at this time.
-                KebabNameKind::Id { .. } => unreachable!(),
+                ComponentNameKind::Interface(_)
+                | ComponentNameKind::Url(_)
+                | ComponentNameKind::Hash(_)
+                | ComponentNameKind::Dependency(_) => unreachable!(),
             },
 
             // Note that this name includes "name mangling" such as
@@ -1632,3 +1591,17 @@ impl Registrar<'_> {
         Ok(())
     }
 }
+
+pub(crate) trait InterfaceNameExt {
+    fn to_package_name(&self) -> PackageName;
+}
+
+impl InterfaceNameExt for wasmparser::names::InterfaceName<'_> {
+    fn to_package_name(&self) -> PackageName {
+        PackageName {
+            namespace: self.namespace().to_string(),
+            name: self.package().to_string(),
+            version: self.version(),
+        }
+    }
+}
diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs
index 2548940f..de9b344e 100644
--- a/crates/wit-component/src/validation.rs
+++ b/crates/wit-component/src/validation.rs
@@ -1,15 +1,16 @@
+use crate::decoding::InterfaceNameExt;
 use crate::metadata::{Bindgen, ModuleMetadata};
 use anyhow::{bail, Context, Result};
 use indexmap::{map::Entry, IndexMap, IndexSet};
 use std::mem;
-use wasmparser::names::{KebabName, KebabNameKind};
+use wasmparser::names::{ComponentName, ComponentNameKind};
 use wasmparser::{
-    types::Types, ComponentExternName, Encoding, ExternalKind, FuncType, Parser, Payload, TypeRef,
-    ValType, ValidPayload, Validator,
+    types::Types, Encoding, ExternalKind, FuncType, Parser, Payload, TypeRef, ValType,
+    ValidPayload, Validator,
 };
 use wit_parser::{
     abi::{AbiVariant, WasmSignature, WasmType},
-    Function, InterfaceId, PackageName, Resolve, TypeDefKind, TypeId, WorldId, WorldItem, WorldKey,
+    Function, InterfaceId, Resolve, TypeDefKind, TypeId, WorldId, WorldItem, WorldKey,
 };
 
 fn is_canonical_function(name: &str) -> bool {
@@ -567,27 +568,12 @@ pub fn validate_adapter_module<'a>(
 }
 
 fn world_key(resolve: &Resolve, name: &str) -> WorldKey {
-    let name = if name.contains('/') {
-        ComponentExternName::Interface(name)
-    } else {
-        ComponentExternName::Kebab(name)
-    };
-    let kebab_name = KebabName::new(name, 0);
+    let kebab_name = ComponentName::new(name, 0);
     let (pkgname, interface) = match kebab_name.as_ref().map(|k| k.kind()) {
-        Ok(KebabNameKind::Id {
-            namespace,
-            package,
-            version,
-            interface,
-        }) => (
-            PackageName {
-                namespace: namespace.as_str().to_string(),
-                name: package.as_str().to_string(),
-                version,
-            },
-            interface.as_str(),
-        ),
-        _ => return WorldKey::Name(name.as_str().to_string()),
+        Ok(ComponentNameKind::Interface(name)) => {
+            (name.to_package_name(), name.interface().as_str())
+        }
+        _ => return WorldKey::Name(name.to_string()),
     };
     match resolve
         .package_names
@@ -595,7 +581,7 @@ fn world_key(resolve: &Resolve, name: &str) -> WorldKey {
         .and_then(|p| resolve.packages[*p].interfaces.get(interface))
     {
         Some(id) => WorldKey::Interface(*id),
-        None => WorldKey::Name(name.as_str().to_string()),
+        None => WorldKey::Name(name.to_string()),
     }
 }
 


Test patch:
diff --git a/crates/wasm-compose/tests/compositions/defs/composed.wat b/crates/wasm-compose/tests/compositions/defs/composed.wat
index 16b1d39d..a33b8b02 100644
--- a/crates/wasm-compose/tests/compositions/defs/composed.wat
+++ b/crates/wasm-compose/tests/compositions/defs/composed.wat
@@ -11,7 +11,7 @@
         (export (;1;) "get-arguments" (func (type 4)))
       )
     )
-    (import (interface "wasi:cli-base/environment") (instance (;0;) (type 0)))
+    (import "wasi:cli-base/environment" (instance (;0;) (type 0)))
     (type (;1;)
       (instance)
     )
@@ -164,7 +164,7 @@
         (with "import-func-get-arguments" (func 1))
       )
     )
-    (export (;1;) (interface "wasi:cli-base/environment") (instance 0))
+    (export (;1;) "wasi:cli-base/environment" (instance 0))
   )
   (component (;2;)
     (instance (;0;))
diff --git a/crates/wasm-compose/tests/compositions/type-use/composed.wat b/crates/wasm-compose/tests/compositions/type-use/composed.wat
index 18e2cd7a..8324e255 100644
--- a/crates/wasm-compose/tests/compositions/type-use/composed.wat
+++ b/crates/wasm-compose/tests/compositions/type-use/composed.wat
@@ -7,7 +7,7 @@
       (export (;3;) "r2" (type (eq 2)))
     )
   )
-  (import (interface "a:b/type-def") (instance (;0;) (type 0)))
+  (import "a:b/type-def" (instance (;0;) (type 0)))
   (alias export 0 "r1" (type (;1;)))
   (alias export 0 "r2" (type (;2;)))
   (type (;3;)
@@ -18,7 +18,7 @@
       (export (;3;) "r2" (type (eq 2)))
     )
   )
-  (import (interface "a:b/type-use") (instance (;1;) (type 3)))
+  (import "a:b/type-use" (instance (;1;) (type 3)))
   (type (;4;)
     (instance
       (type (;0;) u32)
@@ -26,14 +26,14 @@
       (export (;2;) "t2" (type (eq 1)))
     )
   )
-  (import (interface "a:b/type-use-in-same-interface") (instance (;2;) (type 4)))
+  (import "a:b/type-use-in-same-interface" (instance (;2;) (type 4)))
   (type (;5;)
     (instance
       (type (;0;) u32)
       (export (;1;) "t" (type (eq 0)))
     )
   )
-  (import (interface "a:b/diamond-base") (instance (;3;) (type 5)))
+  (import "a:b/diamond-base" (instance (;3;) (type 5)))
   (alias export 3 "t" (type (;6;)))
   (type (;7;)
     (instance
@@ -41,7 +41,7 @@
       (export (;1;) "t" (type (eq 0)))
     )
   )
-  (import (interface "a:b/diamond1") (instance (;4;) (type 7)))
+  (import "a:b/diamond1" (instance (;4;) (type 7)))
   (alias export 3 "t" (type (;8;)))
   (type (;9;)
     (instance
@@ -49,7 +49,7 @@
       (export (;1;) "t" (type (eq 0)))
     )
   )
-  (import (interface "a:b/diamond2") (instance (;5;) (type 9)))
+  (import "a:b/diamond2" (instance (;5;) (type 9)))
   (alias export 4 "t" (type (;10;)))
   (alias export 5 "t" (type (;11;)))
   (type (;12;)
@@ -60,7 +60,7 @@
       (export (;3;) "t2" (type (eq 2)))
     )
   )
-  (import (interface "a:b/diamond-join") (instance (;6;) (type 12)))
+  (import "a:b/diamond-join" (instance (;6;) (type 12)))
   (component (;0;)
     (type (;0;)
       (instance)
@@ -76,7 +76,7 @@
         (export (;3;) "r2" (type (eq 2)))
       )
     )
-    (import (interface "a:b/type-def") (instance $type-def (;0;) (type 0)))
+    (import "a:b/type-def" (instance $type-def (;0;) (type 0)))
     (alias export $type-def "r1" (type $r1 (;1;)))
     (alias export $type-def "r2" (type $r2 (;2;)))
     (type (;3;)
@@ -87,7 +87,7 @@
         (export (;3;) "r2" (type (eq 2)))
       )
     )
-    (import (interface "a:b/type-use") (instance (;1;) (type 3)))
+    (import "a:b/type-use" (instance (;1;) (type 3)))
     (type (;4;)
       (instance
         (type (;0;) u32)
@@ -95,14 +95,14 @@
         (export (;2;) "t2" (type (eq 1)))
       )
     )
-    (import (interface "a:b/type-use-in-same-interface") (instance (;2;) (type 4)))
+    (import "a:b/type-use-in-same-interface" (instance (;2;) (type 4)))
     (type (;5;)
       (instance
         (type (;0;) u32)
         (export (;1;) "t" (type (eq 0)))
       )
     )
-    (import (interface "a:b/diamond-base") (instance $diamond-base (;3;) (type 5)))
+    (import "a:b/diamond-base" (instance $diamond-base (;3;) (type 5)))
     (alias export $diamond-base "t" (type $t-diamond-base (;6;)))
     (type (;7;)
       (instance
@@ -110,14 +110,14 @@
         (export (;1;) "t" (type (eq 0)))
       )
     )
-    (import (interface "a:b/diamond1") (instance $diamond1 (;4;) (type 7)))
+    (import "a:b/diamond1" (instance $diamond1 (;4;) (type 7)))
     (type (;8;)
       (instance
         (alias outer 1 $t-diamond-base (type (;0;)))
         (export (;1;) "t" (type (eq 0)))
       )
     )
-    (import (interface "a:b/diamond2") (instance $diamond2 (;5;) (type 8)))
+    (import "a:b/diamond2" (instance $diamond2 (;5;) (type 8)))
     (alias export $diamond1 "t" (type $t-diamond1 (;9;)))
     (alias export $diamond2 "t" (type $t-diamond2 (;10;)))
     (type (;11;)
@@ -128,7 +128,7 @@
         (export (;3;) "t2" (type (eq 2)))
       )
     )
-    (import (interface "a:b/diamond-join") (instance (;6;) (type 11)))
+    (import "a:b/diamond-join" (instance (;6;) (type 11)))
   )
   (instance (;7;) (instantiate 1
       (with "a:b/type-def" (instance 0))
diff --git a/crates/wit-component/tests/components/adapt-export-namespaced/component.wat b/crates/wit-component/tests/components/adapt-export-namespaced/component.wat
index 516cfada..656d7bca 100644
--- a/crates/wit-component/tests/components/adapt-export-namespaced/component.wat
+++ b/crates/wit-component/tests/components/adapt-export-namespaced/component.wat
@@ -35,7 +35,7 @@
       (with "import-func-entrypoint" (func 0))
     )
   )
-  (export (;1;) (interface "foo:foo/new") (instance 0))
+  (export (;1;) "foo:foo/new" (instance 0))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat b/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat
index 1f87b438..6800b2e0 100644
--- a/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat
+++ b/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat
@@ -95,7 +95,7 @@
       (with "import-func-foo" (func 0))
     )
   )
-  (export (;1;) (interface "foo:foo/new") (instance 0))
+  (export (;1;) "foo:foo/new" (instance 0))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat
index a2689c01..5042b4f4 100644
--- a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat
+++ b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "foo" (func (type 0)))
     )
   )
-  (import (interface "foo:foo/adapter-imports") (instance (;0;) (type 0)))
+  (import "foo:foo/adapter-imports" (instance (;0;) (type 0)))
   (type (;1;) (func (param "x" string)))
   (import "foo" (func (;0;) (type 1)))
   (core module (;0;)
diff --git a/crates/wit-component/tests/components/adapt-preview1/component.wat b/crates/wit-component/tests/components/adapt-preview1/component.wat
index 31c1410b..06f007c5 100644
--- a/crates/wit-component/tests/components/adapt-preview1/component.wat
+++ b/crates/wit-component/tests/components/adapt-preview1/component.wat
@@ -12,7 +12,7 @@
       (export (;0;) "proc-exit" (func (type 0)))
     )
   )
-  (import (interface "foo:foo/my-wasi") (instance (;1;) (type 1)))
+  (import "foo:foo/my-wasi" (instance (;1;) (type 1)))
   (core module (;0;)
     (type (;0;) (func))
     (type (;1;) (func (param i32)))
diff --git a/crates/wit-component/tests/components/ensure-default-type-exports/component.wat b/crates/wit-component/tests/components/ensure-default-type-exports/component.wat
index 5c1b5670..2420a53a 100644
--- a/crates/wit-component/tests/components/ensure-default-type-exports/component.wat
+++ b/crates/wit-component/tests/components/ensure-default-type-exports/component.wat
@@ -9,7 +9,7 @@
       (export (;0;) "a" (func (type 4)))
     )
   )
-  (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+  (import "foo:foo/foo" (instance (;0;) (type 0)))
   (core module (;0;)
     (type (;0;) (func (param i32)))
     (type (;1;) (func (param i32 i32 i32 i32) (result i32)))
diff --git a/crates/wit-component/tests/components/export-interface-using-import/component.wat b/crates/wit-component/tests/components/export-interface-using-import/component.wat
index 27571287..cbb72807 100644
--- a/crates/wit-component/tests/components/export-interface-using-import/component.wat
+++ b/crates/wit-component/tests/components/export-interface-using-import/component.wat
@@ -7,7 +7,7 @@
       (export (;3;) "r" (type (eq 2)))
     )
   )
-  (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+  (import "foo:foo/foo" (instance (;0;) (type 0)))
   (core module (;0;)
     (@producers
       (processed-by "wit-component" "$CARGO_PKG_VERSION")
diff --git a/crates/wit-component/tests/components/export-name-shuffling/component.wat b/crates/wit-component/tests/components/export-name-shuffling/component.wat
index 64c505a0..a767376c 100644
--- a/crates/wit-component/tests/components/export-name-shuffling/component.wat
+++ b/crates/wit-component/tests/components/export-name-shuffling/component.wat
@@ -14,7 +14,7 @@
     (export (;1;) "foo" (type 0))
   )
   (instance (;0;) (instantiate 0))
-  (export (;1;) (interface "foo:foo/name") (instance 0))
+  (export (;1;) "foo:foo/name" (instance 0))
   (alias export 1 "foo" (type (;0;)))
   (type (;1;) (func (param "f" 0)))
   (alias core export 0 "name#a" (core func (;0;)))
diff --git a/crates/wit-component/tests/components/export-type-name-conflict/component.wat b/crates/wit-component/tests/components/export-type-name-conflict/component.wat
index 8864fd4c..dea717da 100644
--- a/crates/wit-component/tests/components/export-type-name-conflict/component.wat
+++ b/crates/wit-component/tests/components/export-type-name-conflict/component.wat
@@ -5,7 +5,7 @@
       (export (;1;) "foo" (type (eq 0)))
     )
   )
-  (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+  (import "foo:foo/foo" (instance (;0;) (type 0)))
   (core module (;0;)
     (type (;0;) (func (result i32)))
     (func (;0;) (type 0) (result i32)
diff --git a/crates/wit-component/tests/components/export-with-type-alias/component.wat b/crates/wit-component/tests/components/export-with-type-alias/component.wat
index b9677138..2a06cf62 100644
--- a/crates/wit-component/tests/components/export-with-type-alias/component.wat
+++ b/crates/wit-component/tests/components/export-with-type-alias/component.wat
@@ -33,7 +33,7 @@
       (with "import-type-b" (type 0))
     )
   )
-  (export (;1;) (interface "foo:foo/foo") (instance 0))
+  (export (;1;) "foo:foo/foo" (instance 0))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/import-and-export-resource/component.wat b/crates/wit-component/tests/components/import-and-export-resource/component.wat
index 7b6d6d40..74a42251 100644
--- a/crates/wit-component/tests/components/import-and-export-resource/component.wat
+++ b/crates/wit-component/tests/components/import-and-export-resource/component.wat
@@ -4,7 +4,7 @@
       (export (;0;) "a" (type (sub resource)))
     )
   )
-  (import (interface "foo:bar/foo") (instance (;0;) (type 0)))
+  (import "foo:bar/foo" (instance (;0;) (type 0)))
   (alias export 0 "a" (type (;1;)))
   (import "a" (type (;2;) (eq 1)))
   (core module (;0;)
@@ -46,7 +46,7 @@
       (with "import-type-a" (type 4))
     )
   )
-  (export (;2;) (interface "foo:bar/foo") (instance 1))
+  (export (;2;) "foo:bar/foo" (instance 1))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/import-conflict/component.wat b/crates/wit-component/tests/components/import-conflict/component.wat
index 6025efad..aa7762c6 100644
--- a/crates/wit-component/tests/components/import-conflict/component.wat
+++ b/crates/wit-component/tests/components/import-conflict/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "a" (func (type 0)))
     )
   )
-  (import (interface "foo:foo/bar") (instance (;0;) (type 0)))
+  (import "foo:foo/bar" (instance (;0;) (type 0)))
   (type (;1;)
     (instance
       (type (;0;) (list u8))
@@ -13,14 +13,14 @@
       (export (;0;) "baz" (func (type 1)))
     )
   )
-  (import (interface "foo:foo/baz") (instance (;1;) (type 1)))
+  (import "foo:foo/baz" (instance (;1;) (type 1)))
   (type (;2;)
     (instance
       (type (;0;) (func))
       (export (;0;) "a" (func (type 0)))
     )
   )
-  (import (interface "foo:foo/foo") (instance (;2;) (type 2)))
+  (import "foo:foo/foo" (instance (;2;) (type 2)))
   (core module (;0;)
     (type (;0;) (func))
     (type (;1;) (func (param i64 i32 i32)))
diff --git a/crates/wit-component/tests/components/import-export-same-iface-name/component.wat b/crates/wit-component/tests/components/import-export-same-iface-name/component.wat
index d1708516..bab67bc8 100644
--- a/crates/wit-component/tests/components/import-export-same-iface-name/component.wat
+++ b/crates/wit-component/tests/components/import-export-same-iface-name/component.wat
@@ -5,14 +5,14 @@
       (export (;0;) "a" (func (type 0)))
     )
   )
-  (import (interface "foo:dep/the-name") (instance (;0;) (type 0)))
+  (import "foo:dep/the-name" (instance (;0;) (type 0)))
   (type (;1;)
     (instance
       (type (;0;) (func))
       (export (;0;) "a" (func (type 0)))
     )
   )
-  (import (interface "foo:foo/the-name") (instance (;1;) (type 1)))
+  (import "foo:foo/the-name" (instance (;1;) (type 1)))
   (core module (;0;)
     (type (;0;) (func))
     (import "foo:dep/the-name" "a" (func (;0;) (type 0)))
@@ -52,7 +52,7 @@
       (with "import-func-a" (func 2))
     )
   )
-  (export (;3;) (interface "foo:foo/the-name") (instance 2))
+  (export (;3;) "foo:foo/the-name" (instance 2))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat b/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat
index 8d038927..45443464 100644
--- a/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat
+++ b/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat
@@ -11,14 +11,14 @@
       (export (;5;) "g3" (func (type 1)))
     )
   )
-  (import (interface "foo:shared-dependency/doc") (instance (;0;) (type 0)))
+  (import "foo:shared-dependency/doc" (instance (;0;) (type 0)))
   (type (;1;)
     (instance
       (type (;0;) u32)
       (export (;1;) "a-typedef" (type (eq 0)))
     )
   )
-  (import (interface "foo:shared-dependency/types") (instance (;1;) (type 1)))
+  (import "foo:shared-dependency/types" (instance (;1;) (type 1)))
   (alias export 1 "a-typedef" (type (;2;)))
   (type (;3;)
     (instance
diff --git a/crates/wit-component/tests/components/import-partial-export-full/component.wat b/crates/wit-component/tests/components/import-partial-export-full/component.wat
index 3c933901..7997a1ce 100644
--- a/crates/wit-component/tests/components/import-partial-export-full/component.wat
+++ b/crates/wit-component/tests/components/import-partial-export-full/component.wat
@@ -6,7 +6,7 @@
       (export (;2;) "name" (type (eq 1)))
     )
   )
-  (import (interface "a:b/name") (instance (;0;) (type 0)))
+  (import "a:b/name" (instance (;0;) (type 0)))
   (alias export 0 "name" (type (;1;)))
   (import "name" (type (;2;) (eq 1)))
   (core module (;0;)
@@ -24,7 +24,7 @@
     (export (;4;) "name" (type 3))
   )
   (instance (;1;) (instantiate 0))
-  (export (;2;) (interface "a:b/name") (instance 1))
+  (export (;2;) "a:b/name" (instance 1))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/lift-options/component.wat b/crates/wit-component/tests/components/lift-options/component.wat
index f7095db9..d03a52a9 100644
--- a/crates/wit-component/tests/components/lift-options/component.wat
+++ b/crates/wit-component/tests/components/lift-options/component.wat
@@ -279,7 +279,7 @@
       (with "import-type-v-no-string" (type 9))
     )
   )
-  (export (;1;) (interface "foo:foo/my-default") (instance 0))
+  (export (;1;) "foo:foo/my-default" (instance 0))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/link-circular/component.wat b/crates/wit-component/tests/components/link-circular/component.wat
index 23633772..f8aadfcc 100644
--- a/crates/wit-component/tests/components/link-circular/component.wat
+++ b/crates/wit-component/tests/components/link-circular/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "foo" (func (type 0)))
     )
   )
-  (import (interface "test:test/test") (instance (;0;) (type 0)))
+  (import "test:test/test" (instance (;0;) (type 0)))
   (core module (;0;)
     (type (;0;) (func (param i32) (result i32)))
     (func (;0;) (type 0) (param i32) (result i32)
@@ -162,7 +162,7 @@
       (with "import-func-foo" (func 1))
     )
   )
-  (export (;2;) (interface "test:test/test") (instance 1))
+  (export (;2;) "test:test/test" (instance 1))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/link-dl-openable/component.wat b/crates/wit-component/tests/components/link-dl-openable/component.wat
index 2ce93d8f..05b4a4f7 100644
--- a/crates/wit-component/tests/components/link-dl-openable/component.wat
+++ b/crates/wit-component/tests/components/link-dl-openable/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "foo" (func (type 0)))
     )
   )
-  (import (interface "test:test/test") (instance (;0;) (type 0)))
+  (import "test:test/test" (instance (;0;) (type 0)))
   (core module (;0;)
     (table (;0;) 3 funcref)
     (memory (;0;) 17)
@@ -119,7 +119,7 @@
       (with "import-func-foo" (func 1))
     )
   )
-  (export (;2;) (interface "test:test/test") (instance 1))
+  (export (;2;) "test:test/test" (instance 1))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/link-duplicate-symbols/component.wat b/crates/wit-component/tests/components/link-duplicate-symbols/component.wat
index e182b2f6..f267ac4b 100644
--- a/crates/wit-component/tests/components/link-duplicate-symbols/component.wat
+++ b/crates/wit-component/tests/components/link-duplicate-symbols/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "foo" (func (type 0)))
     )
   )
-  (import (interface "test:test/test") (instance (;0;) (type 0)))
+  (import "test:test/test" (instance (;0;) (type 0)))
   (core module (;0;)
     (type (;0;) (func (param i32) (result i32)))
     (func (;0;) (type 0) (param i32) (result i32)
@@ -163,7 +163,7 @@
       (with "import-func-foo" (func 1))
     )
   )
-  (export (;2;) (interface "test:test/test") (instance 1))
+  (export (;2;) "test:test/test" (instance 1))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/link-got-func/component.wat b/crates/wit-component/tests/components/link-got-func/component.wat
index 10cff036..c54b8955 100644
--- a/crates/wit-component/tests/components/link-got-func/component.wat
+++ b/crates/wit-component/tests/components/link-got-func/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "foo" (func (type 0)))
     )
   )
-  (import (interface "test:test/test") (instance (;0;) (type 0)))
+  (import "test:test/test" (instance (;0;) (type 0)))
   (core module (;0;)
     (type (;0;) (func (param i32) (result i32)))
     (func (;0;) (type 0) (param i32) (result i32)
@@ -156,7 +156,7 @@
       (with "import-func-foo" (func 1))
     )
   )
-  (export (;2;) (interface "test:test/test") (instance 1))
+  (export (;2;) "test:test/test" (instance 1))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/link-initialize/component.wat b/crates/wit-component/tests/components/link-initialize/component.wat
index bb382862..dbbf3dae 100644
--- a/crates/wit-component/tests/components/link-initialize/component.wat
+++ b/crates/wit-component/tests/components/link-initialize/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "bar" (func (type 0)))
     )
   )
-  (import (interface "test:test/test") (instance (;0;) (type 0)))
+  (import "test:test/test" (instance (;0;) (type 0)))
   (core module (;0;)
     (table (;0;) 0 funcref)
     (memory (;0;) 17)
@@ -293,7 +293,7 @@
       (with "import-func-bar" (func 1))
     )
   )
-  (export (;2;) (interface "test:test/test") (instance 1))
+  (export (;2;) "test:test/test" (instance 1))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/link-resources/component.wat b/crates/wit-component/tests/components/link-resources/component.wat
index 8794c067..ef038e32 100644
--- a/crates/wit-component/tests/components/link-resources/component.wat
+++ b/crates/wit-component/tests/components/link-resources/component.wat
@@ -158,7 +158,7 @@
       (with "import-type-x" (type 0))
     )
   )
-  (export (;1;) (interface "test:test/foo") (instance 0))
+  (export (;1;) "test:test/foo" (instance 0))
   (type (;6;) (own 1))
   (type (;7;) (func (param "v" u32) (result 6)))
   (alias core export 8 "test:test/bar#[constructor]x" (core func (;2;)))
@@ -189,7 +189,7 @@
       (with "import-type-x" (type 1))
     )
   )
-  (export (;3;) (interface "test:test/bar") (instance 2))
+  (export (;3;) "test:test/bar" (instance 2))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/link-stubs/component.wat b/crates/wit-component/tests/components/link-stubs/component.wat
index f859d77c..3797346f 100644
--- a/crates/wit-component/tests/components/link-stubs/component.wat
+++ b/crates/wit-component/tests/components/link-stubs/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "foo" (func (type 0)))
     )
   )
-  (import (interface "test:test/test") (instance (;0;) (type 0)))
+  (import "test:test/test" (instance (;0;) (type 0)))
   (core module (;0;)
     (table (;0;) 0 funcref)
     (memory (;0;) 17)
@@ -152,7 +152,7 @@
       (with "import-func-foo" (func 1))
     )
   )
-  (export (;2;) (interface "test:test/test") (instance 1))
+  (export (;2;) "test:test/test" (instance 1))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/link-weak-import/component.wat b/crates/wit-component/tests/components/link-weak-import/component.wat
index f66f107f..3c1d1d6a 100644
--- a/crates/wit-component/tests/components/link-weak-import/component.wat
+++ b/crates/wit-component/tests/components/link-weak-import/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "foo" (func (type 0)))
     )
   )
-  (import (interface "test:test/test") (instance (;0;) (type 0)))
+  (import "test:test/test" (instance (;0;) (type 0)))
   (core module (;0;)
     (table (;0;) 0 funcref)
     (memory (;0;) 17)
@@ -154,7 +154,7 @@
       (with "import-func-foo" (func 1))
     )
   )
-  (export (;2;) (interface "test:test/test") (instance 1))
+  (export (;2;) "test:test/test" (instance 1))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/link/component.wat b/crates/wit-component/tests/components/link/component.wat
index 47466a04..b35218f1 100644
--- a/crates/wit-component/tests/components/link/component.wat
+++ b/crates/wit-component/tests/components/link/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "bar" (func (type 0)))
     )
   )
-  (import (interface "test:test/test") (instance (;0;) (type 0)))
+  (import "test:test/test" (instance (;0;) (type 0)))
   (core module (;0;)
     (table (;0;) 0 funcref)
     (memory (;0;) 17)
@@ -293,7 +293,7 @@
       (with "import-func-bar" (func 1))
     )
   )
-  (export (;2;) (interface "test:test/test") (instance 1))
+  (export (;2;) "test:test/test" (instance 1))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/live-exports-dead-imports/component.wat b/crates/wit-component/tests/components/live-exports-dead-imports/component.wat
index e1dd3685..4d73e1e7 100644
--- a/crates/wit-component/tests/components/live-exports-dead-imports/component.wat
+++ b/crates/wit-component/tests/components/live-exports-dead-imports/component.wat
@@ -31,7 +31,7 @@
       (with "import-type-r" (type 0))
     )
   )
-  (export (;1;) (interface "foo:foo/a") (instance 0))
+  (export (;1;) "foo:foo/a" (instance 0))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/components/lower-options/component.wat b/crates/wit-component/tests/components/lower-options/component.wat
index 9aa289c2..c4c0357a 100644
--- a/crates/wit-component/tests/components/lower-options/component.wat
+++ b/crates/wit-component/tests/components/lower-options/component.wat
@@ -49,7 +49,7 @@
       (export (;15;) "p" (func (type 29)))
     )
   )
-  (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+  (import "foo:foo/foo" (instance (;0;) (type 0)))
   (core module (;0;)
     (type (;0;) (func))
     (type (;1;) (func (param i32 i32)))
diff --git a/crates/wit-component/tests/components/many-same-names/component.wat b/crates/wit-component/tests/components/many-same-names/component.wat
index 7c84080c..628ec4ce 100644
--- a/crates/wit-component/tests/components/many-same-names/component.wat
+++ b/crates/wit-component/tests/components/many-same-names/component.wat
@@ -16,7 +16,7 @@
     (export (;3;) "r2" (type 2))
   )
   (instance (;0;) (instantiate 0))
-  (export (;1;) (interface "foo:foo/name") (instance 0))
+  (export (;1;) "foo:foo/name" (instance 0))
   (type (;0;) (func))
   (alias core export 0 "name#a" (core func (;0;)))
   (func (;0;) (type 0) (canon lift (core func 0)))
diff --git a/crates/wit-component/tests/components/rename-import-interface/component.wat b/crates/wit-component/tests/components/rename-import-interface/component.wat
index 929103c0..28b547cd 100644
--- a/crates/wit-component/tests/components/rename-import-interface/component.wat
+++ b/crates/wit-component/tests/components/rename-import-interface/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "the-func" (func (type 0)))
     )
   )
-  (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+  (import "foo:foo/foo" (instance (;0;) (type 0)))
   (core module (;0;)
     (type (;0;) (func))
     (import "foo:foo/foo" "the-func" (func (;0;) (type 0)))
diff --git a/crates/wit-component/tests/components/rename-interface/component.wat b/crates/wit-component/tests/components/rename-interface/component.wat
index 300caf8b..7729691a 100644
--- a/crates/wit-component/tests/components/rename-interface/component.wat
+++ b/crates/wit-component/tests/components/rename-interface/component.wat
@@ -5,7 +5,7 @@
       (export (;1;) "bar" (type (eq 0)))
     )
   )
-  (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+  (import "foo:foo/foo" (instance (;0;) (type 0)))
   (alias export 0 "bar" (type (;1;)))
   (type (;2;)
     (instance
diff --git a/crates/wit-component/tests/components/resource-used-through-import/component.wat b/crates/wit-component/tests/components/resource-used-through-import/component.wat
index 729cb3de..69064d8b 100644
--- a/crates/wit-component/tests/components/resource-used-through-import/component.wat
+++ b/crates/wit-component/tests/components/resource-used-through-import/component.wat
@@ -4,7 +4,7 @@
       (export (;0;) "r" (type (sub resource)))
     )
   )
-  (import (interface "foo:bar/a") (instance (;0;) (type 0)))
+  (import "foo:bar/a" (instance (;0;) (type 0)))
   (core module (;0;)
     (type (;0;) (func (param i32)))
     (type (;1;) (func (result i32)))
diff --git a/crates/wit-component/tests/components/resource-using-export/component.wat b/crates/wit-component/tests/components/resource-using-export/component.wat
index b1cb6c40..f8f983df 100644
--- a/crates/wit-component/tests/components/resource-using-export/component.wat
+++ b/crates/wit-component/tests/components/resource-using-export/component.wat
@@ -32,7 +32,7 @@
       (with "import-type-r" (type 0))
     )
   )
-  (export (;1;) (interface "foo:bar/foo") (instance 0))
+  (export (;1;) "foo:bar/foo" (instance 0))
   (alias export 1 "handle" (type (;1;)))
   (type (;2;) (func (result 1)))
   (alias core export 1 "anon#f" (core func (;1;)))
diff --git a/crates/wit-component/tests/components/tricky-order/component.wat b/crates/wit-component/tests/components/tricky-order/component.wat
index d46be4d1..36b69975 100644
--- a/crates/wit-component/tests/components/tricky-order/component.wat
+++ b/crates/wit-component/tests/components/tricky-order/component.wat
@@ -5,7 +5,7 @@
       (export (;1;) "name" (type (eq 0)))
     )
   )
-  (import (interface "foo:foo/name1") (instance (;0;) (type 0)))
+  (import "foo:foo/name1" (instance (;0;) (type 0)))
   (alias export 0 "name" (type (;1;)))
   (type (;2;)
     (instance
@@ -13,7 +13,7 @@
       (export (;1;) "name" (type (eq 0)))
     )
   )
-  (import (interface "foo:foo/name2") (instance (;1;) (type 2)))
+  (import "foo:foo/name2" (instance (;1;) (type 2)))
   (core module (;0;)
     (@producers
       (processed-by "wit-component" "$CARGO_PKG_VERSION")
diff --git a/crates/wit-component/tests/components/tricky-resources/component.wat b/crates/wit-component/tests/components/tricky-resources/component.wat
index a7d64c11..0fa0c26f 100644
--- a/crates/wit-component/tests/components/tricky-resources/component.wat
+++ b/crates/wit-component/tests/components/tricky-resources/component.wat
@@ -33,7 +33,7 @@
       (with "import-type-r" (type 0))
     )
   )
-  (export (;1;) (interface "foo:bar/a") (instance 0))
+  (export (;1;) "foo:bar/a" (instance 0))
   (alias export 1 "r" (type (;1;)))
   (component (;1;)
     (import "import-type-r" (type (;0;) (sub resource)))
@@ -43,7 +43,7 @@
       (with "import-type-r" (type 1))
     )
   )
-  (export (;3;) (interface "foo:bar/b") (instance 2))
+  (export (;3;) "foo:bar/b" (instance 2))
   (alias export 3 "r" (type (;2;)))
   (type (;3;) (own 2))
   (type (;4;) (func (result 3)))
diff --git a/crates/wit-component/tests/components/tricky-resources2/component.wat b/crates/wit-component/tests/components/tricky-resources2/component.wat
index 2f611ee7..b60c2350 100644
--- a/crates/wit-component/tests/components/tricky-resources2/component.wat
+++ b/crates/wit-component/tests/components/tricky-resources2/component.wat
@@ -20,7 +20,7 @@
       (with "import-type-r" (type 0))
     )
   )
-  (export (;1;) (interface "foo:bar/a") (instance 0))
+  (export (;1;) "foo:bar/a" (instance 0))
   (alias export 1 "r" (type (;1;)))
   (type (;2;) (own 1))
   (type (;3;) (func (result 2)))
diff --git a/crates/wit-component/tests/components/tricky-resources3/component.wat b/crates/wit-component/tests/components/tricky-resources3/component.wat
index 49e146d4..06f27583 100644
--- a/crates/wit-component/tests/components/tricky-resources3/component.wat
+++ b/crates/wit-component/tests/components/tricky-resources3/component.wat
@@ -15,7 +15,7 @@
       (with "import-type-name" (type 0))
     )
   )
-  (export (;1;) (interface "foo:bar/foo") (instance 0))
+  (export (;1;) "foo:bar/foo" (instance 0))
   (alias export 1 "name" (type (;1;)))
   (component (;1;)
     (import "import-type-name" (type (;0;) (sub resource)))
@@ -25,7 +25,7 @@
       (with "import-type-name" (type 1))
     )
   )
-  (export (;3;) (interface "foo:bar/name") (instance 2))
+  (export (;3;) "foo:bar/name" (instance 2))
   (alias export 3 "name" (type (;2;)))
   (component (;2;)
     (import "import-type-name" (type (;0;) (sub resource)))
diff --git a/crates/wit-component/tests/components/tricky-resources4/component.wat b/crates/wit-component/tests/components/tricky-resources4/component.wat
index 7e760815..326370be 100644
--- a/crates/wit-component/tests/components/tricky-resources4/component.wat
+++ b/crates/wit-component/tests/components/tricky-resources4/component.wat
@@ -44,7 +44,7 @@
       (with "import-type-handle" (type 0))
     )
   )
-  (export (;1;) (interface "foo:bar/name") (instance 0))
+  (export (;1;) "foo:bar/name" (instance 0))
   (alias export 1 "name" (type (;3;)))
   (alias export 1 "handle" (type (;4;)))
   (component (;1;)
diff --git a/crates/wit-component/tests/components/unused-import/component.wat b/crates/wit-component/tests/components/unused-import/component.wat
index 59d4716d..9d16c6f6 100644
--- a/crates/wit-component/tests/components/unused-import/component.wat
+++ b/crates/wit-component/tests/components/unused-import/component.wat
@@ -5,7 +5,7 @@
       (export (;0;) "name" (func (type 0)))
     )
   )
-  (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+  (import "foo:foo/foo" (instance (;0;) (type 0)))
   (core module (;0;)
     (type (;0;) (func (param i32)))
     (import "foo:foo/foo" "name" (func (;0;) (type 0)))
diff --git a/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat b/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat
index 3d23846d..45a4c542 100644
--- a/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat
+++ b/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat
@@ -7,7 +7,7 @@
       (export (;0;) "the-func" (func (type 2)))
     )
   )
-  (import (interface "foo:foo/i") (instance (;0;) (type 0)))
+  (import "foo:foo/i" (instance (;0;) (type 0)))
   (alias export 0 "some-type" (type (;1;)))
   (import "other-name" (type (;2;) (eq 1)))
   (core module (;0;)
@@ -60,7 +60,7 @@
       (with "import-type-some-type" (type 3))
     )
   )
-  (export (;2;) (interface "foo:foo/i") (instance 1))
+  (export (;2;) "foo:foo/i" (instance 1))
   (@producers
     (processed-by "wit-component" "$CARGO_PKG_VERSION")
   )
diff --git a/crates/wit-component/tests/interfaces/console.wat b/crates/wit-component/tests/interfaces/console.wat
index 8825a84c..deccc9e6 100644
--- a/crates/wit-component/tests/interfaces/console.wat
+++ b/crates/wit-component/tests/interfaces/console.wat
@@ -7,7 +7,7 @@
           (export (;0;) "log" (func (type 0)))
         )
       )
-      (export (;0;) (interface "foo:console/console") (instance (type 0)))
+      (export (;0;) "foo:console/console" (instance (type 0)))
     )
   )
   (export (;1;) "console" (type 0))
diff --git a/crates/wit-component/tests/interfaces/diamond-disambiguate.wat b/crates/wit-component/tests/interfaces/diamond-disambiguate.wat
index f1744b29..1564bec4 100644
--- a/crates/wit-component/tests/interfaces/diamond-disambiguate.wat
+++ b/crates/wit-component/tests/interfaces/diamond-disambiguate.wat
@@ -7,7 +7,7 @@
           (export (;1;) "t1" (type (eq 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/shared1") (instance (type 0)))
+      (export (;0;) "foo:foo/shared1" (instance (type 0)))
     )
   )
   (export (;1;) "shared1" (type 0))
@@ -19,7 +19,7 @@
           (export (;1;) "t2" (type (eq 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/shared2") (instance (type 0)))
+      (export (;0;) "foo:foo/shared2" (instance (type 0)))
     )
   )
   (export (;3;) "shared2" (type 2))
@@ -33,7 +33,7 @@
               (export (;1;) "t1" (type (eq 0)))
             )
           )
-          (import (interface "foo:foo/shared1") (instance (;0;) (type 0)))
+          (import "foo:foo/shared1" (instance (;0;) (type 0)))
           (alias export 0 "t1" (type (;1;)))
           (type (;2;)
             (instance
@@ -48,7 +48,7 @@
               (export (;1;) "t2" (type (eq 0)))
             )
           )
-          (import (interface "foo:foo/shared2") (instance (;2;) (type 3)))
+          (import "foo:foo/shared2" (instance (;2;) (type 3)))
           (alias export 2 "t2" (type (;4;)))
           (type (;5;)
             (instance
@@ -59,7 +59,7 @@
           (import "bar" (instance (;3;) (type 5)))
         )
       )
-      (export (;0;) (interface "foo:foo/w1") (component (type 0)))
+      (export (;0;) "foo:foo/w1" (component (type 0)))
     )
   )
   (export (;5;) "w1" (type 4))
diff --git a/crates/wit-component/tests/interfaces/diamond.wat b/crates/wit-component/tests/interfaces/diamond.wat
index ea0da3aa..505cc7f2 100644
--- a/crates/wit-component/tests/interfaces/diamond.wat
+++ b/crates/wit-component/tests/interfaces/diamond.wat
@@ -7,7 +7,7 @@
           (export (;1;) "the-enum" (type (eq 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/shared-items") (instance (type 0)))
+      (export (;0;) "foo:foo/shared-items" (instance (type 0)))
     )
   )
   (export (;1;) "shared-items" (type 0))
@@ -21,7 +21,7 @@
               (export (;1;) "the-enum" (type (eq 0)))
             )
           )
-          (import (interface "foo:foo/shared-items") (instance (;0;) (type 0)))
+          (import "foo:foo/shared-items" (instance (;0;) (type 0)))
           (alias export 0 "the-enum" (type (;1;)))
           (type (;2;)
             (instance
@@ -39,7 +39,7 @@
           (import "bar" (instance (;2;) (type 3)))
         )
       )
-      (export (;0;) (interface "foo:foo/w1") (component (type 0)))
+      (export (;0;) "foo:foo/w1" (component (type 0)))
     )
   )
   (export (;3;) "w1" (type 2))
@@ -53,7 +53,7 @@
               (export (;1;) "the-enum" (type (eq 0)))
             )
           )
-          (import (interface "foo:foo/shared-items") (instance (;0;) (type 0)))
+          (import "foo:foo/shared-items" (instance (;0;) (type 0)))
           (alias export 0 "the-enum" (type (;1;)))
           (type (;2;)
             (instance
@@ -71,7 +71,7 @@
           (export (;2;) "bar" (instance (type 3)))
         )
       )
-      (export (;0;) (interface "foo:foo/w2") (component (type 0)))
+      (export (;0;) "foo:foo/w2" (component (type 0)))
     )
   )
   (export (;5;) "w2" (type 4))
@@ -85,7 +85,7 @@
               (export (;1;) "the-enum" (type (eq 0)))
             )
           )
-          (import (interface "foo:foo/shared-items") (instance (;0;) (type 0)))
+          (import "foo:foo/shared-items" (instance (;0;) (type 0)))
           (alias export 0 "the-enum" (type (;1;)))
           (type (;2;)
             (instance
@@ -96,7 +96,7 @@
           (export (;1;) "bar" (instance (type 2)))
         )
       )
-      (export (;0;) (interface "foo:foo/w3") (component (type 0)))
+      (export (;0;) "foo:foo/w3" (component (type 0)))
     )
   )
   (export (;7;) "w3" (type 6))
diff --git a/crates/wit-component/tests/interfaces/doc-comments.wat b/crates/wit-component/tests/interfaces/doc-comments.wat
index 16dfb3ae..362f5aab 100644
--- a/crates/wit-component/tests/interfaces/doc-comments.wat
+++ b/crates/wit-component/tests/interfaces/doc-comments.wat
@@ -25,7 +25,7 @@
           (export (;3;) "f" (func (type 15)))
         )
       )
-      (export (;0;) (interface "foo:foo/coverage-iface") (instance (type 0)))
+      (export (;0;) "foo:foo/coverage-iface" (instance (type 0)))
     )
   )
   (export (;1;) "coverage-iface" (type 0))
@@ -38,7 +38,7 @@
           (export (;1;) "mixed-forms" (func (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/other-comment-forms") (instance (type 0)))
+      (export (;0;) "foo:foo/other-comment-forms" (instance (type 0)))
     )
   )
   (export (;3;) "other-comment-forms" (type 2))
@@ -62,7 +62,7 @@
           (export (;0;) "i" (instance (type 3)))
         )
       )
-      (export (;0;) (interface "foo:foo/coverage-world") (component (type 0)))
+      (export (;0;) "foo:foo/coverage-world" (component (type 0)))
     )
   )
   (export (;5;) "coverage-world" (type 4))
diff --git a/crates/wit-component/tests/interfaces/empty.wat b/crates/wit-component/tests/interfaces/empty.wat
index efea26d3..67a579c4 100644
--- a/crates/wit-component/tests/interfaces/empty.wat
+++ b/crates/wit-component/tests/interfaces/empty.wat
@@ -4,7 +4,7 @@
       (type (;0;)
         (instance)
       )
-      (export (;0;) (interface "foo:empty/empty") (instance (type 0)))
+      (export (;0;) "foo:empty/empty" (instance (type 0)))
     )
   )
   (export (;1;) "empty" (type 0))
@@ -15,7 +15,7 @@
           (type (;0;)
             (instance)
           )
-          (import (interface "foo:empty/empty") (instance (;0;) (type 0)))
+          (import "foo:empty/empty" (instance (;0;) (type 0)))
           (type (;1;)
             (instance)
           )
@@ -23,14 +23,14 @@
           (type (;2;)
             (instance)
           )
-          (export (;2;) (interface "foo:empty/empty") (instance (type 2)))
+          (export (;2;) "foo:empty/empty" (instance (type 2)))
           (type (;3;)
             (instance)
           )
           (export (;3;) "empty2" (instance (type 3)))
         )
       )
-      (export (;0;) (interface "foo:empty/empty-world") (component (type 0)))
+      (export (;0;) "foo:empty/empty-world" (component (type 0)))
     )
   )
   (export (;3;) "empty-world" (type 2))
@@ -39,7 +39,7 @@
       (type (;0;)
         (component)
       )
-      (export (;0;) (interface "foo:empty/actually-empty-world") (component (type 0)))
+      (export (;0;) "foo:empty/actually-empty-world" (component (type 0)))
     )
   )
   (export (;5;) "actually-empty-world" (type 4))
diff --git a/crates/wit-component/tests/interfaces/export-other-packages-interface.wat b/crates/wit-component/tests/interfaces/export-other-packages-interface.wat
index 49329a39..62417daa 100644
--- a/crates/wit-component/tests/interfaces/export-other-packages-interface.wat
+++ b/crates/wit-component/tests/interfaces/export-other-packages-interface.wat
@@ -9,10 +9,10 @@
               (export (;1;) "t" (type (eq 0)))
             )
           )
-          (export (;0;) (interface "foo:the-dep/the-interface") (instance (type 0)))
+          (export (;0;) "foo:the-dep/the-interface" (instance (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo") (component (type 0)))
+      (export (;0;) "foo:foo/foo" (component (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
diff --git a/crates/wit-component/tests/interfaces/exports.wat b/crates/wit-component/tests/interfaces/exports.wat
index 99da09b4..3f6e791c 100644
--- a/crates/wit-component/tests/interfaces/exports.wat
+++ b/crates/wit-component/tests/interfaces/exports.wat
@@ -9,7 +9,7 @@
           (export (;0;) "my-function" (func (type 2)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo") (instance (type 0)))
+      (export (;0;) "foo:foo/foo" (instance (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
@@ -25,10 +25,10 @@
               (export (;0;) "my-function" (func (type 2)))
             )
           )
-          (export (;0;) (interface "foo:foo/foo") (instance (type 0)))
+          (export (;0;) "foo:foo/foo" (instance (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/export-foo") (component (type 0)))
+      (export (;0;) "foo:foo/export-foo" (component (type 0)))
     )
   )
   (export (;3;) "export-foo" (type 2))
diff --git a/crates/wit-component/tests/interfaces/flags.wat b/crates/wit-component/tests/interfaces/flags.wat
index b39eee54..6304c5a2 100644
--- a/crates/wit-component/tests/interfaces/flags.wat
+++ b/crates/wit-component/tests/interfaces/flags.wat
@@ -33,7 +33,7 @@
           (export (;6;) "roundtrip-flag64" (func (type 20)))
         )
       )
-      (export (;0;) (interface "foo:flags/imports") (instance (type 0)))
+      (export (;0;) "foo:flags/imports" (instance (type 0)))
     )
   )
   (export (;1;) "imports" (type 0))
@@ -73,10 +73,10 @@
               (export (;6;) "roundtrip-flag64" (func (type 20)))
             )
           )
-          (import (interface "foo:flags/imports") (instance (;0;) (type 0)))
+          (import "foo:flags/imports" (instance (;0;) (type 0)))
         )
       )
-      (export (;0;) (interface "foo:flags/flags-world") (component (type 0)))
+      (export (;0;) "foo:flags/flags-world" (component (type 0)))
     )
   )
   (export (;3;) "flags-world" (type 2))
diff --git a/crates/wit-component/tests/interfaces/floats.wat b/crates/wit-component/tests/interfaces/floats.wat
index fa163945..929554d3 100644
--- a/crates/wit-component/tests/interfaces/floats.wat
+++ b/crates/wit-component/tests/interfaces/floats.wat
@@ -13,7 +13,7 @@
           (export (;3;) "float64-result" (func (type 3)))
         )
       )
-      (export (;0;) (interface "foo:floats/floats") (instance (type 0)))
+      (export (;0;) "foo:floats/floats" (instance (type 0)))
     )
   )
   (export (;1;) "floats" (type 0))
@@ -33,10 +33,10 @@
               (export (;3;) "float64-result" (func (type 3)))
             )
           )
-          (import (interface "foo:floats/floats") (instance (;0;) (type 0)))
+          (import "foo:floats/floats" (instance (;0;) (type 0)))
         )
       )
-      (export (;0;) (interface "foo:floats/floats-world") (component (type 0)))
+      (export (;0;) "foo:floats/floats-world" (component (type 0)))
     )
   )
   (export (;3;) "floats-world" (type 2))
diff --git a/crates/wit-component/tests/interfaces/foreign-use-chain.wat b/crates/wit-component/tests/interfaces/foreign-use-chain.wat
index d98b07a2..a4458085 100644
--- a/crates/wit-component/tests/interfaces/foreign-use-chain.wat
+++ b/crates/wit-component/tests/interfaces/foreign-use-chain.wat
@@ -9,7 +9,7 @@
               (export (;1;) "the-type" (type (eq 0)))
             )
           )
-          (import (interface "foo:bar/the-interface") (instance (;0;) (type 0)))
+          (import "foo:bar/the-interface" (instance (;0;) (type 0)))
           (alias export 0 "the-type" (type (;1;)))
           (type (;2;)
             (instance
@@ -17,10 +17,10 @@
               (export (;1;) "bar" (type (eq 0)))
             )
           )
-          (import (interface "foo:bar/bar") (instance (;1;) (type 2)))
+          (import "foo:bar/bar" (instance (;1;) (type 2)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo") (component (type 0)))
+      (export (;0;) "foo:foo/foo" (component (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
diff --git a/crates/wit-component/tests/interfaces/import-and-export.wat b/crates/wit-component/tests/interfaces/import-and-export.wat
index 494f72e5..c743c859 100644
--- a/crates/wit-component/tests/interfaces/import-and-export.wat
+++ b/crates/wit-component/tests/interfaces/import-and-export.wat
@@ -7,7 +7,7 @@
           (export (;0;) "foo" (func (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo") (instance (type 0)))
+      (export (;0;) "foo:foo/foo" (instance (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
@@ -19,7 +19,7 @@
           (export (;0;) "bar" (func (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/bar") (instance (type 0)))
+      (export (;0;) "foo:foo/bar" (instance (type 0)))
     )
   )
   (export (;3;) "bar" (type 2))
@@ -33,17 +33,17 @@
               (export (;0;) "foo" (func (type 0)))
             )
           )
-          (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+          (import "foo:foo/foo" (instance (;0;) (type 0)))
           (type (;1;)
             (instance
               (type (;0;) (func))
               (export (;0;) "bar" (func (type 0)))
             )
           )
-          (export (;1;) (interface "foo:foo/bar") (instance (type 1)))
+          (export (;1;) "foo:foo/bar" (instance (type 1)))
         )
       )
-      (export (;0;) (interface "foo:foo/import-and-export") (component (type 0)))
+      (export (;0;) "foo:foo/import-and-export" (component (type 0)))
     )
   )
   (export (;5;) "import-and-export" (type 4))
diff --git a/crates/wit-component/tests/interfaces/integers.wat b/crates/wit-component/tests/interfaces/integers.wat
index dd55f771..361c101e 100644
--- a/crates/wit-component/tests/interfaces/integers.wat
+++ b/crates/wit-component/tests/interfaces/integers.wat
@@ -44,7 +44,7 @@
           (export (;18;) "multi-ret" (func (type 19)))
         )
       )
-      (export (;0;) (interface "foo:foo/integers") (instance (type 0)))
+      (export (;0;) "foo:foo/integers" (instance (type 0)))
     )
   )
   (export (;1;) "integers" (type 0))
@@ -95,10 +95,10 @@
               (export (;18;) "multi-ret" (func (type 19)))
             )
           )
-          (import (interface "foo:foo/integers") (instance (;0;) (type 0)))
+          (import "foo:foo/integers" (instance (;0;) (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/integers-world") (component (type 0)))
+      (export (;0;) "foo:foo/integers-world" (component (type 0)))
     )
   )
   (export (;3;) "integers-world" (type 2))
diff --git a/crates/wit-component/tests/interfaces/lists.wat b/crates/wit-component/tests/interfaces/lists.wat
index 5d19e477..1bb83321 100644
--- a/crates/wit-component/tests/interfaces/lists.wat
+++ b/crates/wit-component/tests/interfaces/lists.wat
@@ -95,7 +95,7 @@
           (export (;27;) "load-store-everything" (func (type 61)))
         )
       )
-      (export (;0;) (interface "foo:foo/lists") (instance (type 0)))
+      (export (;0;) "foo:foo/lists" (instance (type 0)))
     )
   )
   (export (;1;) "lists" (type 0))
@@ -197,10 +197,10 @@
               (export (;27;) "load-store-everything" (func (type 61)))
             )
           )
-          (import (interface "foo:foo/lists") (instance (;0;) (type 0)))
+          (import "foo:foo/lists" (instance (;0;) (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/lists-world") (component (type 0)))
+      (export (;0;) "foo:foo/lists-world" (component (type 0)))
     )
   )
   (export (;3;) "lists-world" (type 2))
diff --git a/crates/wit-component/tests/interfaces/multi-doc.wat b/crates/wit-component/tests/interfaces/multi-doc.wat
index fff5254c..9eb9a32b 100644
--- a/crates/wit-component/tests/interfaces/multi-doc.wat
+++ b/crates/wit-component/tests/interfaces/multi-doc.wat
@@ -7,7 +7,7 @@
           (export (;1;) "the-type" (type (eq 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/b") (instance (type 0)))
+      (export (;0;) "foo:foo/b" (instance (type 0)))
     )
   )
   (export (;1;) "b" (type 0))
@@ -19,7 +19,7 @@
           (export (;1;) "the-type" (type (eq 0)))
         )
       )
-      (import (interface "foo:foo/b") (instance (;0;) (type 0)))
+      (import "foo:foo/b" (instance (;0;) (type 0)))
       (alias export 0 "the-type" (type (;1;)))
       (type (;2;)
         (instance
@@ -27,7 +27,7 @@
           (export (;1;) "the-type" (type (eq 0)))
         )
       )
-      (export (;1;) (interface "foo:foo/a") (instance (type 2)))
+      (export (;1;) "foo:foo/a" (instance (type 2)))
     )
   )
   (export (;3;) "a" (type 2))
@@ -39,7 +39,7 @@
           (export (;1;) "the-type" (type (eq 0)))
         )
       )
-      (import (interface "foo:foo/b") (instance (;0;) (type 0)))
+      (import "foo:foo/b" (instance (;0;) (type 0)))
       (alias export 0 "the-type" (type (;1;)))
       (type (;2;)
         (instance
@@ -47,7 +47,7 @@
           (export (;1;) "the-type" (type (eq 0)))
         )
       )
-      (export (;1;) (interface "foo:foo/b2") (instance (type 2)))
+      (export (;1;) "foo:foo/b2" (instance (type 2)))
     )
   )
   (export (;5;) "b2" (type 4))
@@ -59,7 +59,7 @@
           (export (;1;) "the-type" (type (eq 0)))
         )
       )
-      (import (interface "foo:foo/b") (instance (;0;) (type 0)))
+      (import "foo:foo/b" (instance (;0;) (type 0)))
       (alias export 0 "the-type" (type (;1;)))
       (type (;2;)
         (instance
@@ -67,7 +67,7 @@
           (export (;1;) "the-type" (type (eq 0)))
         )
       )
-      (export (;1;) (interface "foo:foo/a2") (instance (type 2)))
+      (export (;1;) "foo:foo/a2" (instance (type 2)))
     )
   )
   (export (;7;) "a2" (type 6))
diff --git a/crates/wit-component/tests/interfaces/multiple-use.wat b/crates/wit-component/tests/interfaces/multiple-use.wat
index adab86d9..f17501ea 100644
--- a/crates/wit-component/tests/interfaces/multiple-use.wat
+++ b/crates/wit-component/tests/interfaces/multiple-use.wat
@@ -9,7 +9,7 @@
           (export (;3;) "t2" (type (eq 2)))
         )
       )
-      (export (;0;) (interface "foo:multiuse/foo") (instance (type 0)))
+      (export (;0;) "foo:multiuse/foo" (instance (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
@@ -21,7 +21,7 @@
           (export (;1;) "u" (type (eq 0)))
         )
       )
-      (export (;0;) (interface "foo:multiuse/bar") (instance (type 0)))
+      (export (;0;) "foo:multiuse/bar" (instance (type 0)))
     )
   )
   (export (;3;) "bar" (type 2))
@@ -35,14 +35,14 @@
           (export (;3;) "t2" (type (eq 2)))
         )
       )
-      (import (interface "foo:multiuse/foo") (instance (;0;) (type 0)))
+      (import "foo:multiuse/foo" (instance (;0;) (type 0)))
       (type (;1;)
         (instance
           (type (;0;) u8)
           (export (;1;) "u" (type (eq 0)))
         )
       )
-      (import (interface "foo:multiuse/bar") (instance (;1;) (type 1)))
+      (import "foo:multiuse/bar" (instance (;1;) (type 1)))
       (alias export 0 "t1" (type (;2;)))
       (alias export 1 "u" (type (;3;)))
       (alias export 0 "t2" (type (;4;)))
@@ -56,7 +56,7 @@
           (export (;5;) "t2" (type (eq 4)))
         )
       )
-      (export (;2;) (interface "foo:multiuse/baz") (instance (type 5)))
+      (export (;2;) "foo:multiuse/baz" (instance (type 5)))
     )
   )
   (export (;5;) "baz" (type 4))
diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain.wat b/crates/wit-component/tests/interfaces/pkg-use-chain.wat
index 4c02b18f..cc8ed7c1 100644
--- a/crates/wit-component/tests/interfaces/pkg-use-chain.wat
+++ b/crates/wit-component/tests/interfaces/pkg-use-chain.wat
@@ -7,7 +7,7 @@
           (export (;1;) "a" (type (eq 0)))
         )
       )
-      (export (;0;) (interface "foo:chain/a") (instance (type 0)))
+      (export (;0;) "foo:chain/a" (instance (type 0)))
     )
   )
   (export (;1;) "a" (type 0))
@@ -19,7 +19,7 @@
           (export (;1;) "a" (type (eq 0)))
         )
       )
-      (import (interface "foo:chain/a") (instance (;0;) (type 0)))
+      (import "foo:chain/a" (instance (;0;) (type 0)))
       (alias export 0 "a" (type (;1;)))
       (type (;2;)
         (instance
@@ -29,7 +29,7 @@
           (export (;3;) "name" (type (eq 2)))
         )
       )
-      (export (;1;) (interface "foo:chain/def") (instance (type 2)))
+      (export (;1;) "foo:chain/def" (instance (type 2)))
     )
   )
   (export (;3;) "def" (type 2))
@@ -41,7 +41,7 @@
           (export (;1;) "a" (type (eq 0)))
         )
       )
-      (import (interface "foo:chain/a") (instance (;0;) (type 0)))
+      (import "foo:chain/a" (instance (;0;) (type 0)))
       (alias export 0 "a" (type (;1;)))
       (type (;2;)
         (instance
@@ -51,7 +51,7 @@
           (export (;3;) "name" (type (eq 2)))
         )
       )
-      (import (interface "foo:chain/def") (instance (;1;) (type 2)))
+      (import "foo:chain/def" (instance (;1;) (type 2)))
       (alias export 1 "name" (type (;3;)))
       (type (;4;)
         (instance
@@ -59,7 +59,7 @@
           (export (;1;) "name" (type (eq 0)))
         )
       )
-      (export (;2;) (interface "foo:chain/foo") (instance (type 4)))
+      (export (;2;) "foo:chain/foo" (instance (type 4)))
     )
   )
   (export (;5;) "foo" (type 4))
diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain2.wat b/crates/wit-component/tests/interfaces/pkg-use-chain2.wat
index cded6090..13201123 100644
--- a/crates/wit-component/tests/interfaces/pkg-use-chain2.wat
+++ b/crates/wit-component/tests/interfaces/pkg-use-chain2.wat
@@ -7,7 +7,7 @@
           (export (;1;) "name" (type (eq 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/other") (instance (type 0)))
+      (export (;0;) "foo:foo/other" (instance (type 0)))
     )
   )
   (export (;1;) "other" (type 0))
@@ -19,7 +19,7 @@
           (export (;1;) "name" (type (eq 0)))
         )
       )
-      (import (interface "foo:foo/other") (instance (;0;) (type 0)))
+      (import "foo:foo/other" (instance (;0;) (type 0)))
       (alias export 0 "name" (type (;1;)))
       (type (;2;)
         (instance
@@ -29,7 +29,7 @@
           (export (;3;) "name" (type (eq 2)))
         )
       )
-      (export (;1;) (interface "foo:foo/bar") (instance (type 2)))
+      (export (;1;) "foo:foo/bar" (instance (type 2)))
     )
   )
   (export (;3;) "bar" (type 2))
@@ -41,7 +41,7 @@
           (export (;1;) "name" (type (eq 0)))
         )
       )
-      (import (interface "foo:foo/other") (instance (;0;) (type 0)))
+      (import "foo:foo/other" (instance (;0;) (type 0)))
       (alias export 0 "name" (type (;1;)))
       (type (;2;)
         (instance
@@ -51,7 +51,7 @@
           (export (;3;) "name" (type (eq 2)))
         )
       )
-      (import (interface "foo:foo/bar") (instance (;1;) (type 2)))
+      (import "foo:foo/bar" (instance (;1;) (type 2)))
       (alias export 1 "the-name" (type (;3;)))
       (type (;4;)
         (instance
@@ -59,7 +59,7 @@
           (export (;1;) "the-name" (type (eq 0)))
         )
       )
-      (export (;2;) (interface "foo:foo/foo") (instance (type 4)))
+      (export (;2;) "foo:foo/foo" (instance (type 4)))
     )
   )
   (export (;5;) "foo" (type 4))
diff --git a/crates/wit-component/tests/interfaces/preserve-dep-type-order.wat b/crates/wit-component/tests/interfaces/preserve-dep-type-order.wat
index 9c3d93b7..2d49280e 100644
--- a/crates/wit-component/tests/interfaces/preserve-dep-type-order.wat
+++ b/crates/wit-component/tests/interfaces/preserve-dep-type-order.wat
@@ -9,7 +9,7 @@
           (export (;3;) "ty" (type (eq 2)))
         )
       )
-      (import (interface "foo:dep/foo") (instance (;0;) (type 0)))
+      (import "foo:dep/foo" (instance (;0;) (type 0)))
       (alias export 0 "ty" (type (;1;)))
       (type (;2;)
         (instance
@@ -17,7 +17,7 @@
           (export (;1;) "ty" (type (eq 0)))
         )
       )
-      (export (;1;) (interface "foo:foo/foo") (instance (type 2)))
+      (export (;1;) "foo:foo/foo" (instance (type 2)))
     )
   )
   (export (;1;) "foo" (type 0))
@@ -33,10 +33,10 @@
               (export (;3;) "ty" (type (eq 2)))
             )
           )
-          (import (interface "foo:dep/foo") (instance (;0;) (type 0)))
+          (import "foo:dep/foo" (instance (;0;) (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/bar") (component (type 0)))
+      (export (;0;) "foo:foo/bar" (component (type 0)))
     )
   )
   (export (;3;) "bar" (type 2))
diff --git a/crates/wit-component/tests/interfaces/preserve-foreign-reexport.wat b/crates/wit-component/tests/interfaces/preserve-foreign-reexport.wat
index 736988e6..02734007 100644
--- a/crates/wit-component/tests/interfaces/preserve-foreign-reexport.wat
+++ b/crates/wit-component/tests/interfaces/preserve-foreign-reexport.wat
@@ -10,10 +10,10 @@
               (export (;2;) "bar" (type (eq 1)))
             )
           )
-          (export (;0;) (interface "foo:my-dep/my-interface") (instance (type 0)))
+          (export (;0;) "foo:my-dep/my-interface" (instance (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo") (component (type 0)))
+      (export (;0;) "foo:foo/foo" (component (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
diff --git a/crates/wit-component/tests/interfaces/print-keyword.wat b/crates/wit-component/tests/interfaces/print-keyword.wat
index 5619770f..eb1e3c38 100644
--- a/crates/wit-component/tests/interfaces/print-keyword.wat
+++ b/crates/wit-component/tests/interfaces/print-keyword.wat
@@ -10,7 +10,7 @@
           (export (;4;) "record" (type (eq 3)))
         )
       )
-      (export (;0;) (interface "foo:foo/interface") (instance (type 0)))
+      (export (;0;) "foo:foo/interface" (instance (type 0)))
     )
   )
   (export (;1;) "interface" (type 0))
diff --git a/crates/wit-component/tests/interfaces/records.wat b/crates/wit-component/tests/interfaces/records.wat
index 3f76796c..62c3092d 100644
--- a/crates/wit-component/tests/interfaces/records.wat
+++ b/crates/wit-component/tests/interfaces/records.wat
@@ -40,7 +40,7 @@
           (export (;10;) "typedef-inout" (func (type 23)))
         )
       )
-      (export (;0;) (interface "foo:records/records") (instance (type 0)))
+      (export (;0;) "foo:records/records" (instance (type 0)))
     )
   )
   (export (;1;) "records" (type 0))
@@ -87,7 +87,7 @@
               (export (;10;) "typedef-inout" (func (type 23)))
             )
           )
-          (import (interface "foo:records/records") (instance (;0;) (type 0)))
+          (import "foo:records/records" (instance (;0;) (type 0)))
           (type (;1;)
             (instance
               (type (;0;) (record (field "f" u8)))
@@ -127,10 +127,10 @@
               (export (;10;) "typedef-inout" (func (type 23)))
             )
           )
-          (export (;1;) (interface "foo:records/records") (instance (type 1)))
+          (export (;1;) "foo:records/records" (instance (type 1)))
         )
       )
-      (export (;0;) (interface "foo:records/records-world") (component (type 0)))
+      (export (;0;) "foo:records/records-world" (component (type 0)))
     )
   )
   (export (;3;) "records-world" (type 2))
diff --git a/crates/wit-component/tests/interfaces/reference-out-of-order.wat b/crates/wit-component/tests/interfaces/reference-out-of-order.wat
index 13573eae..e423b357 100644
--- a/crates/wit-component/tests/interfaces/reference-out-of-order.wat
+++ b/crates/wit-component/tests/interfaces/reference-out-of-order.wat
@@ -21,7 +21,7 @@
           (export (;3;) "d" (func (type 11)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo") (instance (type 0)))
+      (export (;0;) "foo:foo/foo" (instance (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
@@ -49,10 +49,10 @@
               (export (;3;) "d" (func (type 11)))
             )
           )
-          (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+          (import "foo:foo/foo" (instance (;0;) (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo-world") (component (type 0)))
+      (export (;0;) "foo:foo/foo-world" (component (type 0)))
     )
   )
   (export (;3;) "foo-world" (type 2))
diff --git a/crates/wit-component/tests/interfaces/resources.wat b/crates/wit-component/tests/interfaces/resources.wat
index b95fa83d..255f4d12 100644
--- a/crates/wit-component/tests/interfaces/resources.wat
+++ b/crates/wit-component/tests/interfaces/resources.wat
@@ -19,7 +19,7 @@
           (export (;3;) "a" (func (type 9)))
         )
       )
-      (export (;0;) (interface "foo:bar/foo") (instance (type 0)))
+      (export (;0;) "foo:bar/foo" (instance (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
@@ -33,7 +33,7 @@
           (export (;3;) "t2" (type (eq 2)))
         )
       )
-      (import (interface "foo:bar/foo") (instance (;0;) (type 0)))
+      (import "foo:bar/foo" (instance (;0;) (type 0)))
       (alias export 0 "bar" (type (;1;)))
       (alias export 0 "t" (type (;2;)))
       (type (;3;)
@@ -50,7 +50,7 @@
           (export (;1;) "b" (func (type 7)))
         )
       )
-      (export (;1;) (interface "foo:bar/baz") (instance (type 3)))
+      (export (;1;) "foo:bar/baz" (instance (type 3)))
     )
   )
   (export (;3;) "baz" (type 2))
@@ -67,7 +67,7 @@
           (export (;1;) "c" (func (type 4)))
         )
       )
-      (export (;0;) (interface "foo:bar/implicit-own-handles") (instance (type 0)))
+      (export (;0;) "foo:bar/implicit-own-handles" (instance (type 0)))
     )
   )
   (export (;5;) "implicit-own-handles" (type 4))
@@ -91,7 +91,7 @@
           (export (;2;) "[static]c.a" (func (type 10)))
         )
       )
-      (export (;0;) (interface "foo:bar/implicit-own-handles2") (instance (type 0)))
+      (export (;0;) "foo:bar/implicit-own-handles2" (instance (type 0)))
     )
   )
   (export (;7;) "implicit-own-handles2" (type 6))
@@ -131,7 +131,7 @@
               (export (;3;) "a" (func (type 9)))
             )
           )
-          (import (interface "foo:bar/foo") (instance (;1;) (type 1)))
+          (import "foo:bar/foo" (instance (;1;) (type 1)))
           (alias export 1 "bar" (type (;2;)))
           (alias export 1 "t" (type (;3;)))
           (type (;4;)
@@ -148,7 +148,7 @@
               (export (;1;) "b" (func (type 7)))
             )
           )
-          (import (interface "foo:bar/baz") (instance (;2;) (type 4)))
+          (import "foo:bar/baz" (instance (;2;) (type 4)))
           (alias export 2 "bar" (type (;5;)))
           (import "bar" (type (;6;) (eq 5)))
           (import "a" (type (;7;) (sub resource)))
@@ -161,7 +161,7 @@
           (export (;2;) "y" (func (type 11)))
         )
       )
-      (export (;0;) (interface "foo:bar/some-world") (component (type 0)))
+      (export (;0;) "foo:bar/some-world" (component (type 0)))
     )
   )
   (export (;9;) "some-world" (type 8))
@@ -176,7 +176,7 @@
           (import "[constructor]a" (func (;0;) (type 3)))
         )
       )
-      (export (;0;) (interface "foo:bar/implicit-own-handles3") (component (type 0)))
+      (export (;0;) "foo:bar/implicit-own-handles3" (component (type 0)))
     )
   )
   (export (;11;) "implicit-own-handles3" (type 10))
diff --git a/crates/wit-component/tests/interfaces/simple-deps.wat b/crates/wit-component/tests/interfaces/simple-deps.wat
index d8730975..153e77eb 100644
--- a/crates/wit-component/tests/interfaces/simple-deps.wat
+++ b/crates/wit-component/tests/interfaces/simple-deps.wat
@@ -7,7 +7,7 @@
           (export (;1;) "some-type" (type (eq 0)))
         )
       )
-      (import (interface "foo:some-dep/types") (instance (;0;) (type 0)))
+      (import "foo:some-dep/types" (instance (;0;) (type 0)))
       (alias export 0 "some-type" (type (;1;)))
       (type (;2;)
         (instance
@@ -15,7 +15,7 @@
           (export (;1;) "some-type" (type (eq 0)))
         )
       )
-      (export (;1;) (interface "foo:foo/foo") (instance (type 2)))
+      (export (;1;) "foo:foo/foo" (instance (type 2)))
     )
   )
   (export (;1;) "foo" (type 0))
diff --git a/crates/wit-component/tests/interfaces/simple-multi.wat b/crates/wit-component/tests/interfaces/simple-multi.wat
index fabd6da4..54dfcc2d 100644
--- a/crates/wit-component/tests/interfaces/simple-multi.wat
+++ b/crates/wit-component/tests/interfaces/simple-multi.wat
@@ -4,7 +4,7 @@
       (type (;0;)
         (instance)
       )
-      (export (;0;) (interface "foo:foo/bar") (instance (type 0)))
+      (export (;0;) "foo:foo/bar" (instance (type 0)))
     )
   )
   (export (;1;) "bar" (type 0))
@@ -13,7 +13,7 @@
       (type (;0;)
         (instance)
       )
-      (export (;0;) (interface "foo:foo/foo") (instance (type 0)))
+      (export (;0;) "foo:foo/foo" (instance (type 0)))
     )
   )
   (export (;3;) "foo" (type 2))
diff --git a/crates/wit-component/tests/interfaces/simple-use.wat b/crates/wit-component/tests/interfaces/simple-use.wat
index f1dcfcb8..fcf64df3 100644
--- a/crates/wit-component/tests/interfaces/simple-use.wat
+++ b/crates/wit-component/tests/interfaces/simple-use.wat
@@ -7,7 +7,7 @@
           (export (;1;) "level" (type (eq 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/types") (instance (type 0)))
+      (export (;0;) "foo:foo/types" (instance (type 0)))
     )
   )
   (export (;1;) "types" (type 0))
@@ -19,7 +19,7 @@
           (export (;1;) "level" (type (eq 0)))
         )
       )
-      (import (interface "foo:foo/types") (instance (;0;) (type 0)))
+      (import "foo:foo/types" (instance (;0;) (type 0)))
       (alias export 0 "level" (type (;1;)))
       (type (;2;)
         (instance
@@ -29,7 +29,7 @@
           (export (;0;) "log" (func (type 2)))
         )
       )
-      (export (;1;) (interface "foo:foo/console") (instance (type 2)))
+      (export (;1;) "foo:foo/console" (instance (type 2)))
     )
   )
   (export (;3;) "console" (type 2))
diff --git a/crates/wit-component/tests/interfaces/simple-world.wat b/crates/wit-component/tests/interfaces/simple-world.wat
index a7dd0472..6e132e15 100644
--- a/crates/wit-component/tests/interfaces/simple-world.wat
+++ b/crates/wit-component/tests/interfaces/simple-world.wat
@@ -7,7 +7,7 @@
           (export (;0;) "log" (func (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/console") (instance (type 0)))
+      (export (;0;) "foo:foo/console" (instance (type 0)))
     )
   )
   (export (;1;) "console" (type 0))
@@ -21,10 +21,10 @@
               (export (;0;) "log" (func (type 0)))
             )
           )
-          (import (interface "foo:foo/console") (instance (;0;) (type 0)))
+          (import "foo:foo/console" (instance (;0;) (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/the-world") (component (type 0)))
+      (export (;0;) "foo:foo/the-world" (component (type 0)))
     )
   )
   (export (;3;) "the-world" (type 2))
diff --git a/crates/wit-component/tests/interfaces/single-named-result.wat b/crates/wit-component/tests/interfaces/single-named-result.wat
index c7398bb7..c1474d0a 100644
--- a/crates/wit-component/tests/interfaces/single-named-result.wat
+++ b/crates/wit-component/tests/interfaces/single-named-result.wat
@@ -7,7 +7,7 @@
           (export (;0;) "a" (func (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo") (instance (type 0)))
+      (export (;0;) "foo:foo/foo" (instance (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
diff --git a/crates/wit-component/tests/interfaces/type-alias.wat b/crates/wit-component/tests/interfaces/type-alias.wat
index 5bb85d88..31071d9e 100644
--- a/crates/wit-component/tests/interfaces/type-alias.wat
+++ b/crates/wit-component/tests/interfaces/type-alias.wat
@@ -10,7 +10,7 @@
           (export (;0;) "f" (func (type 3)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo") (instance (type 0)))
+      (export (;0;) "foo:foo/foo" (instance (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
@@ -27,7 +27,7 @@
               (export (;0;) "f" (func (type 3)))
             )
           )
-          (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+          (import "foo:foo/foo" (instance (;0;) (type 0)))
           (type (;1;)
             (instance
               (type (;0;) u8)
@@ -37,10 +37,10 @@
               (export (;0;) "f" (func (type 3)))
             )
           )
-          (export (;1;) (interface "foo:foo/foo") (instance (type 1)))
+          (export (;1;) "foo:foo/foo" (instance (type 1)))
         )
       )
-      (export (;0;) (interface "foo:foo/my-world") (component (type 0)))
+      (export (;0;) "foo:foo/my-world" (component (type 0)))
     )
   )
   (export (;3;) "my-world" (type 2))
diff --git a/crates/wit-component/tests/interfaces/type-alias2.wat b/crates/wit-component/tests/interfaces/type-alias2.wat
index 11306474..d5cbd461 100644
--- a/crates/wit-component/tests/interfaces/type-alias2.wat
+++ b/crates/wit-component/tests/interfaces/type-alias2.wat
@@ -10,7 +10,7 @@
           (export (;0;) "f" (func (type 3)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo") (instance (type 0)))
+      (export (;0;) "foo:foo/foo" (instance (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
@@ -27,10 +27,10 @@
               (export (;0;) "f" (func (type 3)))
             )
           )
-          (export (;0;) (interface "foo:foo/foo") (instance (type 0)))
+          (export (;0;) "foo:foo/foo" (instance (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/my-world") (component (type 0)))
+      (export (;0;) "foo:foo/my-world" (component (type 0)))
     )
   )
   (export (;3;) "my-world" (type 2))
diff --git a/crates/wit-component/tests/interfaces/upstream-deps-same-name.wat b/crates/wit-component/tests/interfaces/upstream-deps-same-name.wat
index 9f1cf07a..bd4d1935 100644
--- a/crates/wit-component/tests/interfaces/upstream-deps-same-name.wat
+++ b/crates/wit-component/tests/interfaces/upstream-deps-same-name.wat
@@ -7,14 +7,14 @@
           (export (;1;) "ty" (type (eq 0)))
         )
       )
-      (import (interface "foo:a/the-name") (instance (;0;) (type 0)))
+      (import "foo:a/the-name" (instance (;0;) (type 0)))
       (type (;1;)
         (instance
           (type (;0;) u8)
           (export (;1;) "ty" (type (eq 0)))
         )
       )
-      (import (interface "foo:b/the-name") (instance (;1;) (type 1)))
+      (import "foo:b/the-name" (instance (;1;) (type 1)))
       (alias export 0 "ty" (type (;2;)))
       (alias export 1 "ty" (type (;3;)))
       (type (;4;)
@@ -25,7 +25,7 @@
           (export (;3;) "ty2" (type (eq 2)))
         )
       )
-      (export (;2;) (interface "foo:foo/a") (instance (type 4)))
+      (export (;2;) "foo:foo/a" (instance (type 4)))
     )
   )
   (export (;1;) "a" (type 0))
diff --git a/crates/wit-component/tests/interfaces/use-chain.wat b/crates/wit-component/tests/interfaces/use-chain.wat
index 7c417336..1e986780 100644
--- a/crates/wit-component/tests/interfaces/use-chain.wat
+++ b/crates/wit-component/tests/interfaces/use-chain.wat
@@ -9,7 +9,7 @@
           (export (;3;) "c" (type (eq 2)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo") (instance (type 0)))
+      (export (;0;) "foo:foo/foo" (instance (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
@@ -23,7 +23,7 @@
           (export (;3;) "c" (type (eq 2)))
         )
       )
-      (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+      (import "foo:foo/foo" (instance (;0;) (type 0)))
       (alias export 0 "c" (type (;1;)))
       (type (;2;)
         (instance
@@ -31,7 +31,7 @@
           (export (;1;) "c" (type (eq 0)))
         )
       )
-      (export (;1;) (interface "foo:foo/bar") (instance (type 2)))
+      (export (;1;) "foo:foo/bar" (instance (type 2)))
     )
   )
   (export (;3;) "bar" (type 2))
@@ -45,7 +45,7 @@
           (export (;3;) "c" (type (eq 2)))
         )
       )
-      (import (interface "foo:foo/foo") (instance (;0;) (type 0)))
+      (import "foo:foo/foo" (instance (;0;) (type 0)))
       (alias export 0 "c" (type (;1;)))
       (type (;2;)
         (instance
@@ -53,7 +53,7 @@
           (export (;1;) "c" (type (eq 0)))
         )
       )
-      (import (interface "foo:foo/bar") (instance (;1;) (type 2)))
+      (import "foo:foo/bar" (instance (;1;) (type 2)))
       (alias export 1 "c" (type (;3;)))
       (type (;4;)
         (instance
@@ -61,7 +61,7 @@
           (export (;1;) "c" (type (eq 0)))
         )
       )
-      (export (;2;) (interface "foo:foo/baz") (instance (type 4)))
+      (export (;2;) "foo:foo/baz" (instance (type 4)))
     )
   )
   (export (;5;) "baz" (type 4))
diff --git a/crates/wit-component/tests/interfaces/use-for-type.wat b/crates/wit-component/tests/interfaces/use-for-type.wat
index a6f44949..311ea136 100644
--- a/crates/wit-component/tests/interfaces/use-for-type.wat
+++ b/crates/wit-component/tests/interfaces/use-for-type.wat
@@ -4,7 +4,7 @@
       (type (;0;)
         (instance)
       )
-      (export (;0;) (interface "foo:foo/foo") (instance (type 0)))
+      (export (;0;) "foo:foo/foo" (instance (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
@@ -16,7 +16,7 @@
           (export (;1;) "t" (type (eq 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/bar") (instance (type 0)))
+      (export (;0;) "foo:foo/bar" (instance (type 0)))
     )
   )
   (export (;3;) "bar" (type 2))
@@ -28,7 +28,7 @@
           (export (;1;) "t" (type (eq 0)))
         )
       )
-      (import (interface "foo:foo/bar") (instance (;0;) (type 0)))
+      (import "foo:foo/bar" (instance (;0;) (type 0)))
       (alias export 0 "t" (type (;1;)))
       (type (;2;)
         (instance
@@ -38,7 +38,7 @@
           (export (;3;) "bar" (type (eq 2)))
         )
       )
-      (export (;1;) (interface "foo:foo/baz") (instance (type 2)))
+      (export (;1;) "foo:foo/baz" (instance (type 2)))
     )
   )
   (export (;5;) "baz" (type 4))
diff --git a/crates/wit-component/tests/interfaces/variants.wat b/crates/wit-component/tests/interfaces/variants.wat
index 2061db28..07221a52 100644
--- a/crates/wit-component/tests/interfaces/variants.wat
+++ b/crates/wit-component/tests/interfaces/variants.wat
@@ -88,7 +88,7 @@
           (export (;17;) "expected-simple" (func (type 64)))
         )
       )
-      (export (;0;) (interface "foo:variants/variants") (instance (type 0)))
+      (export (;0;) "foo:variants/variants" (instance (type 0)))
     )
   )
   (export (;1;) "variants" (type 0))
@@ -183,10 +183,10 @@
               (export (;17;) "expected-simple" (func (type 64)))
             )
           )
-          (import (interface "foo:variants/variants") (instance (;0;) (type 0)))
+          (import "foo:variants/variants" (instance (;0;) (type 0)))
         )
       )
-      (export (;0;) (interface "foo:variants/variants-world") (component (type 0)))
+      (export (;0;) "foo:variants/variants-world" (component (type 0)))
     )
   )
   (export (;3;) "variants-world" (type 2))
diff --git a/crates/wit-component/tests/interfaces/wasi-http.wat b/crates/wit-component/tests/interfaces/wasi-http.wat
index 2a9dce8e..969fb683 100644
--- a/crates/wit-component/tests/interfaces/wasi-http.wat
+++ b/crates/wit-component/tests/interfaces/wasi-http.wat
@@ -7,7 +7,7 @@
           (export (;1;) "pollable" (type (eq 0)))
         )
       )
-      (import (interface "wasi:poll/poll") (instance (;0;) (type 0)))
+      (import "wasi:poll/poll" (instance (;0;) (type 0)))
       (alias export 0 "pollable" (type (;1;)))
       (type (;2;)
         (instance
@@ -21,7 +21,7 @@
           (export (;7;) "output-stream" (type (eq 6)))
         )
       )
-      (import (interface "wasi:io/streams") (instance (;1;) (type 2)))
+      (import "wasi:io/streams" (instance (;1;) (type 2)))
       (alias export 1 "input-stream" (type (;3;)))
       (alias export 1 "output-stream" (type (;4;)))
       (type (;5;)
@@ -138,7 +138,7 @@
           (export (;32;) "listen-to-future-incoming-response" (func (type 76)))
         )
       )
-      (export (;2;) (interface "wasi:http/types") (instance (type 5)))
+      (export (;2;) "wasi:http/types" (instance (type 5)))
     )
   )
   (export (;1;) "types" (type 0))
@@ -150,7 +150,7 @@
           (export (;1;) "pollable" (type (eq 0)))
         )
       )
-      (import (interface "wasi:poll/poll") (instance (;0;) (type 0)))
+      (import "wasi:poll/poll" (instance (;0;) (type 0)))
       (alias export 0 "pollable" (type (;1;)))
       (type (;2;)
         (instance
@@ -164,7 +164,7 @@
           (export (;7;) "output-stream" (type (eq 6)))
         )
       )
-      (import (interface "wasi:io/streams") (instance (;1;) (type 2)))
+      (import "wasi:io/streams" (instance (;1;) (type 2)))
       (alias export 1 "input-stream" (type (;3;)))
       (alias export 1 "output-stream" (type (;4;)))
       (type (;5;)
@@ -206,7 +206,7 @@
           (export (;34;) "future-incoming-response" (type (eq 33)))
         )
       )
-      (import (interface "wasi:http/types") (instance (;2;) (type 5)))
+      (import "wasi:http/types" (instance (;2;) (type 5)))
       (alias export 2 "incoming-request" (type (;6;)))
       (alias export 2 "response-outparam" (type (;7;)))
       (type (;8;)
@@ -219,7 +219,7 @@
           (export (;0;) "handle" (func (type 4)))
         )
       )
-      (export (;3;) (interface "wasi:http/incoming-handler") (instance (type 8)))
+      (export (;3;) "wasi:http/incoming-handler" (instance (type 8)))
     )
   )
   (export (;3;) "incoming-handler" (type 2))
@@ -231,7 +231,7 @@
           (export (;1;) "pollable" (type (eq 0)))
         )
       )
-      (import (interface "wasi:poll/poll") (instance (;0;) (type 0)))
+      (import "wasi:poll/poll" (instance (;0;) (type 0)))
       (alias export 0 "pollable" (type (;1;)))
       (type (;2;)
         (instance
@@ -245,7 +245,7 @@
           (export (;7;) "output-stream" (type (eq 6)))
         )
       )
-      (import (interface "wasi:io/streams") (instance (;1;) (type 2)))
+      (import "wasi:io/streams" (instance (;1;) (type 2)))
       (alias export 1 "input-stream" (type (;3;)))
       (alias export 1 "output-stream" (type (;4;)))
       (type (;5;)
@@ -287,7 +287,7 @@
           (export (;34;) "future-incoming-response" (type (eq 33)))
         )
       )
-      (import (interface "wasi:http/types") (instance (;2;) (type 5)))
+      (import "wasi:http/types" (instance (;2;) (type 5)))
       (alias export 2 "outgoing-request" (type (;6;)))
       (alias export 2 "request-options" (type (;7;)))
       (alias export 2 "future-incoming-response" (type (;8;)))
@@ -304,7 +304,7 @@
           (export (;0;) "handle" (func (type 7)))
         )
       )
-      (export (;3;) (interface "wasi:http/outgoing-handler") (instance (type 9)))
+      (export (;3;) "wasi:http/outgoing-handler" (instance (type 9)))
     )
   )
   (export (;5;) "outgoing-handler" (type 4))
@@ -324,7 +324,7 @@
               (export (;2;) "insecure-random" (func (type 4)))
             )
           )
-          (import (interface "wasi:random/random") (instance (;0;) (type 0)))
+          (import "wasi:random/random" (instance (;0;) (type 0)))
           (type (;1;)
             (instance
               (type (;0;) (enum "trace" "debug" "info" "warn" "error"))
@@ -333,7 +333,7 @@
               (export (;0;) "log" (func (type 2)))
             )
           )
-          (import (interface "wasi:logging/handler") (instance (;1;) (type 1)))
+          (import "wasi:logging/handler" (instance (;1;) (type 1)))
           (type (;2;)
             (instance
               (type (;0;) u32)
@@ -346,7 +346,7 @@
               (export (;1;) "poll-oneoff" (func (type 5)))
             )
           )
-          (import (interface "wasi:poll/poll") (instance (;2;) (type 2)))
+          (import "wasi:poll/poll" (instance (;2;) (type 2)))
           (alias export 2 "pollable" (type (;3;)))
           (type (;4;)
             (instance
@@ -391,7 +391,7 @@
               (export (;14;) "drop-output-stream" (func (type 23)))
             )
           )
-          (import (interface "wasi:io/streams") (instance (;3;) (type 4)))
+          (import "wasi:io/streams" (instance (;3;) (type 4)))
           (alias export 3 "input-stream" (type (;5;)))
           (alias export 3 "output-stream" (type (;6;)))
           (type (;7;)
@@ -508,7 +508,7 @@
               (export (;32;) "listen-to-future-incoming-response" (func (type 76)))
             )
           )
-          (import (interface "wasi:http/types") (instance (;4;) (type 7)))
+          (import "wasi:http/types" (instance (;4;) (type 7)))
           (alias export 4 "outgoing-request" (type (;8;)))
           (alias export 4 "request-options" (type (;9;)))
           (alias export 4 "future-incoming-response" (type (;10;)))
@@ -525,7 +525,7 @@
               (export (;0;) "handle" (func (type 7)))
             )
           )
-          (import (interface "wasi:http/outgoing-handler") (instance (;5;) (type 11)))
+          (import "wasi:http/outgoing-handler" (instance (;5;) (type 11)))
           (alias export 4 "incoming-request" (type (;12;)))
           (alias export 4 "response-outparam" (type (;13;)))
           (type (;14;)
@@ -538,10 +538,10 @@
               (export (;0;) "handle" (func (type 4)))
             )
           )
-          (export (;6;) (interface "wasi:http/incoming-handler") (instance (type 14)))
+          (export (;6;) "wasi:http/incoming-handler" (instance (type 14)))
         )
       )
-      (export (;0;) (interface "wasi:http/proxy") (component (type 0)))
+      (export (;0;) "wasi:http/proxy" (component (type 0)))
     )
   )
   (export (;7;) "proxy" (type 6))
diff --git a/crates/wit-component/tests/interfaces/world-inline-interface.wat b/crates/wit-component/tests/interfaces/world-inline-interface.wat
index bfed860d..9138a0a1 100644
--- a/crates/wit-component/tests/interfaces/world-inline-interface.wat
+++ b/crates/wit-component/tests/interfaces/world-inline-interface.wat
@@ -13,7 +13,7 @@
           (export (;1;) "bar" (instance (type 1)))
         )
       )
-      (export (;0;) (interface "foo:foo/has-inline") (component (type 0)))
+      (export (;0;) "foo:foo/has-inline" (component (type 0)))
     )
   )
   (export (;1;) "has-inline" (type 0))
diff --git a/crates/wit-component/tests/interfaces/world-pkg-conflict.wat b/crates/wit-component/tests/interfaces/world-pkg-conflict.wat
index c0a4611c..ab7f94cd 100644
--- a/crates/wit-component/tests/interfaces/world-pkg-conflict.wat
+++ b/crates/wit-component/tests/interfaces/world-pkg-conflict.wat
@@ -7,7 +7,7 @@
           (export (;1;) "t" (type (eq 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/a") (instance (type 0)))
+      (export (;0;) "foo:foo/a" (instance (type 0)))
     )
   )
   (export (;1;) "a" (type 0))
@@ -19,7 +19,7 @@
           (export (;1;) "t" (type (eq 0)))
         )
       )
-      (import (interface "foo:foo/a") (instance (;0;) (type 0)))
+      (import "foo:foo/a" (instance (;0;) (type 0)))
       (alias export 0 "t" (type (;1;)))
       (type (;2;)
         (instance
@@ -27,7 +27,7 @@
           (export (;1;) "t" (type (eq 0)))
         )
       )
-      (export (;1;) (interface "foo:foo/foo") (instance (type 2)))
+      (export (;1;) "foo:foo/foo" (instance (type 2)))
     )
   )
   (export (;3;) "foo" (type 2))
@@ -36,7 +36,7 @@
       (type (;0;)
         (component)
       )
-      (export (;0;) (interface "foo:foo/c") (component (type 0)))
+      (export (;0;) "foo:foo/c" (component (type 0)))
     )
   )
   (export (;5;) "c" (type 4))
diff --git a/crates/wit-component/tests/interfaces/world-top-level.wat b/crates/wit-component/tests/interfaces/world-top-level.wat
index 1bd285cf..9a740034 100644
--- a/crates/wit-component/tests/interfaces/world-top-level.wat
+++ b/crates/wit-component/tests/interfaces/world-top-level.wat
@@ -20,7 +20,7 @@
           (export (;1;) "another-interface" (instance (type 4)))
         )
       )
-      (export (;0;) (interface "foo:foo/foo") (component (type 0)))
+      (export (;0;) "foo:foo/foo" (component (type 0)))
     )
   )
   (export (;1;) "foo" (type 0))
@@ -32,7 +32,7 @@
           (import "foo" (func (;0;) (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/just-import") (component (type 0)))
+      (export (;0;) "foo:foo/just-import" (component (type 0)))
     )
   )
   (export (;3;) "just-import" (type 2))
@@ -44,7 +44,7 @@
           (export (;0;) "foo" (func (type 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/just-export") (component (type 0)))
+      (export (;0;) "foo:foo/just-export" (component (type 0)))
     )
   )
   (export (;5;) "just-export" (type 4))
diff --git a/crates/wit-component/tests/interfaces/worlds-with-types.wat b/crates/wit-component/tests/interfaces/worlds-with-types.wat
index 4a983c2b..949c876c 100644
--- a/crates/wit-component/tests/interfaces/worlds-with-types.wat
+++ b/crates/wit-component/tests/interfaces/worlds-with-types.wat
@@ -7,7 +7,7 @@
           (export (;1;) "foo" (type (eq 0)))
         )
       )
-      (export (;0;) (interface "foo:foo/import-me") (instance (type 0)))
+      (export (;0;) "foo:foo/import-me" (instance (type 0)))
     )
   )
   (export (;1;) "import-me" (type 0))
@@ -23,7 +23,7 @@
           (export (;1;) "b" (func (type 3)))
         )
       )
-      (export (;0;) (interface "foo:foo/simple") (component (type 0)))
+      (export (;0;) "foo:foo/simple" (component (type 0)))
     )
   )
   (export (;3;) "simple" (type 2))
@@ -37,7 +37,7 @@
               (export (;1;) "foo" (type (eq 0)))
             )
           )
-          (import (interface "foo:foo/import-me") (instance (;0;) (type 0)))
+          (import "foo:foo/import-me" (instance (;0;) (type 0)))
           (alias export 0 "foo" (type (;1;)))
           (import "foo" (type (;2;) (eq 1)))
           (type (;3;) (func (param "a" 2)))
@@ -45,7 +45,7 @@
           (export (;1;) "b" (func (type 3)))
         )
       )
-      (export (;0;) (interface "foo:foo/with-imports") (component (type 0)))
+      (export (;0;) "foo:foo/with-imports" (component (type 0)))
     )
   )
   (export (;5;) "with-imports" (type 4))
diff --git a/tests/cli/dump/alias.wat.stdout b/tests/cli/dump/alias.wat.stdout
index 37f9689e..6e91d663 100644
--- a/tests/cli/dump/alias.wat.stdout
+++ b/tests/cli/dump/alias.wat.stdout
@@ -2,7 +2,7 @@
       | 0d 00 01 00
   0x8 | 07 1f       | component type section
   0xa | 01          | 1 count
-  0xb | 42 04 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab("f1"), ty: Func(0) }, Type(Func(ComponentFuncType { params: [("p1", Primitive(String))], results: Named([]) })), Export { name: Kebab("f2"), ty: Func(1) }])
+  0xb | 42 04 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName("f1"), ty: Func(0) }, Type(Func(ComponentFuncType { params: [("p1", Primitive(String))], results: Named([]) })), Export { name: ComponentExportName("f2"), ty: Func(1) }])
       | 00 01 00 04
       | 00 02 66 31
       | 01 00 01 40
@@ -12,7 +12,7 @@
       | 01 01      
  0x29 | 0a 06       | component import section
  0x2b | 01          | 1 count
- 0x2c | 00 01 69 05 | [instance 0] ComponentImport { name: Kebab("i"), ty: Instance(0) }
+ 0x2c | 00 01 69 05 | [instance 0] ComponentImport { name: ComponentImportName("i"), ty: Instance(0) }
       | 00         
  0x31 | 06 13       | component alias section
  0x33 | 03          | 3 count
diff --git a/tests/cli/dump/alias2.wat.stdout b/tests/cli/dump/alias2.wat.stdout
index b489dc93..4b8450e8 100644
--- a/tests/cli/dump/alias2.wat.stdout
+++ b/tests/cli/dump/alias2.wat.stdout
@@ -2,7 +2,7 @@
        | 0d 00 01 00
    0x8 | 07 30       | component type section
    0xa | 01          | 1 count
-   0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: Kebab("a"), ty: Module(0) }, Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab("b"), ty: Func(0) }, Export { name: Kebab("c"), ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: Kebab("d"), ty: Instance(1) }, Type(Component([])), Export { name: Kebab("e"), ty: Component(2) }])
+   0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: ComponentExportName("a"), ty: Module(0) }, Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName("b"), ty: Func(0) }, Export { name: ComponentExportName("c"), ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: ComponentExportName("d"), ty: Instance(1) }, Type(Component([])), Export { name: ComponentExportName("e"), ty: Component(2) }])
        | 00 04 00 01
        | 61 00 11 00
        | 01 40 00 01
@@ -16,7 +16,7 @@
        | 65 04 02   
   0x3a | 0a 06       | component import section
   0x3c | 01          | 1 count
-  0x3d | 00 01 61 05 | [instance 0] ComponentImport { name: Kebab("a"), ty: Instance(0) }
+  0x3d | 00 01 61 05 | [instance 0] ComponentImport { name: ComponentImportName("a"), ty: Instance(0) }
        | 00         
   0x42 | 04 59       | [component 0] inline size
     0x44 | 00 61 73 6d | version 13 (Component)
@@ -26,30 +26,30 @@
     0x4f | 50 00       | [core type 0] Module([])
     0x51 | 0a 07       | component import section
     0x53 | 01          | 1 count
-    0x54 | 00 01 61 00 | [module 0] ComponentImport { name: Kebab("a"), ty: Module(0) }
+    0x54 | 00 01 61 00 | [module 0] ComponentImport { name: ComponentImportName("a"), ty: Module(0) }
          | 11 00      
     0x5a | 07 05       | component type section
     0x5c | 01          | 1 count
     0x5d | 40 00 01 00 | [type 0] Func(ComponentFuncType { params: [], results: Named([]) })
     0x61 | 0a 0b       | component import section
     0x63 | 02          | 2 count
-    0x64 | 00 01 62 01 | [func 0] ComponentImport { name: Kebab("b"), ty: Func(0) }
+    0x64 | 00 01 62 01 | [func 0] ComponentImport { name: ComponentImportName("b"), ty: Func(0) }
          | 00         
-    0x69 | 00 01 63 02 | [value 0] ComponentImport { name: Kebab("c"), ty: Value(Primitive(String)) }
+    0x69 | 00 01 63 02 | [value 0] ComponentImport { name: ComponentImportName("c"), ty: Value(Primitive(String)) }
          | 73         
     0x6e | 07 03       | component type section
     0x70 | 01          | 1 count
     0x71 | 42 00       | [type 1] Instance([])
     0x73 | 0a 06       | component import section
     0x75 | 01          | 1 count
-    0x76 | 00 01 64 05 | [instance 0] ComponentImport { name: Kebab("d"), ty: Instance(1) }
+    0x76 | 00 01 64 05 | [instance 0] ComponentImport { name: ComponentImportName("d"), ty: Instance(1) }
          | 01         
     0x7b | 07 03       | component type section
     0x7d | 01          | 1 count
     0x7e | 41 00       | [type 2] Component([])
     0x80 | 0a 06       | component import section
     0x82 | 01          | 1 count
-    0x83 | 00 01 65 04 | [component 0] ComponentImport { name: Kebab("e"), ty: Component(2) }
+    0x83 | 00 01 65 04 | [component 0] ComponentImport { name: ComponentImportName("e"), ty: Component(2) }
          | 02         
     0x88 | 00 13       | custom section
     0x8a | 0e 63 6f 6d | name: "component-name"
@@ -86,7 +86,7 @@
     0xe2 | 03 02 01 00 | alias [type 0] Outer { kind: Type, count: 1, index: 0 }
     0xe6 | 0a 06       | component import section
     0xe8 | 01          | 1 count
-    0xe9 | 00 01 61 05 | [instance 0] ComponentImport { name: Kebab("a"), ty: Instance(0) }
+    0xe9 | 00 01 61 05 | [instance 0] ComponentImport { name: ComponentImportName("a"), ty: Instance(0) }
          | 00         
     0xee | 00 1b       | custom section
     0xf0 | 0e 63 6f 6d | name: "component-name"
@@ -112,7 +112,7 @@
        | 65         
  0x128 | 05 24       | component instance section
  0x12a | 02          | 2 count
- 0x12b | 01 05 00 01 | [instance 4] FromExports([ComponentExport { name: Kebab("a"), kind: Module, index: 1, ty: None }, ComponentExport { name: Kebab("b"), kind: Func, index: 1, ty: None }, ComponentExport { name: Kebab("c"), kind: Value, index: 1, ty: None }, ComponentExport { name: Kebab("d"), kind: Instance, index: 3, ty: None }, ComponentExport { name: Kebab("e"), kind: Component, index: 3, ty: None }])
+ 0x12b | 01 05 00 01 | [instance 4] FromExports([ComponentExport { name: ComponentExportName("a"), kind: Module, index: 1, ty: None }, ComponentExport { name: ComponentExportName("b"), kind: Func, index: 1, ty: None }, ComponentExport { name: ComponentExportName("c"), kind: Value, index: 1, ty: None }, ComponentExport { name: ComponentExportName("d"), kind: Instance, index: 3, ty: None }, ComponentExport { name: ComponentExportName("e"), kind: Component, index: 3, ty: None }])
        | 61 00 11 01
        | 00 01 62 01
        | 01 00 01 63
diff --git a/tests/cli/dump/bundled.wat.stdout b/tests/cli/dump/bundled.wat.stdout
index ad449f16..7564ea09 100644
--- a/tests/cli/dump/bundled.wat.stdout
+++ b/tests/cli/dump/bundled.wat.stdout
@@ -2,7 +2,7 @@
        | 0d 00 01 00
    0x8 | 07 30       | component type section
    0xa | 01          | 1 count
-   0xb | 42 06 01 70 | [type 0] Instance([Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("len", Primitive(U32))], results: Unnamed(Type(0)) })), Export { name: Kebab("read"), ty: Func(1) }, Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("buf", Type(2))], results: Unnamed(Primitive(U32)) })), Export { name: Kebab("write"), ty: Func(3) }])
+   0xb | 42 06 01 70 | [type 0] Instance([Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("len", Primitive(U32))], results: Unnamed(Type(0)) })), Export { name: ComponentExportName("read"), ty: Func(1) }, Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("buf", Type(2))], results: Unnamed(Primitive(U32)) })), Export { name: ComponentExportName("write"), ty: Func(3) }])
        | 7d 01 40 01
        | 03 6c 65 6e
        | 79 00 00 04
@@ -16,7 +16,7 @@
        | 65 01 03   
   0x3a | 0a 0e       | component import section
   0x3c | 01          | 1 count
-  0x3d | 00 09 77 61 | [instance 0] ComponentImport { name: Kebab("wasi-file"), ty: Instance(0) }
+  0x3d | 00 09 77 61 | [instance 0] ComponentImport { name: ComponentImportName("wasi-file"), ty: Instance(0) }
        | 73 69 2d 66
        | 69 6c 65 05
        | 00         
@@ -189,7 +189,7 @@
        | 01         
  0x1e0 | 0b 0a       | component export section
  0x1e2 | 01          | 1 count
- 0x1e3 | 00 04 77 6f | export ComponentExport { name: Kebab("work"), kind: Func, index: 1, ty: None }
+ 0x1e3 | 00 04 77 6f | export ComponentExport { name: ComponentExportName("work"), kind: Func, index: 1, ty: None }
        | 72 6b 01 01
        | 00         
  0x1ec | 00 7c       | custom section
diff --git a/tests/cli/dump/component-expand-bundle2.wat.stdout b/tests/cli/dump/component-expand-bundle2.wat.stdout
index 33d358ff..b525afcd 100644
--- a/tests/cli/dump/component-expand-bundle2.wat.stdout
+++ b/tests/cli/dump/component-expand-bundle2.wat.stdout
@@ -8,7 +8,7 @@
           | 01 00 00 00
    0x1c | 0b 08       | component export section
    0x1e | 01          | 1 count
-   0x1f | 00 01 65 00 | export ComponentExport { name: Kebab("e"), kind: Module, index: 0, ty: None }
+   0x1f | 00 01 65 00 | export ComponentExport { name: ComponentExportName("e"), kind: Module, index: 0, ty: None }
         | 11 00 00   
    0x26 | 00 13       | custom section
    0x28 | 0e 63 6f 6d | name: "component-name"
@@ -22,12 +22,12 @@
         | 0d 00 01 00
    0x45 | 07 0d       | component type section
    0x47 | 01          | 1 count
-   0x48 | 41 02 00 50 | [type 0] Component([CoreType(Module([])), Import(ComponentImport { name: Kebab("i"), ty: Module(0) })])
+   0x48 | 41 02 00 50 | [type 0] Component([CoreType(Module([])), Import(ComponentImport { name: ComponentImportName("i"), ty: Module(0) })])
         | 00 03 00 01
         | 69 00 11 00
    0x54 | 0a 06       | component import section
    0x56 | 01          | 1 count
-   0x57 | 00 01 69 04 | [component 0] ComponentImport { name: Kebab("i"), ty: Component(0) }
+   0x57 | 00 01 69 04 | [component 0] ComponentImport { name: ComponentImportName("i"), ty: Component(0) }
         | 00         
    0x5c | 00 14       | custom section
    0x5e | 0e 63 6f 6d | name: "component-name"
@@ -45,7 +45,7 @@
       | 01 65      
  0x81 | 05 10       | component instance section
  0x83 | 02          | 2 count
- 0x84 | 01 01 00 01 | [instance 1] FromExports([ComponentExport { name: Kebab("e"), kind: Module, index: 0, ty: None }])
+ 0x84 | 01 01 00 01 | [instance 1] FromExports([ComponentExport { name: ComponentExportName("e"), kind: Module, index: 0, ty: None }])
       | 65 00 11 00
  0x8c | 00 01 01 01 | [instance 2] Instantiate { component_index: 1, args: [ComponentInstantiationArg { name: "i", kind: Instance, index: 1 }] }
       | 69 05 01   
diff --git a/tests/cli/dump/component-inline-export-import.wat.stdout b/tests/cli/dump/component-inline-export-import.wat.stdout
index 8ac44f5c..3a51b4e5 100644
--- a/tests/cli/dump/component-inline-export-import.wat.stdout
+++ b/tests/cli/dump/component-inline-export-import.wat.stdout
@@ -5,17 +5,17 @@
   0xb | 41 00       | [type 0] Component([])
   0xd | 0a 05       | component import section
   0xf | 01          | 1 count
- 0x10 | 00 00 04 00 | [component 0] ComponentImport { name: Kebab(""), ty: Component(0) }
+ 0x10 | 00 00 04 00 | [component 0] ComponentImport { name: ComponentImportName(""), ty: Component(0) }
  0x14 | 03 03       | core type section
  0x16 | 01          | 1 count
  0x17 | 50 00       | [core type 0] Module([])
  0x19 | 0a 07       | component import section
  0x1b | 01          | 1 count
- 0x1c | 00 01 61 00 | [module 0] ComponentImport { name: Kebab("a"), ty: Module(0) }
+ 0x1c | 00 01 61 00 | [module 0] ComponentImport { name: ComponentImportName("a"), ty: Module(0) }
       | 11 00      
  0x22 | 0b 0d       | component export section
  0x24 | 02          | 2 count
- 0x25 | 00 00 04 00 | export ComponentExport { name: Kebab(""), kind: Component, index: 0, ty: None }
+ 0x25 | 00 00 04 00 | export ComponentExport { name: ComponentExportName(""), kind: Component, index: 0, ty: None }
       | 00         
- 0x2a | 00 01 61 00 | export ComponentExport { name: Kebab("a"), kind: Module, index: 0, ty: None }
+ 0x2a | 00 01 61 00 | export ComponentExport { name: ComponentExportName("a"), kind: Module, index: 0, ty: None }
       | 11 00 00   
diff --git a/tests/cli/dump/component-inline-type.wat.stdout b/tests/cli/dump/component-inline-type.wat.stdout
index d6d55e5d..77917a71 100644
--- a/tests/cli/dump/component-inline-type.wat.stdout
+++ b/tests/cli/dump/component-inline-type.wat.stdout
@@ -5,26 +5,26 @@
   0xb | 41 00       | [type 0] Component([])
   0xd | 0a 06       | component import section
   0xf | 01          | 1 count
- 0x10 | 00 01 61 04 | [component 0] ComponentImport { name: Kebab("a"), ty: Component(0) }
+ 0x10 | 00 01 61 04 | [component 0] ComponentImport { name: ComponentImportName("a"), ty: Component(0) }
       | 00         
  0x15 | 03 03       | core type section
  0x17 | 01          | 1 count
  0x18 | 50 00       | [core type 0] Module([])
  0x1a | 0a 07       | component import section
  0x1c | 01          | 1 count
- 0x1d | 00 01 62 00 | [module 0] ComponentImport { name: Kebab("b"), ty: Module(0) }
+ 0x1d | 00 01 62 00 | [module 0] ComponentImport { name: ComponentImportName("b"), ty: Module(0) }
       | 11 00      
  0x23 | 07 03       | component type section
  0x25 | 01          | 1 count
  0x26 | 42 00       | [type 1] Instance([])
  0x28 | 0a 06       | component import section
  0x2a | 01          | 1 count
- 0x2b | 00 01 63 05 | [instance 0] ComponentImport { name: Kebab("c"), ty: Instance(1) }
+ 0x2b | 00 01 63 05 | [instance 0] ComponentImport { name: ComponentImportName("c"), ty: Instance(1) }
       | 01         
  0x30 | 07 05       | component type section
  0x32 | 01          | 1 count
  0x33 | 40 00 01 00 | [type 2] Func(ComponentFuncType { params: [], results: Named([]) })
  0x37 | 0a 06       | component import section
  0x39 | 01          | 1 count
- 0x3a | 00 01 64 01 | [func 0] ComponentImport { name: Kebab("d"), ty: Func(2) }
+ 0x3a | 00 01 64 01 | [func 0] ComponentImport { name: ComponentImportName("d"), ty: Func(2) }
       | 02         
diff --git a/tests/cli/dump/component-instance-type.wat.stdout b/tests/cli/dump/component-instance-type.wat.stdout
index 384d8f18..6b299f2b 100644
--- a/tests/cli/dump/component-instance-type.wat.stdout
+++ b/tests/cli/dump/component-instance-type.wat.stdout
@@ -2,7 +2,7 @@
       | 0d 00 01 00
   0x8 | 07 28       | component type section
   0xa | 01          | 1 count
-  0xb | 42 03 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Type(Component([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Alias(Outer { kind: Type, count: 1, index: 0 }), Import(ComponentImport { name: Kebab("1"), ty: Func(0) }), Export { name: Kebab("1"), ty: Func(1) }])), Export { name: Kebab("c5"), ty: Component(1) }])
+  0xb | 42 03 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Type(Component([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Alias(Outer { kind: Type, count: 1, index: 0 }), Import(ComponentImport { name: ComponentImportName("1"), ty: Func(0) }), Export { name: ComponentExportName("1"), ty: Func(1) }])), Export { name: ComponentExportName("c5"), ty: Component(1) }])
       | 00 01 00 01
       | 41 04 01 40
       | 00 01 00 02
diff --git a/tests/cli/dump/component-linking.wat.stdout b/tests/cli/dump/component-linking.wat.stdout
index 70d09f8f..4dd685fa 100644
--- a/tests/cli/dump/component-linking.wat.stdout
+++ b/tests/cli/dump/component-linking.wat.stdout
@@ -2,7 +2,7 @@
       | 0d 00 01 00
   0x8 | 07 30       | component type section
   0xa | 01          | 1 count
-  0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: Kebab("a"), ty: Module(0) }, Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab("b"), ty: Func(0) }, Export { name: Kebab("c"), ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: Kebab("d"), ty: Instance(1) }, Type(Component([])), Export { name: Kebab("e"), ty: Component(2) }])
+  0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: ComponentExportName("a"), ty: Module(0) }, Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName("b"), ty: Func(0) }, Export { name: ComponentExportName("c"), ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: ComponentExportName("d"), ty: Instance(1) }, Type(Component([])), Export { name: ComponentExportName("e"), ty: Component(2) }])
       | 00 04 00 01
       | 61 00 11 00
       | 01 40 00 01
@@ -16,7 +16,7 @@
       | 65 04 02   
  0x3a | 0a 06       | component import section
  0x3c | 01          | 1 count
- 0x3d | 00 01 61 05 | [instance 0] ComponentImport { name: Kebab("a"), ty: Instance(0) }
+ 0x3d | 00 01 61 05 | [instance 0] ComponentImport { name: ComponentImportName("a"), ty: Instance(0) }
       | 00         
  0x42 | 04 59       | [component 0] inline size
    0x44 | 00 61 73 6d | version 13 (Component)
@@ -26,30 +26,30 @@
    0x4f | 50 00       | [core type 0] Module([])
    0x51 | 0a 07       | component import section
    0x53 | 01          | 1 count
-   0x54 | 00 01 61 00 | [module 0] ComponentImport { name: Kebab("a"), ty: Module(0) }
+   0x54 | 00 01 61 00 | [module 0] ComponentImport { name: ComponentImportName("a"), ty: Module(0) }
         | 11 00      
    0x5a | 07 05       | component type section
    0x5c | 01          | 1 count
    0x5d | 40 00 01 00 | [type 0] Func(ComponentFuncType { params: [], results: Named([]) })
    0x61 | 0a 0b       | component import section
    0x63 | 02          | 2 count
-   0x64 | 00 01 62 01 | [func 0] ComponentImport { name: Kebab("b"), ty: Func(0) }
+   0x64 | 00 01 62 01 | [func 0] ComponentImport { name: ComponentImportName("b"), ty: Func(0) }
         | 00         
-   0x69 | 00 01 63 02 | [value 0] ComponentImport { name: Kebab("c"), ty: Value(Primitive(String)) }
+   0x69 | 00 01 63 02 | [value 0] ComponentImport { name: ComponentImportName("c"), ty: Value(Primitive(String)) }
         | 73         
    0x6e | 07 03       | component type section
    0x70 | 01          | 1 count
    0x71 | 42 00       | [type 1] Instance([])
    0x73 | 0a 06       | component import section
    0x75 | 01          | 1 count
-   0x76 | 00 01 64 05 | [instance 0] ComponentImport { name: Kebab("d"), ty: Instance(1) }
+   0x76 | 00 01 64 05 | [instance 0] ComponentImport { name: ComponentImportName("d"), ty: Instance(1) }
         | 01         
    0x7b | 07 03       | component type section
    0x7d | 01          | 1 count
    0x7e | 41 00       | [type 2] Component([])
    0x80 | 0a 06       | component import section
    0x82 | 01          | 1 count
-   0x83 | 00 01 65 04 | [component 0] ComponentImport { name: Kebab("e"), ty: Component(2) }
+   0x83 | 00 01 65 04 | [component 0] ComponentImport { name: ComponentImportName("e"), ty: Component(2) }
         | 02         
    0x88 | 00 13       | custom section
    0x8a | 0e 63 6f 6d | name: "component-name"
diff --git a/tests/cli/dump/import-modules.wat.stdout b/tests/cli/dump/import-modules.wat.stdout
index 4c4f2b55..d74315c5 100644
--- a/tests/cli/dump/import-modules.wat.stdout
+++ b/tests/cli/dump/import-modules.wat.stdout
@@ -7,7 +7,7 @@
       | 01 66 00 00
  0x17 | 0a 07       | component import section
  0x19 | 01          | 1 count
- 0x1a | 00 01 61 00 | [module 0] ComponentImport { name: Kebab("a"), ty: Module(0) }
+ 0x1a | 00 01 61 00 | [module 0] ComponentImport { name: ComponentImportName("a"), ty: Module(0) }
       | 11 00      
  0x20 | 01 2b       | [core module 1] inline size
    0x22 | 00 61 73 6d | version 1 (Module)
diff --git a/tests/cli/dump/instance-expand.wat.stdout b/tests/cli/dump/instance-expand.wat.stdout
index eccb9aad..c61e1f9a 100644
--- a/tests/cli/dump/instance-expand.wat.stdout
+++ b/tests/cli/dump/instance-expand.wat.stdout
@@ -2,12 +2,12 @@
       | 0d 00 01 00
   0x8 | 07 0d       | component type section
   0xa | 01          | 1 count
-  0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab(""), ty: Func(0) }])
+  0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName(""), ty: Func(0) }])
       | 00 01 00 04
       | 00 00 01 00
  0x17 | 0a 06       | component import section
  0x19 | 01          | 1 count
- 0x1a | 00 01 61 05 | [instance 0] ComponentImport { name: Kebab("a"), ty: Instance(0) }
+ 0x1a | 00 01 61 05 | [instance 0] ComponentImport { name: ComponentImportName("a"), ty: Instance(0) }
       | 00         
  0x1f | 00 16       | custom section
  0x21 | 0e 63 6f 6d | name: "component-name"
diff --git a/tests/cli/dump/instance-type.wat.stdout b/tests/cli/dump/instance-type.wat.stdout
index 98c33d3f..83ad5fbe 100644
--- a/tests/cli/dump/instance-type.wat.stdout
+++ b/tests/cli/dump/instance-type.wat.stdout
@@ -2,9 +2,9 @@
       | 0d 00 01 00
   0x8 | 07 17       | component type section
   0xa | 02          | 2 count
-  0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab(""), ty: Func(0) }])
+  0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName(""), ty: Func(0) }])
       | 00 01 00 04
       | 00 00 01 00
- 0x17 | 42 02 01 42 | [type 1] Instance([Type(Instance([])), Export { name: Kebab(""), ty: Instance(0) }])
+ 0x17 | 42 02 01 42 | [type 1] Instance([Type(Instance([])), Export { name: ComponentExportName(""), ty: Instance(0) }])
       | 00 04 00 00
       | 05 00      
diff --git a/tests/cli/dump/instance-type2.wat.stdout b/tests/cli/dump/instance-type2.wat.stdout
index 6504991a..cbe5db9f 100644
--- a/tests/cli/dump/instance-type2.wat.stdout
+++ b/tests/cli/dump/instance-type2.wat.stdout
@@ -3,10 +3,10 @@
   0x8 | 07 18       | component type section
   0xa | 04          | 4 count
   0xb | 42 00       | [type 0] Instance([])
-  0xd | 42 01 04 00 | [type 1] Instance([Export { name: Kebab(""), ty: Instance(0) }])
+  0xd | 42 01 04 00 | [type 1] Instance([Export { name: ComponentExportName(""), ty: Instance(0) }])
       | 00 05 00   
  0x14 | 42 00       | [type 2] Instance([])
- 0x16 | 42 02 02 03 | [type 3] Instance([Alias(Outer { kind: Type, count: 1, index: 2 }), Export { name: Kebab(""), ty: Instance(0) }])
+ 0x16 | 42 02 02 03 | [type 3] Instance([Alias(Outer { kind: Type, count: 1, index: 2 }), Export { name: ComponentExportName(""), ty: Instance(0) }])
       | 02 01 02 04
       | 00 00 05 00
  0x22 | 00 16       | custom section
diff --git a/tests/cli/dump/instantiate.wat.stdout b/tests/cli/dump/instantiate.wat.stdout
index c72f083c..eb3537a3 100644
--- a/tests/cli/dump/instantiate.wat.stdout
+++ b/tests/cli/dump/instantiate.wat.stdout
@@ -5,14 +5,14 @@
   0xb | 41 00       | [type 0] Component([])
   0xd | 0a 06       | component import section
   0xf | 01          | 1 count
- 0x10 | 00 01 61 04 | [component 0] ComponentImport { name: Kebab("a"), ty: Component(0) }
+ 0x10 | 00 01 61 04 | [component 0] ComponentImport { name: ComponentImportName("a"), ty: Component(0) }
       | 00         
  0x15 | 07 05       | component type section
  0x17 | 01          | 1 count
  0x18 | 40 00 01 00 | [type 1] Func(ComponentFuncType { params: [], results: Named([]) })
  0x1c | 0a 06       | component import section
  0x1e | 01          | 1 count
- 0x1f | 00 01 66 01 | [func 0] ComponentImport { name: Kebab("f"), ty: Func(1) }
+ 0x1f | 00 01 66 01 | [func 0] ComponentImport { name: ComponentImportName("f"), ty: Func(1) }
       | 01         
  0x24 | 05 08       | component instance section
  0x26 | 01          | 1 count
diff --git a/tests/cli/dump/instantiate2.wat.stdout b/tests/cli/dump/instantiate2.wat.stdout
index 7f0462c1..19ccd6ea 100644
--- a/tests/cli/dump/instantiate2.wat.stdout
+++ b/tests/cli/dump/instantiate2.wat.stdout
@@ -2,13 +2,13 @@
       | 0d 00 01 00
   0x8 | 07 0e       | component type section
   0xa | 01          | 1 count
-  0xb | 41 02 01 40 | [type 0] Component([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Import(ComponentImport { name: Kebab("a"), ty: Func(0) })])
+  0xb | 41 02 01 40 | [type 0] Component([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Import(ComponentImport { name: ComponentImportName("a"), ty: Func(0) })])
       | 00 01 00 03
       | 00 01 61 01
       | 00         
  0x18 | 0a 06       | component import section
  0x1a | 01          | 1 count
- 0x1b | 00 01 61 04 | [component 0] ComponentImport { name: Kebab("a"), ty: Component(0) }
+ 0x1b | 00 01 61 04 | [component 0] ComponentImport { name: ComponentImportName("a"), ty: Component(0) }
       | 00         
  0x20 | 05 04       | component instance section
  0x22 | 01          | 1 count
diff --git a/tests/cli/dump/module-types.wat.stdout b/tests/cli/dump/module-types.wat.stdout
index 2430291f..d45a9a00 100644
--- a/tests/cli/dump/module-types.wat.stdout
+++ b/tests/cli/dump/module-types.wat.stdout
@@ -13,7 +13,7 @@
       | 00 01      
  0x2d | 0a 07       | component import section
  0x2f | 01          | 1 count
- 0x30 | 00 01 61 00 | [module 0] ComponentImport { name: Kebab("a"), ty: Module(0) }
+ 0x30 | 00 01 61 00 | [module 0] ComponentImport { name: ComponentImportName("a"), ty: Module(0) }
       | 11 00      
  0x36 | 07 03       | component type section
  0x38 | 01          | 1 count
diff --git a/tests/cli/dump/nested-component.wat.stdout b/tests/cli/dump/nested-component.wat.stdout
index f06093db..abb57173 100644
--- a/tests/cli/dump/nested-component.wat.stdout
+++ b/tests/cli/dump/nested-component.wat.stdout
@@ -5,7 +5,7 @@
   0xb | 41 00       | [type 0] Component([])
   0xd | 0a 06       | component import section
   0xf | 01          | 1 count
- 0x10 | 00 01 61 04 | [component 0] ComponentImport { name: Kebab("a"), ty: Component(0) }
+ 0x10 | 00 01 61 04 | [component 0] ComponentImport { name: ComponentImportName("a"), ty: Component(0) }
       | 00         
  0x15 | 04 08       | [component 1] inline size
    0x17 | 00 61 73 6d | version 13 (Component)
@@ -39,25 +39,25 @@
         | 73 01 00   
    0x70 | 0a 06       | component import section
    0x72 | 01          | 1 count
-   0x73 | 00 01 61 01 | [func 0] ComponentImport { name: Kebab("a"), ty: Func(0) }
+   0x73 | 00 01 61 01 | [func 0] ComponentImport { name: ComponentImportName("a"), ty: Func(0) }
         | 00         
    0x78 | 0b 08       | component export section
    0x7a | 01          | 1 count
-   0x7b | 00 01 61 00 | export ComponentExport { name: Kebab("a"), kind: Module, index: 0, ty: None }
+   0x7b | 00 01 61 00 | export ComponentExport { name: ComponentExportName("a"), kind: Module, index: 0, ty: None }
         | 11 00 00   
    0x82 | 07 0e       | component type section
    0x84 | 01          | 1 count
-   0x85 | 42 02 01 40 | [type 1] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab("a"), ty: Func(0) }])
+   0x85 | 42 02 01 40 | [type 1] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: ComponentExportName("a"), ty: Func(0) }])
         | 00 01 00 04
         | 00 01 61 01
         | 00         
    0x92 | 0a 06       | component import section
    0x94 | 01          | 1 count
-   0x95 | 00 01 62 05 | [instance 0] ComponentImport { name: Kebab("b"), ty: Instance(1) }
+   0x95 | 00 01 62 05 | [instance 0] ComponentImport { name: ComponentImportName("b"), ty: Instance(1) }
         | 01         
    0x9a | 0b 07       | component export section
    0x9c | 01          | 1 count
-   0x9d | 00 01 62 05 | export ComponentExport { name: Kebab("b"), kind: Instance, index: 0, ty: None }
+   0x9d | 00 01 62 05 | export ComponentExport { name: ComponentExportName("b"), kind: Instance, index: 0, ty: None }
         | 00 00      
    0xa3 | 00 17       | custom section
    0xa5 | 0e 63 6f 6d | name: "component-name"
@@ -69,5 +69,5 @@
    0xb9 | 00 01 6d    | Naming { index: 0, name: "m" }
  0xbc | 0b 07       | component export section
  0xbe | 01          | 1 count
- 0xbf | 00 01 61 04 | export ComponentExport { name: Kebab("a"), kind: Component, index: 3, ty: None }
+ 0xbf | 00 01 61 04 | export ComponentExport { name: ComponentExportName("a"), kind: Component, index: 3, ty: None }
       | 03 00      
diff --git a/tests/local/component-model/export.wast b/tests/local/component-model/export.wast
index e9d6146b..614f9133 100644
--- a/tests/local/component-model/export.wast
+++ b/tests/local/component-model/export.wast
@@ -51,3 +51,20 @@
   (import (interface "wasi:http/types@2.0.0") (func))
   (export (interface "wasi:http/types@2.0.0") (func 0))
 )
+
+;; cannot export some types of strings
+(assert_invalid
+  (component (type (component (export "integrity=<sha256-a>" (func)))))
+  "not a valid export name")
+(assert_invalid
+  (component (type (component (export "url=<x>" (func)))))
+  "not a valid export name")
+(assert_invalid
+  (component (type (component (export "relative-url=<x>" (func)))))
+  "not a valid export name")
+(assert_invalid
+  (component (type (component (export "locked-dep=<a:b>" (func)))))
+  "not a valid export name")
+(assert_invalid
+  (component (type (component (export "unlocked-dep=<a:b>" (func)))))
+  "not a valid export name")
diff --git a/tests/local/component-model/import.wast b/tests/local/component-model/import.wast
index f5509298..485a9a73 100644
--- a/tests/local/component-model/import.wast
+++ b/tests/local/component-model/import.wast
@@ -109,80 +109,209 @@
 )
 
 (component
-  (import (interface "wasi:http/types") (func))
-  (import (interface "wasi:http/types@1.0.0") (func))
-  (import (interface "wasi:http/types@2.0.0") (func))
-  (import (interface "a-b:c-d/e-f@123456.7890.488") (func))
-  (import (interface "a:b/c@1.2.3") (func))
-  (import (interface "a:b/c@0.0.0") (func))
-  (import (interface "a:b/c@0.0.0+abcd") (func))
-  (import (interface "a:b/c@0.0.0+abcd-efg") (func))
-  (import (interface "a:b/c@0.0.0-abcd+efg") (func))
-  (import (interface "a:b/c@0.0.0-abcd.1.2+efg.4.ee.5") (func))
+  (import "wasi:http/types" (func))
+  (import "wasi:http/types@1.0.0" (func))
+  (import "wasi:http/types@2.0.0" (func))
+  (import "a-b:c-d/e-f@123456.7890.488" (func))
+  (import "a:b/c@1.2.3" (func))
+  (import "a:b/c@0.0.0" (func))
+  (import "a:b/c@0.0.0+abcd" (func))
+  (import "a:b/c@0.0.0+abcd-efg" (func))
+  (import "a:b/c@0.0.0-abcd+efg" (func))
+  (import "a:b/c@0.0.0-abcd.1.2+efg.4.ee.5" (func))
 )
 
 (assert_invalid
   (component
-    (import (interface "wasi:http/types") (func))
-    (import (interface "wasi:http/types") (func))
+    (import "wasi:http/types" (func))
+    (import "wasi:http/types" (func))
   )
   "conflicts with previous name")
 
 (assert_invalid
-  (component (import (interface "") (func)))
-  "failed to find `:` character")
+  (component (import "" (func)))
+  "`` is not in kebab case")
 (assert_invalid
-  (component (import (interface "wasi") (func)))
-  "failed to find `:` character")
-(assert_invalid
-  (component (import (interface "wasi:") (func)))
+  (component (import "wasi:" (func)))
   "failed to find `/` character")
 (assert_invalid
-  (component (import (interface "wasi:/") (func)))
+  (component (import "wasi:/" (func)))
   "not in kebab case")
 (assert_invalid
-  (component (import (interface ":/") (func)))
+  (component (import ":/" (func)))
   "not in kebab case")
 (assert_invalid
-  (component (import (interface "wasi/http") (func)))
-  "failed to find `:` character")
+  (component (import "wasi/http" (func)))
+  "`wasi/http` is not in kebab case")
 (assert_invalid
-  (component (import (interface "wasi:http/TyPeS") (func)))
+  (component (import "wasi:http/TyPeS" (func)))
   "`TyPeS` is not in kebab case")
 (assert_invalid
-  (component (import (interface "WaSi:http/types") (func)))
+  (component (import "WaSi:http/types" (func)))
   "`WaSi` is not in kebab case")
 (assert_invalid
-  (component (import (interface "wasi:HtTp/types") (func)))
+  (component (import "wasi:HtTp/types" (func)))
   "`HtTp` is not in kebab case")
 (assert_invalid
-  (component (import (interface "wasi:http/types@") (func)))
+  (component (import "wasi:http/types@" (func)))
   "empty string")
 (assert_invalid
-  (component (import (interface "wasi:http/types@.") (func)))
+  (component (import "wasi:http/types@." (func)))
   "unexpected character '.'")
 (assert_invalid
-  (component (import (interface "wasi:http/types@1.") (func)))
+  (component (import "wasi:http/types@1." (func)))
   "unexpected end of input")
 (assert_invalid
-  (component (import (interface "wasi:http/types@a.2") (func)))
+  (component (import "wasi:http/types@a.2" (func)))
   "unexpected character 'a'")
 (assert_invalid
-  (component (import (interface "wasi:http/types@2.b") (func)))
+  (component (import "wasi:http/types@2.b" (func)))
   "unexpected character 'b'")
 (assert_invalid
-  (component (import (interface "wasi:http/types@2.0x0") (func)))
+  (component (import "wasi:http/types@2.0x0" (func)))
   "unexpected character 'x'")
 (assert_invalid
-  (component (import (interface "wasi:http/types@2.0.0+") (func)))
+  (component (import "wasi:http/types@2.0.0+" (func)))
   "empty identifier segment")
 (assert_invalid
-  (component (import (interface "wasi:http/types@2.0.0-") (func)))
+  (component (import "wasi:http/types@2.0.0-" (func)))
   "empty identifier segment")
 
+(component
+  (import "a" (func $a))
+  (export "a" (func $a))
+)
+
+
+(component
+  (import "unlocked-dep=<a:b>" (func))
+  (import "unlocked-dep=<a:b@*>" (func))
+  (import "unlocked-dep=<a:b@{>=1.2.3}>" (func))
+  (import "unlocked-dep=<a:b@{>=1.2.3-rc}>" (func))
+  (import "unlocked-dep=<a:b@{<1.2.3}>" (func))
+  (import "unlocked-dep=<a:b@{<1.2.3-rc}>" (func))
+  (import "unlocked-dep=<a:b@{>=1.2.3 <1.2.3}>" (func))
+  (import "unlocked-dep=<a:b@{>=1.2.3-rc <1.2.3}>" (func))
+)
+
 (assert_invalid
-  (component
-    (import "a" (func $a))
-    (export "a" (func $a))
-  )
-  "export name `a` conflicts with previous name `a`")
+  (component (import "unlocked-dep=" (func)))
+  "expected `<` at ``")
+(assert_invalid
+  (component (import "unlocked-dep=<" (func)))
+  "failed to find `:`")
+(assert_invalid
+  (component (import "unlocked-dep=<>" (func)))
+  "failed to find `:`")
+(assert_invalid
+  (component (import "unlocked-dep=<:>" (func)))
+  "`` is not in kebab case")
+(assert_invalid
+  (component (import "unlocked-dep=<a:>" (func)))
+  "`` is not in kebab case")
+(assert_invalid
+  (component (import "unlocked-dep=<:a>" (func)))
+  "`` is not in kebab case")
+(assert_invalid
+  (component (import "unlocked-dep=<a:a@>" (func)))
+  "expected `{` at `>`")
+(assert_invalid
+  (component (import "unlocked-dep=<a:a@{xyz}>" (func)))
+  "expected `<` at `xyz}>`")
+(assert_invalid
+  (component (import "unlocked-dep=<a:a@{<xyz}>" (func)))
+  "`xyz` is not a valid semver")
+(assert_invalid
+  (component (import "unlocked-dep=<a:a@{<1.2.3 >=2.3.4}>" (func)))
+  "`1.2.3 >=2.3.4` is not a valid semver")
+
+(component
+  (import "locked-dep=<a:b>" (func))
+  (import "locked-dep=<a:b@1.2.3>" (func))
+  (import "locked-dep=<a:b>,integrity=<sha256-a>" (func))
+  (import "locked-dep=<a:b@1.2.3>,integrity=<sha256-a>" (func))
+)
+
+(assert_invalid
+  (component (import "locked-dep=" (func)))
+  "expected `<` at ``")
+(assert_invalid
+  (component (import "locked-dep=<" (func)))
+  "failed to find `:`")
+(assert_invalid
+  (component (import "locked-dep=<:" (func)))
+  "is not in kebab case")
+(assert_invalid
+  (component (import "locked-dep=<:>" (func)))
+  "is not in kebab case")
+(assert_invalid
+  (component (import "locked-dep=<a:>" (func)))
+  "is not in kebab case")
+(assert_invalid
+  (component (import "locked-dep=<:a>" (func)))
+  "is not in kebab case")
+(assert_invalid
+  (component (import "locked-dep=<a:a" (func)))
+  "failed to find `>`")
+(assert_invalid
+  (component (import "locked-dep=<a:a@>" (func)))
+  "is not a valid semver")
+(assert_invalid
+  (component (import "locked-dep=<a:a@1.2.3" (func)))
+  "failed to find `>`")
+(assert_invalid
+  (component (import "locked-dep=<a:a@1.2.3>," (func)))
+  "expected `integrity=<`")
+(assert_invalid
+  (component (import "locked-dep=<a:a@1.2.3>x" (func)))
+  "trailing characters found: `x`")
+
+(component
+  (import "url=<>" (func))
+  (import "url=<a>" (func))
+  (import "url=<a>,integrity=<sha256-a>" (func))
+)
+
+(assert_invalid
+  (component (import "url=" (func)))
+  "expected `<` at ``")
+(assert_invalid
+  (component (import "url=<" (func)))
+  "failed to find `>`")
+
+(component
+  (import "integrity=<sha256-a>" (func))
+  (import "integrity=<sha384-a>" (func))
+  (import "integrity=<sha512-a>" (func))
+  (import "integrity=<sha512-a sha256-b>" (func))
+  (import "integrity=< sha512-a sha256-b >" (func))
+  (import "integrity=<  sha512-a?abcd  >" (func))
+  (import "integrity=<sha256-abcdefghijklmnopqrstuvwxyz>" (func))
+  (import "integrity=<sha256-ABCDEFGHIJKLMNOPQRSTUVWXYZ>" (func))
+  (import "integrity=<sha256-++++++++++++++++++++==>" (func))
+  (import "integrity=<sha256-////////////////////==>" (func))
+)
+(assert_invalid
+  (component (import "integrity=<>" (func)))
+  "integrity hash cannot be empty")
+(assert_invalid
+  (component (import "integrity=<sha256>" (func)))
+  "expected `-` after hash algorithm")
+(assert_invalid
+  (component (import "integrity=<sha256->" (func)))
+  "not valid base64")
+(assert_invalid
+  (component (import "integrity=<sha256-^^^^>" (func)))
+  "not valid base64")
+(assert_invalid
+  (component (import "integrity=<sha256-=========>" (func)))
+  "not valid base64")
+(assert_invalid
+  (component (import "integrity=<sha256-=>" (func)))
+  "not valid base64")
+(assert_invalid
+  (component (import "integrity=<sha256-==>" (func)))
+  "not valid base64")
+(assert_invalid
+  (component (import "integrity=<md5-ABC>" (func)))
+  "unrecognized hash algorithm")
diff --git a/tests/local/component-model/instantiate.wast b/tests/local/component-model/instantiate.wast
index 15ea7ef3..9583d697 100644
--- a/tests/local/component-model/instantiate.wast
+++ b/tests/local/component-model/instantiate.wast
@@ -529,7 +529,7 @@
       (export "a" (component $c))
     )
   )
-  "instance export name `a` conflicts with previous name `a`")
+  "export name `a` conflicts with previous name `a`")
 
 (component
   (import "a" (instance $i))
diff --git a/tests/snapshots/local/component-model/export.wast/7.print b/tests/snapshots/local/component-model/export.wast/7.print
index 19402892..6c480d28 100644
--- a/tests/snapshots/local/component-model/export.wast/7.print
+++ b/tests/snapshots/local/component-model/export.wast/7.print
@@ -1,5 +1,5 @@
 (component
   (type (;0;) (func))
   (import "a" (func (;0;) (type 0)))
-  (export (;1;) (interface "wasi:http/types@2.0.0") (func 0))
+  (export (;1;) "wasi:http/types@2.0.0" (func 0))
 )
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/export.wast/8.print b/tests/snapshots/local/component-model/export.wast/8.print
index ce88c858..f798f758 100644
--- a/tests/snapshots/local/component-model/export.wast/8.print
+++ b/tests/snapshots/local/component-model/export.wast/8.print
@@ -1,5 +1,5 @@
 (component
   (type (;0;) (func))
-  (import (interface "wasi:http/types@2.0.0") (func (;0;) (type 0)))
-  (export (;1;) (interface "wasi:http/types@2.0.0") (func 0))
+  (import "wasi:http/types@2.0.0" (func (;0;) (type 0)))
+  (export (;1;) "wasi:http/types@2.0.0" (func 0))
 )
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/import.wast/14.print b/tests/snapshots/local/component-model/import.wast/14.print
index 95fa2297..3d06fbf2 100644
--- a/tests/snapshots/local/component-model/import.wast/14.print
+++ b/tests/snapshots/local/component-model/import.wast/14.print
@@ -1,22 +1,22 @@
 (component
   (type (;0;) (func))
-  (import (interface "wasi:http/types") (func (;0;) (type 0)))
+  (import "wasi:http/types" (func (;0;) (type 0)))
   (type (;1;) (func))
-  (import (interface "wasi:http/types@1.0.0") (func (;1;) (type 1)))
+  (import "wasi:http/types@1.0.0" (func (;1;) (type 1)))
   (type (;2;) (func))
-  (import (interface "wasi:http/types@2.0.0") (func (;2;) (type 2)))
+  (import "wasi:http/types@2.0.0" (func (;2;) (type 2)))
   (type (;3;) (func))
-  (import (interface "a-b:c-d/e-f@123456.7890.488") (func (;3;) (type 3)))
+  (import "a-b:c-d/e-f@123456.7890.488" (func (;3;) (type 3)))
   (type (;4;) (func))
-  (import (interface "a:b/c@1.2.3") (func (;4;) (type 4)))
+  (import "a:b/c@1.2.3" (func (;4;) (type 4)))
   (type (;5;) (func))
-  (import (interface "a:b/c@0.0.0") (func (;5;) (type 5)))
+  (import "a:b/c@0.0.0" (func (;5;) (type 5)))
   (type (;6;) (func))
-  (import (interface "a:b/c@0.0.0+abcd") (func (;6;) (type 6)))
+  (import "a:b/c@0.0.0+abcd" (func (;6;) (type 6)))
   (type (;7;) (func))
-  (import (interface "a:b/c@0.0.0+abcd-efg") (func (;7;) (type 7)))
+  (import "a:b/c@0.0.0+abcd-efg" (func (;7;) (type 7)))
   (type (;8;) (func))
-  (import (interface "a:b/c@0.0.0-abcd+efg") (func (;8;) (type 8)))
+  (import "a:b/c@0.0.0-abcd+efg" (func (;8;) (type 8)))
   (type (;9;) (func))
-  (import (interface "a:b/c@0.0.0-abcd.1.2+efg.4.ee.5") (func (;9;) (type 9)))
+  (import "a:b/c@0.0.0-abcd.1.2+efg.4.ee.5" (func (;9;) (type 9)))
 )
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/import.wast/32.print b/tests/snapshots/local/component-model/import.wast/32.print
new file mode 100644
index 00000000..186d7fb8
--- /dev/null
+++ b/tests/snapshots/local/component-model/import.wast/32.print
@@ -0,0 +1,5 @@
+(component
+  (type (;0;) (func))
+  (import "a" (func $a (;0;) (type 0)))
+  (export (;1;) "a" (func $a))
+)
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/import.wast/33.print b/tests/snapshots/local/component-model/import.wast/33.print
new file mode 100644
index 00000000..5aa1a8bf
--- /dev/null
+++ b/tests/snapshots/local/component-model/import.wast/33.print
@@ -0,0 +1,18 @@
+(component
+  (type (;0;) (func))
+  (import "unlocked-dep=<a:b>" (func (;0;) (type 0)))
+  (type (;1;) (func))
+  (import "unlocked-dep=<a:b@*>" (func (;1;) (type 1)))
+  (type (;2;) (func))
+  (import "unlocked-dep=<a:b@{>=1.2.3}>" (func (;2;) (type 2)))
+  (type (;3;) (func))
+  (import "unlocked-dep=<a:b@{>=1.2.3-rc}>" (func (;3;) (type 3)))
+  (type (;4;) (func))
+  (import "unlocked-dep=<a:b@{<1.2.3}>" (func (;4;) (type 4)))
+  (type (;5;) (func))
+  (import "unlocked-dep=<a:b@{<1.2.3-rc}>" (func (;5;) (type 5)))
+  (type (;6;) (func))
+  (import "unlocked-dep=<a:b@{>=1.2.3 <1.2.3}>" (func (;6;) (type 6)))
+  (type (;7;) (func))
+  (import "unlocked-dep=<a:b@{>=1.2.3-rc <1.2.3}>" (func (;7;) (type 7)))
+)
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/import.wast/44.print b/tests/snapshots/local/component-model/import.wast/44.print
new file mode 100644
index 00000000..de8d39be
--- /dev/null
+++ b/tests/snapshots/local/component-model/import.wast/44.print
@@ -0,0 +1,10 @@
+(component
+  (type (;0;) (func))
+  (import "locked-dep=<a:b>" (func (;0;) (type 0)))
+  (type (;1;) (func))
+  (import "locked-dep=<a:b@1.2.3>" (func (;1;) (type 1)))
+  (type (;2;) (func))
+  (import "locked-dep=<a:b>,integrity=<sha256-a>" (func (;2;) (type 2)))
+  (type (;3;) (func))
+  (import "locked-dep=<a:b@1.2.3>,integrity=<sha256-a>" (func (;3;) (type 3)))
+)
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/import.wast/56.print b/tests/snapshots/local/component-model/import.wast/56.print
new file mode 100644
index 00000000..e15ec7f5
--- /dev/null
+++ b/tests/snapshots/local/component-model/import.wast/56.print
@@ -0,0 +1,8 @@
+(component
+  (type (;0;) (func))
+  (import "url=<>" (func (;0;) (type 0)))
+  (type (;1;) (func))
+  (import "url=<a>" (func (;1;) (type 1)))
+  (type (;2;) (func))
+  (import "url=<a>,integrity=<sha256-a>" (func (;2;) (type 2)))
+)
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/import.wast/59.print b/tests/snapshots/local/component-model/import.wast/59.print
new file mode 100644
index 00000000..a812c45c
--- /dev/null
+++ b/tests/snapshots/local/component-model/import.wast/59.print
@@ -0,0 +1,22 @@
+(component
+  (type (;0;) (func))
+  (import "integrity=<sha256-a>" (func (;0;) (type 0)))
+  (type (;1;) (func))
+  (import "integrity=<sha384-a>" (func (;1;) (type 1)))
+  (type (;2;) (func))
+  (import "integrity=<sha512-a>" (func (;2;) (type 2)))
+  (type (;3;) (func))
+  (import "integrity=<sha512-a sha256-b>" (func (;3;) (type 3)))
+  (type (;4;) (func))
+  (import "integrity=< sha512-a sha256-b >" (func (;4;) (type 4)))
+  (type (;5;) (func))
+  (import "integrity=<  sha512-a?abcd  >" (func (;5;) (type 5)))
+  (type (;6;) (func))
+  (import "integrity=<sha256-abcdefghijklmnopqrstuvwxyz>" (func (;6;) (type 6)))
+  (type (;7;) (func))
+  (import "integrity=<sha256-ABCDEFGHIJKLMNOPQRSTUVWXYZ>" (func (;7;) (type 7)))
+  (type (;8;) (func))
+  (import "integrity=<sha256-++++++++++++++++++++==>" (func (;8;) (type 8)))
+  (type (;9;) (func))
+  (import "integrity=<sha256-////////////////////==>" (func (;9;) (type 9)))
+)
\ No newline at end of file
diff --git a/tests/snapshots/local/component-model/type-export-restrictions.wast/46.print b/tests/snapshots/local/component-model/type-export-restrictions.wast/46.print
index da10c90b..9387cbb1 100644
--- a/tests/snapshots/local/component-model/type-export-restrictions.wast/46.print
+++ b/tests/snapshots/local/component-model/type-export-restrictions.wast/46.print
@@ -7,7 +7,7 @@
       (export (;3;) "foo" (type (eq 2)))
     )
   )
-  (import (interface "demo:component/types") (instance (;0;) (type 0)))
+  (import "demo:component/types" (instance (;0;) (type 0)))
   (component (;0;)
     (type (;0;)
       (instance
@@ -17,7 +17,7 @@
         (export (;3;) "foo" (type (eq 2)))
       )
     )
-    (import (interface "demo:component/types") (instance (;0;) (type 0)))
+    (import "demo:component/types" (instance (;0;) (type 0)))
     (component (;0;)
       (type (;0;) (enum "qux"))
       (import "import-type-baz" (type (;1;) (eq 0)))
@@ -32,12 +32,12 @@
         (with "import-type-bar" (type 2))
       )
     )
-    (export (;2;) (interface "demo:component/types") (instance 1))
+    (export (;2;) "demo:component/types" (instance 1))
   )
   (instance (;1;) (instantiate 0
       (with "demo:component/types" (instance 0))
     )
   )
   (alias export 1 "demo:component/types" (instance (;2;)))
-  (export (;3;) (interface "demo:component/types") (instance 2))
+  (export (;3;) "demo:component/types" (instance 2))
 )
\ No newline at end of file