---
# System prepended metadata

title: Component Composition Text Interface

---

# Component Composition Text Interface

# Updates from 2023-06-01

* We changed the component import syntax from `component id` to `use kebab-name`, to better emphasise that the name is expected to be resolved rather than imported
* `new` was pushed into `expression`, and an alternate `expression` production case was added for aliasing paths
* Export syntax was reworked to no longer include an optional type, and instead now includes an optional `id` or `kabob-name` to use when exporting the path

## Grammar

```
               id ::= /* from component model pr */
       kabob-name ::= [a-z][a-zA-Z0-9-]*
     package-name ::= /* just the package subset of id */
             path ::= kabob-name { `[` (id | kabob-name) `]` } .

 compose-document ::= {import} {statement} {export} .
           import ::= `import` kabob-name `:` id .
 component-import ::= `use` package-name [`as` kabob-name] `;` .

        statement ::= `let` kabob-name `=` expression `;` .

       expression ::= `new` kabob-name [arguments]
                    | path .

        arguments ::= `{` argument {`,` argument} [`,`] `}` .
         argument ::= [kabob-name `=`] expression .

           export ::= `export` path [ `as` (id | kabob-name) ] `;` .
```

## Examples

### service.wit
```
default world endpoint {
    export handler: self.handler
}

world middleware {
    export incoming: self.handler
    import downstream: self.handler
}

interface handler {
    handle-request(req: request) -> result<response>
    ...
    record request { ...
    record response { ...
}
```

### Example 1

```
import downstream: service.handler;

use foo:middleware;

let service = new foo:middleware{
  downstream: foo[bar:baz/handler]
};

export service as incoming;
```

## Example 2

```
import downstream: service.handler;

use auth:middleware as auth;
use cors:middleware as cors;

let downstream = new cors{new auth{downstream}};

export downstream;
```

# Original

## Grammar
```
 compose-document ::= {import} {statement} {export} .
           import ::= instance-import | component-import .
  instance-import ::= `import` id `:` instance-ty `;` .
 component-import ::= `component` id [`:` component-ty] `;` .
        statement ::= `let` id `=` `new` expression `;` .
       expression ::= id [arguments] .
        arguments ::= `(` argument {`,` argument} [`,`] `)` .
         argument ::= id [`:` expression] .
           export ::= `export` expression [`as` instance-ty] `;` .
```

## Examples

### service.wit
```
default world endpoint {
    export handler: self.handler
}

world middleware {
    export incoming: self.handler
    import downstream: self.handler
}

interface handler {
    handle-request(req: request) -> result<response>
    ...
    record request { ...
    record response { ...
}
```

### Example 1
```
import downstream: service.handler;

// World derived from resolved concrete component
component middleware;

let service = new middleware[downstream];

export service as service.handler;
```

### Example 2
```
import downstream: service.handler;

component auth: service.middleware;
component cors: service.middleware;

let downstream = new auth[downstream];
let downstream = new cors[downstream];

export downstream as service.handler;
```