Types
Slint is a statically typed language and offers a rich range of primitive types.
Primitive Types
Section titled “Primitive Types” bool default: false
boolean whose value can be either true or false.
string
Section titled “string” string default: ""
Any sequence of utf-8 encoded characters surrounded by quotes is a string: "foo".
export component Example inherits Text { text: "hello";}Escape sequences may be embedded into strings to insert characters that would be hard to insert otherwise:
| Escape | Result |
|---|---|
\" | " |
\\ | \ |
\n | new line |
\u{x} | where x is a hexadecimal number, expands to the unicode code point represented by this number |
\{expression} | the result of evaluating the expression |
Anything else following an unescaped \ is an error.
Strings have the following properties and member functions:
is-empty
Section titled “is-empty”true when the string doesn’t contain anything, false otherwise.
export component LengthOfString { property<bool> empty: "".is-empty; // true property<bool> not-empty: "hello".is-empty; // false}character-count
Section titled “character-count”The number of grapheme clusters ↗ in the string.
export component CharacterCountOfString { property<int> empty: "".character-count; // 0 property<int> hello: "hello".character-count; // 5 property<int> hiragana: "あいうえお".character-count; // 5 property<int> surrogate-pair: "😊𩸽".character-count; // 2 property<int> variation-selectors: "👍🏿".character-count; // 1 property<int> combining-character: "パ".character-count; // 1 property<int> zero-width-joiner: "👨👩👧👦".character-count; // 1 property<int> region-indicator-character: "🇦🇿🇿🇦".character-count; // 2 property<int> emoji-tag-sequences: "🏴".character-count; // 1}to-lowercase() -> string
Section titled “to-lowercase() -> string”Returns the string converted to lowercase, according to the Unicode Character Property ↗.
export component StringToLowercase { property<string> hello: "HELLO".to-lowercase(); // "hello" property<string> odysseus: "ὈΔΥΣΣΕΎΣ".to-lowercase(); // "ὀδυσσεύς"}to-uppercase() -> string
Section titled “to-uppercase() -> string”Returns the string converted to uppercase, according to the Unicode Character Property ↗.
export component StringToUppercase { property<string> bye: "tschüß".to-uppercase(); // "TSCHÜSS" property<string> new-year: "农历新年".to-uppercase(); // "农历新年"}to-float() -> float
Section titled “to-float() -> float”Returns the number contained in the string, or 0 if the string isn’t a valid number.
Use is-float() to tell a string holding the number 0 apart from a string that isn’t a valid number.
The string is parsed using the decimal separator of the current locale. See Converting Between Numbers and Strings.
is-float() -> bool
Section titled “is-float() -> bool”Returns true if the string contains a valid number, false otherwise.
Like to-float(), it uses the decimal separator of the current locale.
export component StringToFloat { property<float> hello: "hello".to-float(); // 0 property<bool> goodbye: "goodbye".is-float(); // false property<float> value: "1.5".to-float(); // 1.5 if the decimal separator is "."}styled-text
Section titled “styled-text” styled-text default: ""
A property that is used with the StyledText element.
Create styled text with the @markdown() macro. For example: @markdown("Hello **Bold**").
@markdown() supports interpolation: For example, @markdown("5 + 5 = *\{ 5 + 5 }*") becomes "5 + 5 = *10*".
Any text passed as an argument to the macro will be escaped, for example @markdown("Hello \{"*World*"}") will become "Hello \*World\*".
If multiple string literal are used, they are concatenated.
Use <font color='...'> to apply colors.
Literal color names and hex values work directly: @markdown("<font color='red'>warning</font>").
To interpolate a dynamic color, the expression must be of type color:
@markdown("<font color='\{self.my-color}'>colored</font>").
Interpolation inside HTML tags is only allowed in the color attribute value.
Numeric Types
Section titled “Numeric Types” angle default: 0deg
Angle measurement, corresponds to a literal like 90deg, 1.2rad, 0 25turn
duration
Section titled “duration” duration default: 0ms
Type for the duration of animations. A suffix like ms (millisecond) or s (second) is used to indicate the precision.
float default: 0
Signed, 32-bit floating point number. Numbers with a % suffix are automatically divided by 100, so for example 30% is the same as 0.30.
float and int values have the following member functions:
to-fixed(digits: int) -> string
Section titled “to-fixed(digits: int) -> string”Returns a string representation of the number with digits digits after the decimal point.
It behaves like JavaScript’s toFixed() ↗.
to-precision(digits: int) -> string
Section titled “to-precision(digits: int) -> string”Returns a string representation of the number with digits significant digits.
It behaves like JavaScript’s toPrecision() ↗.
Both functions format the number using the decimal separator of the current locale. See Converting Between Numbers and Strings.
export component FloatToString { property<float> pi: 3.14159; property<string> fixed: pi.to-fixed(2); // "3.14" property<string> precision: pi.to-precision(4); // "3.142"}In addition, call the math functions in postfix style on any numeric value,
for example (-10).abs() or x.round().
to-string-unlocalized() -> string
Section titled “to-string-unlocalized() -> string”Returns a string representation of the number but not localized. This means the decimal separator will always be a dot.
int default: 0
Signed integral number.
length
Section titled “length” length default: 0px
The type used for x, y, width and height coordinates. Corresponds to a literal like 1px, 1pt, 1in, 1mm, or 1cm. It can be converted to and from length provided the binding is run in a context where there is an access to the device pixel ratio.
percent
Section titled “percent” percent default: 0%
Signed, 32-bit floating point number that is interpreted as percentage. Literal number assigned to properties of this type must have a % suffix.
physical-length
Section titled “physical-length” physical-length default: 0phx
This is an amount of physical pixels. To convert from an integer to a length unit, one can simply multiply by 1px. Or to convert from a length to a float, one can divide by 1phx.
relative-font-size
Section titled “relative-font-size” relative-font-size default: 0rem
Relative font size factor that is multiplied with the Window.default-font-size and can be converted to a length.
Please see the language specific API references how these types are mapped to the APIs of the different programming languages.
Color and Brush Types
Section titled “Color and Brush Types” brush default: transparent
A brush is a special type that can be either initialized from a color or a gradient. See Colors & Brushes.
color default: transparent
RGB color with an alpha channel, with 8 bit precision for each channel. CSS color names as well as the hexadecimal color encodings are supported, such as #RRGGBBAA or #RGB. See Colors & Brushes.
Keyboard input
Section titled “Keyboard input” keys default: empty keys
A keys represents a key combined with a list of modifiers. This is the primitive type used to detect if a KeyEvent should trigger a given key binding.
Key bindings in Slint are based on logical keys — the character a key produces on the current keyboard layout — not the physical position of a key on the keyboard. See Key Bindings for details.
keys values have the following member function:
to-string() -> string
Section titled “to-string() -> string”Returns a platform-native description of the key combination.
export component KeysToString inherits FocusScope { undo := KeyBinding { keys: @keys(Control + Z); activated => { debug("UNDO") } }
Text { text: "Press \{undo.keys.to-string()} to undo!"; // Results in "Press ⌘Z to undo!" on macOS // Results in "Press Ctrl+Z to undo!" on other platforms }}Images
Section titled “Images” image default: empty image
The image type is a reference to an image.
In Slint, an image can be loaded from a file with the @image-url("...") construct.
The address within the @image-url function must be a string literal and the image is resolved at compile time.
Slint looks for images in the following places:
- The absolute path or the path relative to the current
.slintfile. - The include path used by the compiler to look up
.slintfiles.
Loading image from http is only supported in SlintPad ↗.
Images can also be loaded from data: URIs ↗, with either base64 or URL-encoded content.
For example: @image-url("data:image/png;base64,iVBORw0KGgo...").
Supported format are SVG, and formats supported by the image crate ↗:
AVIF, BMP, DDS, Farbfeld, GIF, HDR, ICO, JPEG, EXR, PNG, PNM, QOI, TGA, TIFF, WebP.
In C++, properties or struct fields of the image type are mapped to slint::Image.
In Rust, properties or struct fields of the image type are mapped to slint::Image.
In JavaScript properties or struct fields of the image type are mapped an object that implement the ImageData interface.
In Python, properties or struct fields of the image type are mapped to Image.
It is also possible to load images supporting 9 slice scaling ↗ (also called nine patch or border images)
by adding a nine-slice(...) argument. The argument can have either one, two, or four numbers that specifies the size of the edges.
The numbers are either top right bottom left or vertical horizontal, or one number for everything
// nine-slice scalingexport component Example inherits Window { width: 100px; height: 150px; VerticalLayout { Image { source: @image-url("https://interactive-examples.mdn.mozilla.net/media/examples/border-diamonds.png", nine-slice(30 30 30 30)); } }}See also the Image element.
Images have the following properties:
The width of the image in pixels, as an int. An empty image has a width of 0.
height
Section titled “height”The height of the image in pixels, as an int. An empty image has a height of 0.
export component Example inherits Window { preferred-width: 150px; preferred-height: 50px;
// Note: http URL only work on the web version. in property <image> some_image: @image-url("https://slint.dev/logo/slint-logo-full-light.svg");
HorizontalLayout { Text { text: "The image is " + some_image.width + "x" + some_image.height; }
// Check the size to find out if the image is empty. if some_image.width > 0 : Image { source: some_image; } }}data-transfer
Section titled “data-transfer” data-transfer default: an empty data-transfer
A data-transfer value is the payload carried by drag-and-drop and clipboard operations.
It abstracts over the file-type transfer mechanisms supported by each platform.
The type is opaque in Slint code:
construct a data-transfer value and read its content via callbacks implemented in the host language.
See DragAndDrop for an end-to-end example.
Animation
Section titled “Animation”easing
Section titled “easing” easing default: linear
The easing type allows defining an easing curve for animations.
To specify an easing curve, use the values from the Easing namespace. For example you can use Easing.ease-out or Easing.ease-in-quad. The namespace consists of the following names (see easings.net ↗ for a visual reference):
linearease-in-quadease-out-quadease-in-out-quadeaseease-inease-outease-in-outease-in-quartease-out-quartease-in-out-quartease-in-quintease-out-quintease-in-out-quintease-in-expoease-out-expoease-in-out-expoease-in-sineease-out-sineease-in-out-sineease-in-backease-out-backease-in-out-backease-in-circease-out-circease-in-out-circease-in-elasticease-out-elasticease-in-out-elasticease-in-bounceease-out-bounceease-in-out-bouncecubic-bezier(a, b, c, d)as in CSS
Additionally, in expressions of type easing, those names are available directly.
struct AnimationData { curve: easing,}
component Custom inherits Rectangle { property<AnimationData> animation: { // Using the Easing namespace. curve: Easing.ease-in-circ, };
animate x { // In easing expressions the names are available via global scope. easing: ease-out-bounce; }}Type Conversions
Section titled “Type Conversions”Slint supports conversions between different types. Explicit conversions are required to make the UI description more robust, but implicit conversions are allowed between some types for convenience.
The following conversions are possible:
intcan be converted implicitly tofloatand vice-versa. When converting fromfloattoint, the value is truncated.intandfloatcan be converted implicitly tostring, andstringcan be converted tofloatwith theto-float()member function. See Converting Between Numbers and Strings.physical-length,relative-font-size, andlengthcan be converted implicitly to each other only in context where the pixel ratio is known.- the units type (
length,physical-length,duration, …) can’t be converted to numbers (floatorint) but they can be divided by themselves to result in a number. Similarly, a number can be multiplied by one of these unit. The idea is that one would multiply by1pxor divide by1pxto do such conversions - The literal
0can be converted to any of these types that have associated unit. - Struct types convert with another struct type if they have the same property names and their types can be converted. The source struct can have either missing properties, or extra properties. But not both.
- Arrays generally don’t convert between each other. Array literals can be converted if the element types are convertible.
export component Example { // OK: int converts to string property<{a: string, b: int}> prop1: {a: 12, b: 12 }; // OK: even if a is missing, it will just have the default value ("") property<{a: string, b: int}> prop2: { b: 12 }; // OK: even if c is too many, it will be discarded property<{a: string, b: int}> prop3: { a: "x", b: 12, c: 42 }; // ERROR: b is missing and c is extra, this doesn't compile, because it could be a typo. // property<{a: string, b: int}> prop4: { a: "x", c: 42 };
property<string> xxx: "42.1"; property<float> xxx1: xxx.to-float(); // 42.1 property<bool> xxx2: xxx.is-float(); // true property<int> xxx3: 45.8; // 45}Converting Between Numbers and Strings
Section titled “Converting Between Numbers and Strings”int and float convert implicitly to string.
To control how many digits appear in the result, use the to-fixed() and to-precision()
member functions instead of the implicit conversion.
For the other direction, convert a string to a number with the to-float() member function,
and check whether a string holds a valid number with is-float().
All these conversions use the decimal separator of the current locale,
which is exposed as Platform.decimal-separator and defaults to the dot (.).
For example, in a German locale the decimal separator is the comma (,):
- The
floatvalue1.5converts to the string"1,5". "1,5".to-float()returns1.5."1.5".is-float()returnsfalseand"1.5".to-float()returns0: only the locale’s decimal separator is recognized when parsing.
Number literals in .slint files always use the dot, regardless of the locale.
See the translations guide for how the decimal separator is determined.
© 2026 SixtyFPS GmbH