---
title: "The `.slint` File"
description: "The `.slint` File"
---
{/* cSpell: ignore otherlib */}

import CodeSnippetMD from '@slint/common-files/src/components/CodeSnippetMD.astro';
import Link from '@slint/common-files/src/components/Link.astro';
import LangRefLink from '@slint/common-files/src/components/LangRefLink.astro';
import { Tabs, TabItem } from '@astrojs/starlight/components';


You write user interfaces in the Slint language and saved in files with the `.slint` extension.

Each `.slint` file defines one or several components. These components declare
a tree of elements. Components form the basis of composition in Slint. Use them
to build your own re-usable set of UI controls. You can use each declared
component under its name as an element in another component.

Below is an example of components and elements:

```slint

component MyButton inherits Text {
    color: black;
    // ...
}

export component MyApp inherits Window {
    preferred-width: 200px;
    preferred-height: 100px;
    Rectangle {
        width: 200px;
        height: 100px;
        background: green;
    }
    MyButton {
        x:0;y:0;
        text: "hello";
    }
    MyButton {
        y:0;
        x: 50px;
        text: "world";
    }
}
```

Both `MyButton` and `MyApp` are components. `Window` and `Rectangle` are built-in elements
used by `MyApp`. `MyApp` also re-uses the `MyButton` component as two separate elements.

Elements have properties, which you can assign values to. The example above assigns a string
constant "hello" to the first `MyButton`'s `text` property. You
can also assign entire expressions. Slint re-evaluates the expressions when any
of the properties they depend on change, which makes the user-interface reactive.

You can name elements using the `:=` syntax:

```slint
component MyButton inherits Text {
    // ...
}

export component MyApp inherits Window {
    preferred-width: 200px;
    preferred-height: 100px;

    hello := MyButton {
        x:0;y:0;
        text: "hello";
    }
    world := MyButton {
        y:0;
        text: "world";
        x: 50px;
    }
}
```

:::note[Note]
Names have to be valid [identifiers](../../../../reference/language/lexical-structure/).
:::

Some elements are also accessible under pre-defined names:

-   `root` refers to the outermost element of a component.
-   `self` refers to the current element.
-   `parent` refers to the parent element of the current element.

These names are reserved and you can't re-define them.


## Comments

Comments are lines of code that are ignored by the Slint compiler. They are used to explain the code or
to temporarily disable code.

### Single Line Comments

Single line comments are denoted by `//` and are terminated by a new line.

```slint
// Amazing text! This is a comment
```

### Multi Line Comments

Multi line comments are denoted by `/*` and `*/`, and can span multiple lines.

```slint
/*
    This is a multi line comment.
    It can span multiple lines.
*/
```


## Elements and Components

The core part of the Slint language are elements and components. Technically they are the same thing
so once you know how to declare and use one you know the other. Elements are the basic building blocks
that are part of the Slint Language, while components (also know as widgets) are larger items that
are built up from multiple elements and properties.

If you have come from other languages such as HTML or React you might be used to opening and closing tags as well
as self closing tags.

```html
<!-- opening and closing tag -->
<Button>Hello World</Button>
 <!-- self closing tag -->
<img/>
```

Slint simply has a single way to declare an item the `element-name` followed by a set of curly braces `{}` that contain
the properties of the element.

```slint no-test del="Text {};"
// valid
Text {}

Text {
}
// Valid, but considered bad Slint practice
Text
{
}

// Not valid due to terminating semicolon
Text {};
```

:::note[Note]
The Slint tooling provides a code formatter that enforces what is considered good practice.

If you are new to coding then you can make friends with fellow developers by discussing aspects of
code formatting you don't like. It's a type of small talk developers love and appreciate.
:::




## The Root Element


```slint playground
component MyApp {
    Text {
        text: "Hello World";
        font-size: 24px;
    }
}
```

To be a valid Slint file the root element must be a component. Then inside the component you can declare
any number of elements. This is explained in more detail later, it's not important to understand at this point.

## Properties

Properties are the values that are assigned to an element. They are set using the `property-name: value;` syntax.


## Modules

Components declared in a `.slint` file can be used as elements in other `.slint` files,
by means of exporting and importing them.
By default, every type declared in a `.slint` file is private.
Export a component to make it available to other files, and import it where you need it:

```slint no-test
import { Button } from "./button.slint";

export component App inherits Rectangle {
    // ...
    Button {
        // ...
    }
}
```

Elements, globals and structs can be exported and imported as well.
For all the forms, including renaming and re-exports, see the
[Imports](../../../../reference/language/imports/) and [Exports](../../../../reference/language/exports/)
chapters of the language reference.

## Component Libraries

Splitting your code base into separate module files promotes re-use and
improves encapsulation by allow you to hide helper components. This works
well within a project's own directory structure. To share libraries of
components between projects without hardcoding their relative paths, use
the component library syntax:

```slint no-test
import { MySwitch } from "@mylibrary/switch.slint";
import { MyButton } from "@otherlibrary";
```

In the above example, the `MySwitch` component will be imported from a component
library called `mylibrary`, in which Slint looks for the `switch.slint` file. Therefore `mylibrary` must be
declared to refer to a directory, so that the subsequent search for `switch.slint`
succeeds. `MyButton` will be imported from `otherlibrary`. Therefore `otherlibrary`
must be declared to refer to a `.slint` file that exports `MyButton`.
A library provides images and fonts as well as components.
Reference them with the same prefix, as in `@image-url("@mylibrary/logo.png")`
or `import "@mylibrary/MyFont.ttf";`.

The path to each library, as file or directory, must be defined separately at compilation time.
Use one of the following methods to help the Slint compiler resolve libraries to the correct
path on disk:

<Tabs syncKey="dev-language">
<TabItem label="Rust" icon="seti:rust">
* In `build.rs`, call <LangRefLink lang="rust-slint-build" relpath="struct.CompilerConfiguration#method.with_library_paths">`with_library_paths`</LangRefLink>
  to provide a mapping from library name to path. For example:

```rust
// build.rs
fn main() {
    let manifest_dir = std::path::PathBuf::from(std::env::var_os("CARGO_MANIFEST_DIR").unwrap());
    let library_paths = std::collections::HashMap::from([(
        "example".to_string(),
        manifest_dir.join("third_party/example/ui/lib.slint"),
    )]);
    let config = slint_build::CompilerConfiguration::new().with_library_paths(library_paths);
    slint_build::compile_with_config("ui/main.slint", config).unwrap();
}
```

</TabItem>
<TabItem label="C++" icon="seti:cpp">
* Specify `LIBRARY_PATHS` with <LangRefLink lang="cpp" relpath="cmake-reference/slint-target-sources/">`slint_target_sources`</LangRefLink>. For example:

```cmake
slint_target_sources(my_application
    ui/main.slint
    LIBRARY_PATHS
        material=${CMAKE_CURRENT_SOURCE_DIR}/material-1.0/material.slint
)
```

</TabItem>
<TabItem label="NodeJS" icon="node">
* Provide the `libraryPaths` map with <LangRefLink lang="nodejs" relpath="api/functions/loadFile/">`loadFile`</LangRefLink> in `LoadFileOptions`. For example:

```javascript
let ui = slint.loadFile("/path/to/main.slint", {
    libraryPaths: {
        "material": "/path/to/material-1.0/material.slint"
    }
});
```

</TabItem>
<TabItem label="Python" icon="seti:python">
* Provide the `library_paths` dict with <LangRefLink lang="python" relpath="api/functions/load_file/">`load_file`</LangRefLink>. For example:

```python
ui = slint.load_file(
    "/path/to/main.slint",
    library_paths={
        "material": "/path/to/material-1.0/material.slint"
    },
)
```

</TabItem>
</Tabs>


* When invoking the `slint-viewer` from the command line, pass `-Lmylibrary=/path/to/my/library` for each component
  library.
* When using the VS Code extension, configure the Slint extension's library path
  using the `Slint: Library Paths` setting. Example below:
  ```json
  "slint.libraryPaths": {
      "mylibrary": "/path/to/my/library",
      "otherlibrary": "/path/to/otherlib/index.slint",
  },
  ```
  This can also be edited in the `.vscode/settings.json` file committed to your repository.
  Relative paths are resolved against the workspace root.
* With other editors, you can configure them to pass the `-L` argument to the `slint-lsp` just like for the slint-viewer.