---
# System prepended metadata

title: Marko Linter

---

# Marko Linter

## Probable Errors


### Implicit change handler in rest attributes

Bad:

```htmlembedded=
<attrs/{ foo, ...others }/>
<input #value:=foo>
```

Good:

```htmlembedded=
<attrs/{ foo, fooChange, ...others }/>
<input #value:=foo>
```

### Defining the same attribute twice

Bad:

```htmlembedded=
<let/x=1 value=2/>
<my-tag foo=defaultFoo ...others foo=overrideFoo/>
```

### Dynamic tag string that refers to marko tag

Bad:

```htmlembedded=
// when `@ebay/ebayui-core` is installed
<${input.condition ? "ebay-button" : "ebay-menu-button"}/>
```

Good:

```htmlembedded=
import EbayButton from "<ebay-button>";
import EbayMenuButton from "<ebay-menu-button>";
<${input.condition ? EbayButton : EbayMenuButton}/>
```

```htmlembedded=
<${input.condition ? "button" : "a"}/>
```

```htmlembedded=
// strings can refer to web components
// more specifically, as long as they don't resolve
// to a marko component
<${input.condition ? "paper-button" : "paper-menu-button"}/>
```
_could also create a tag lookup in dev mode to give runtime warnings when static analysis isn't possible_

## Performance

### Async value passed to async attribute

Bad:
```htmlembedded=
<AsyncComponent foo=await barAsync/>
```

Good:
```htmlembedded=
<SyncComponent foo=await barAsync/>
<AsyncComponent foo=barSync/>
```


## Opinions/Style

### Default attribute with named attributes

Bad:
```htmlembedded=
<attrs/{ default: foo, other }/>
```

Good:
```htmlembedded=
<attrs/{ default: foo }/>
```

### Use control directives

Bad:
```htmlembedded=
<input value=""/>
<input type="checkbox" checked/>
```

Good:
```htmlembedded=
<input #value=""/>
<input type="checkbox" #checkedValue=.../>
```

### Avoid shadowing Marko custom tags

Bad:
```htmlembedded=
<const/Foo = "div"/> 
<Foo/> // if there already exists a custom <Foo> tag
```

Bad:
```
app/
├─ node_modules/
│  ├─ FooTaglib/
│  │  ├─ components/
│  │  │  ├─ Foo.marko
├─ components/
│  ├─ Foo.marko
```
