Skip to main content
A Dart String is an immutable sequence of UTF-16 code units. It represents text data and provides a robust set of built-in properties and methods for string manipulation, supporting both standard character encoding and complex Unicode scalar values.

String Literals

Dart supports multiple literal formats to accommodate different formatting and escaping requirements. Strings can be defined using single or double quotes.
String singleQuote = 'A string literal';
String doubleQuote = "Another string literal";
Multiline Strings Triple quotes (either single or double) create multiline strings, preserving whitespace and line breaks exactly as authored in the source code.
String multiline = '''
This is a
multiline string
''';
Raw Strings Prefixing a string literal with r creates a raw string. Raw strings ignore escape sequences (like \n or \t), treating them as literal characters.
String rawString = r'This will print the \n literally.';

String Interpolation

Dart evaluates expressions embedded within string literals using the $ or ${} syntax. The language implicitly invokes the toString() method on the evaluated object. The curly braces can be omitted for simple identifiers.
int value = 42;
String simple = 'The value is $value';
String expression = 'The hex value is ${value.toRadixString(16)}';

Concatenation

Strings can be concatenated using the + operator. Additionally, Dart supports implicit concatenation of adjacent string literals, which is evaluated at compile time.
// Operator concatenation
String combined = 'Hello' + ' ' + 'World';

// Adjacent literal concatenation (compile-time)
String adjacent = 'Hello' ' ' 'World';

Immutability

Strings in Dart are strictly immutable. Once a String object is created in memory, its state cannot be altered. Any method that performs a transformation (e.g., substring, replaceAll, toLowerCase) allocates and returns a completely new String object.
String original = 'Dart';
// The following creates a new string; 'original' remains 'Dart'
String modified = original.toUpperCase(); 

Internal Representation: Code Units and Runes

Because Dart strings are UTF-16, characters within the Basic Multilingual Plane (BMP) are represented by a single 16-bit code unit. However, characters outside the BMP (such as emojis or specific mathematical symbols) require two code units, known as a surrogate pair. To safely iterate over or manipulate complex Unicode characters without splitting surrogate pairs, Dart provides the runes property, which exposes an iterable of UTF-32 code points.
String emoji = '🚀';

// Length in UTF-16 code units (Returns 2, due to surrogate pair)
int unitLength = emoji.length; 

// UTF-16 code units: [55357, 56960]
List<int> codeUnits = emoji.codeUnits; 

// Length in UTF-32 code points (Returns 1)
int runeLength = emoji.runes.length; 

// UTF-32 code points: (128640)
Iterable<int> runes = emoji.runes; 
Tired of Poor Dart Skills? Fix That With Deep Grasping!Learn More