Swift Variables (var) and Constants (let) Explained

Swift uses variables and constants to store values in your program. This topic is one of the first things every Swift developer learns, because almost every piece of code depends on naming data, reading it later, and deciding whether that value should be allowed to change. In this article, you will learn what var and let mean, how to declare them, when to use each one, and how to avoid the most common beginner mistakes.

Quick answer: In Swift, use var to create a variable whose value can change, and use let to create a constant whose value cannot be reassigned after it is set. In most cases, prefer let by default and switch to var only when you truly need mutability.

Difficulty: Beginner

Helpful to know first: You will understand this better if you already know basic Swift syntax, how to print values, and simple types such as String, Int, and Bool.

1. What Is Variables (var) & Constants (let)?

A variable or constant gives a name to a value so your program can use it later. Instead of writing the same literal value everywhere, you store it once and refer to it by name.

  • var creates a stored value that can be changed later.
  • let creates a stored value that cannot be reassigned after initialization.
  • Both help make code more readable by replacing raw values with meaningful names.
  • Swift encourages safe code, so constants are preferred whenever possible.
  • The main comparison is simple: let means immutable binding, while var means mutable binding.

For example, a user's name usually stays the same during a short function, so it can often be declared with let. A score in a game changes over time, so it should usually be declared with var.

2. Why Variables (var) & Constants (let) Matters

Choosing between var and let affects correctness, readability, and safety.

When you use let, Swift protects that value from accidental reassignment. This reduces bugs, especially in longer functions where values pass through several steps. A constant also communicates intent to other developers: this value is meant to stay fixed.

When you use var, you allow a value to evolve. This is useful for counters, user input, temporary state, and calculations that happen in stages.

In real projects, using the right one matters because:

  • It prevents unintended changes to important values.
  • It makes code easier to reason about during debugging.
  • It helps the compiler enforce safer patterns.
  • It signals whether a value is part of changing state or fixed configuration.

A helpful rule is: if you are not sure whether a value should change, start with let. If Swift later shows that reassignment is necessary, change it to var.

3. Basic Syntax

The syntax for declaring a variable or constant is simple. You write the keyword, then a name, then optionally a type annotation, and then a value.

Declaring a constant with let

Use let when the value should stay the same after it is assigned.

Swift
let siteName = "DevDocs10"
print(siteName)
Output✓ Tested · Swift 6.4
DevDocs10

This creates a constant named siteName. Swift infers that its type is String from the assigned value.

Declaring a variable with var

Use var when the value needs to change.

Swift
var score = 0
score = 10
print(score)
Output✓ Tested · Swift 6.4
10

This works because score was declared as a variable, so Swift allows reassignment.

Adding an explicit type

You can also write the type yourself. This is useful when clarity matters or when the initial value does not make the intended type obvious.

Swift
let maxUsers: Int = 100
var temperature: Double = 21.5

Here, the type annotation comes after the name and before the value.

Declaring first and assigning later

Swift also allows declaration without an immediate value if the type is known and the value will be set before use.

Swift
var username: String
username = "Taylor"
print(username)
Output✓ Tested · Swift 6.4
Taylor

This is valid because the variable has a type and gets a value before it is read.

4. Step-by-Step Examples

Example 1: Storing a fixed app name

An app name usually does not change while the program runs, so a constant is a good fit.

Swift
let appName = "WeatherNow"
print("App: \(appName)")
Output✓ Tested · Swift 6.4
App: WeatherNow

This example shows a constant used for configuration-style data that should remain unchanged.

Example 2: Updating a counter

Counters change over time, so they should be variables.

Swift
var pageViews = 0
pageViews += 1
pageViews += 1
print(pageViews)
Output✓ Tested · Swift 6.4
2

The value starts at 0 and changes as visits are counted.

Example 3: Using type annotations for clarity

Sometimes adding the type makes your intent clearer to the reader.

Swift
let pi: Double = 3.14159
var cartItems: Int = 2
print(pi)
print(cartItems)
Output✓ Tested · Swift 6.4
3.14159
2

This is especially useful in tutorial code, APIs, and places where inferred types may be less obvious.

Example 4: Declaring a value and assigning it later

You may know the type before you know the exact value.

Swift
var message: String

message = "Welcome back!"
print(message)
Output✓ Tested · Swift 6.4
Welcome back!

This is common when a value depends on later logic, user input, or a function result.

5. Practical Use Cases

  • Use let for fixed configuration values such as app names, API base URLs, and tax rates that should not be reassigned.
  • Use var for counters, scores, totals, and values that are updated inside loops.
  • Use let for function-local values that are calculated once and then reused.
  • Use var for form input, current selections, or state that changes in response to user actions.
  • Use let to make important values safer when passing them through multiple lines of logic.
  • Use var when building a value step by step, such as accumulating a total price or building a status message.

6. Common Mistakes

Mistake 1: Trying to reassign a constant

A constant declared with let can only be assigned once. After that, Swift does not allow a new value.

Problem: This code tries to change a constant after initialization, so Swift reports an error such as Cannot assign to value: 'name' is a 'let' constant.

Swift
let name = "Ana"
name = "Mila"
Compiler output✓ Tested · Swift 6.4
error: cannot assign to value: 'name' is a 'let' constant

Fix: Use var only if the value is meant to change.

Swift
var name = "Ana"
name = "Mila"

The corrected version works because var allows reassignment.

Mistake 2: Declaring without enough type information

Swift needs to know the type of a variable or constant. If you do not provide a value or a type annotation, Swift cannot infer what the storage should hold.

Problem: This declaration does not include a value or a type, so Swift cannot infer the intended type and reports an error.

Swift
var total
Compiler output✓ Tested · Swift 6.4
error: type annotation missing in pattern

Fix: Either assign an initial value or provide an explicit type annotation.

Swift
var total = 0
var price: Double

The corrected version works because Swift now knows what type each variable should store.

Mistake 3: Reading a variable before assigning a value

If you declare a variable with a type but no initial value, you must assign something before using it.

Problem: This code attempts to read greeting before it has been initialized, which causes a compile-time error.

Swift
var greeting: String
print(greeting)
Compiler output✓ Tested · Swift 6.4
error: variable 'greeting' used before being initialized

Fix: Assign a value before the first read.

Swift
var greeting: String
greeting = "Hello"
print(greeting)
Output✓ Tested · Swift 6.4
Hello

The corrected version works because the variable is initialized before it is used.

Mistake 4: Using var when let communicates intent better

Not every value that could be mutable should be mutable. Overusing var makes code harder to reason about.

Problem: This code marks a fixed value as mutable, which can lead to accidental reassignment later and makes the code less clear.

Swift
var countryCode = "US"
print(countryCode)
Output✓ Tested · Swift 6.4
US

Fix: Use let when the value should stay constant.

Swift
let countryCode = "US"
print(countryCode)
Output✓ Tested · Swift 6.4
US

The corrected version communicates more clearly that the value is fixed.

7. Best Practices

Practice 1: Default to let

A common Swift style is to start with let and change to var only when needed. This makes your intent safer and clearer.

Less preferred:

Swift
var username = "Casey"

Preferred:

Swift
let username = "Casey"

This practice reduces accidental changes and better documents your code.

Practice 2: Choose descriptive names

The name of a variable or constant should tell the reader what the value means, not just that a value exists.

Less preferred:

Swift
let x = 30

Preferred:

Swift
let maxLoginAttempts = 30

Descriptive names make maintenance easier and reduce the need for extra comments.

Practice 3: Add explicit types when they improve clarity

Swift type inference is powerful, but an explicit type can make code easier to read in APIs, shared code, or educational examples.

Less preferred when the intended type is not obvious:

Swift
let timeout = 5

Preferred when you want to show intent clearly:

Swift
let timeoutSeconds: Double = 5.0

This helps other developers understand the expected kind of value immediately.

8. Limitations and Edge Cases

  • A let constant cannot be reassigned, but that does not mean every nested piece of data is always deeply immutable in every scenario. The exact behavior depends on the type and whether it exposes mutable internal state.
  • Swift must know a variable's type either from the assigned value or from an explicit annotation. A declaration with neither will fail to compile.
  • A variable declared without an initial value cannot be used until it has been initialized.
  • Type inference is convenient, but sometimes integer and floating-point values can behave differently than beginners expect. For example, 5 is inferred as Int, while 5.0 is inferred as Double.
  • If you see a message like Cannot assign to value: 'x' is a 'let' constant, the problem is reassignment, not the original declaration syntax.
  • If a value truly needs to change across steps of a calculation, forcing it into let will make the code awkward. In those cases, var is the correct choice.

9. Practical Mini Project

Let’s build a small checkout summary that uses both constants and variables. Constants hold fixed values such as product name and shipping fee. Variables hold values that change, such as quantity and total cost.

Swift
let productName = "Notebook"
let unitPrice: Double = 4.50
let shippingFee: Double = 2.00

var quantity = 2
var subtotal = Double(quantity) * unitPrice
var total = subtotal + shippingFee

print("Product: \(productName)")
print("Quantity: \(quantity)")
print("Subtotal: \(subtotal)")
print("Total: \(total)")

// Customer adds one more notebook
quantity = 3
subtotal = Double(quantity) * unitPrice
total = subtotal + shippingFee

print("Updated quantity: \(quantity)")
print("Updated total: \(total)")
Output✓ Tested · Swift 6.4
Product: Notebook
Quantity: 2
Subtotal: 9.0
Total: 11.0
Updated quantity: 3
Updated total: 15.5

This example shows a realistic pattern: fixed values are constants, while values that react to user behavior are variables. That makes the code easier to read and safer to maintain.

10. Key Points

  • var creates a value that can be reassigned later.
  • let creates a value that cannot be reassigned after initialization.
  • Prefer let by default and switch to var only when change is required.
  • Swift can often infer types, but explicit annotations are useful when they improve clarity.
  • A variable declared without an initial value must be assigned before it is read.
  • The error Cannot assign to value: is a 'let' constant means you tried to change a constant.

11. Practice Exercise

Create a small program for tracking a user's reading progress.

  • Declare a constant for the book title.
  • Declare a constant for the total number of pages.
  • Declare a variable for the current page and set it to an initial value.
  • Update the current page after the user reads more pages.
  • Print the book title, total pages, current page, and remaining pages.

Expected output: The program should show fixed book information and an updated reading position after the page value changes.

Hint: Use let for values that do not change and var for the page number that updates.

Show solution
Swift
let bookTitle = "Swift Basics"
let totalPages = 250

var currentPage = 40
print("Book: \(bookTitle)")
print("Total pages: \(totalPages)")
print("Current page: \(currentPage)")
print("Remaining pages: \(totalPages - currentPage)")

currentPage = 85
print("Updated current page: \(currentPage)")
print("Updated remaining pages: \(totalPages - currentPage)")
Output✓ Tested · Swift 6.4
Book: Swift Basics
Total pages: 250
Current page: 40
Remaining pages: 210
Updated current page: 85
Updated remaining pages: 165

Check Your Understanding

Pick an answer for each question, then check your score.

1. Which keyword declares a value that can't be reassigned?
Show answer

Answer: let. let creates a constant. (const is JavaScript, not Swift.)

2. What's the recommended default?
Show answer

Answer: let, switching to var only when the value must change. Using let by default makes code safer and easier to follow.

3. What happens with let score = 10 followed by score = 20?
Show answer

Answer: A compile error: cannot assign to value, score is a let constant. Swift catches the reassignment at compile time.

4. What type does Swift infer for let pi = 3.14?
Show answer

Answer: Double. Floating-point literals default to Double unless you annotate another type.

12. Final Summary

Variables and constants are foundational in Swift because they control how your program stores and manages data. The key distinction is simple: use let for values that should not change, and use var for values that must change over time. That one decision improves safety, readability, and correctness throughout your code.

In this article, you learned the core syntax, saw how type inference and type annotations work, explored practical examples, fixed common errors, and applied the concept in a small mini project. If you want to continue building your Swift basics, a strong next step is learning Swift data types such as String, Int, Double, and Bool, because variables and constants become much more useful once you understand the kinds of values they can store.