Mojo is a modern programming language that combines Python-like readability with static typing, memory safety, systems programming features, and high-performance computing capabilities.
For beginners, one of Mojo’s biggest advantages is that much of its basic syntax looks familiar, especially if you already know Python.
For example, a simple Mojo program looks like this:
def main():
print("Hello, Mojo!")
Mojo uses indentation, functions, conditions, loops, variables, structs, imports, and many other concepts that should feel approachable to developers coming from Python.
However, Mojo is not simply Python with a different compiler.
It also introduces features such as:
- Static typing
- Ownership and references
- Compile-time parameters
- Traits
- Structs
- Memory-safe systems programming
- CPU and GPU programming
The current Mojo 1.0 language reference defines syntax for identifiers, literals, operators, expressions, statements, functions, structs, traits, closures, decorators, and compile-time features.
This guide explains the most important Mojo syntax a beginner should understand.
Basic Structure of a Mojo Program
A basic executable Mojo program contains a main() function:
def main():
print("Hello, World!")
The program starts execution from:
main()
The basic structure is:
Program Starts
↓
main()
↓
Statements Execute
↓
Program Ends
Mojo’s official beginner documentation uses def main(): as the standard entry point for executable programs.
Mojo Uses Indentation
Mojo uses indentation to define code blocks.
Correct:
def main():
print("Hello")
Incorrect:
def main():
print("Hello")
The body of the function must be indented.
This also applies to:
- Conditions
- Loops
- Functions
- Struct methods
- Error handling
For example:
def main():
var age = 20
if age >= 18:
print("Adult")
The print() statement belongs to the if block because it is indented.
Comments in Mojo
Single-line comments begin with:
#
Example:
# This is a Mojo comment
def main():
print("Hello")
Comments can also appear after code:
var age = 25 # User age
Mojo ignores comments when compiling the program.
Mojo Docstrings
Mojo also supports documentation strings using triple quotes.
Example:
def greet(name: String):
"""Print a greeting for the supplied name."""
print("Hello,", name)
Docstrings are useful for documenting functions and APIs.
They are different from normal # comments and can be used by documentation tooling.
Variables in Mojo
Use the var keyword to declare a mutable variable.
Example:
def main():
var age = 25
print(age)
Output:
25
Another example:
var score = 100
Here:
vardeclares the variablescoreis the variable name100is the initial value
Mojo variables are statically typed. If you do not explicitly specify a type, Mojo infers it from the initial value.
Explicit Variable Types
You can write the type explicitly:
var age: Int = 25
Here:
age
is the variable name, while:
Int
is the type.
Another example:
var name: String = "Alex"
Declare a Variable Before Assigning a Value
Mojo also allows variables to be declared before assigning their value.
Example:
def main():
var total: Int
total = 100
print(total)
This can be useful when the value is assigned later in the program.
Static Typing
Mojo uses static typing.
For example:
var number = 10
Mojo infers an integer type.
You cannot later simply change the same variable into a string:
var number = 10
number = "Hello"
This causes a type error because Mojo fixes the variable’s type at compile time.
Mojo Identifiers
Identifiers are names used for things such as:
- Variables
- Functions
- Structs
- Parameters
Examples:
var score = 100
def calculate_total():
pass
struct Player:
pass
Here:
score
calculate_total
Player
are identifiers.
Regular Mojo identifiers begin with a letter or underscore and can then contain letters, numbers, and underscores.
Examples of normal identifiers:
score
player_name
total2
_private_value
Mojo Naming Examples
Common naming styles might include:
var player_score = 100
var total_health = 75
Function names:
def calculate_score():
pass
Struct names commonly use a capitalized style:
struct Player:
pass
Mojo Keywords
Mojo has reserved keywords that have special meanings.
Important examples include:
def
var
ref
struct
trait
if
else
elif
for
while
return
break
continue
raise
try
except
import
from
as
pass
You should not normally use reserved keywords as ordinary variable names.
The language reference defines Mojo’s identifiers, reserved keywords, and argument conventions such as var, ref, mut, and out.
The def Keyword
Functions are currently declared with:
def
Example:
def greet():
print("Hello")
Important: older Mojo code may use:
fn
However, fn is deprecated. Current Mojo uses def as the standard function declaration keyword.
So prefer:
def add():
pass
instead of older examples using fn.
Functions in Mojo
A basic function looks like:
def greet():
print("Hello")
Call it with:
greet()
Complete example:
def greet():
print("Hello")
def main():
greet()
Output:
Hello
Every function declaration in current Mojo begins with def.
Function Arguments
Functions can accept arguments.
Example:
def greet(name: String):
print("Hello,", name)
def main():
greet("Alex")
Here:
name: String
defines an argument named name with the type String.
Multiple Function Arguments
Example:
def add(a: Int, b: Int):
print(a + b)
def main():
add(10, 20)
Output:
30
Arguments are separated by commas.
Function Return Types
Use:
->
to specify a return type.
Example:
def add(a: Int, b: Int) -> Int:
return a + b
The complete syntax is:
def function_name(arguments) -> ReturnType:
function_body
The official Mojo function reference uses this same declaration form.
The return Statement
The return keyword sends a value back from a function.
Example:
def square(number: Int) -> Int:
return number * number
Then:
def main():
var result = square(5)
print(result)
Output:
25
Functions Without a Return Value
A function does not need to return a value.
Example:
def show_message():
print("Welcome to Mojo")
There is no:
-> Type
because the function only performs an action.
The pass Statement
Sometimes you want to create an empty function or block temporarily.
Use:
pass
Example:
def future_feature():
pass
This provides a valid function body without implementing anything yet.
Strings in Mojo
Strings represent text.
Example:
var name: String = "Alex"
Another example:
var message = "Learning Mojo"
Print a string:
print(message)
String Concatenation
You can combine strings:
def main():
var first = "Hello, "
var second = "Mojo!"
print(first + second)
Output:
Hello, Mojo!
Adjacent String Literals
Mojo can combine adjacent string literals.
For example, conceptually:
var message = "Hello, " "Mojo!"
The resulting value is one combined string.
This behavior is documented in Mojo’s language basics.
Integer Values
Integers represent whole numbers.
Example:
var age: Int = 25
var score: Int = 100
You can perform arithmetic:
var total = 10 + 20
Floating-Point Values
Floating-point numbers represent decimal values.
Example:
var price = 10.5
Mojo provides multiple numeric types and lower-level representations for performance-oriented programming. The language reference includes dedicated numeric type documentation.
Boolean Values
Boolean values represent:
True
False
Example:
var is_active = True
You can use booleans inside conditions:
if is_active:
print("Active")
Arithmetic Operators
Common arithmetic operators include:
+ Addition
- Subtraction
* Multiplication
/ Division
% Remainder
Example:
def main():
var a = 10
var b = 3
print(a + b)
print(a - b)
print(a * b)
print(a % b)
Assignment Operators
Basic assignment uses:
=
Example:
var score = 10
You can also update values with compound assignment operators such as:
+=
-=
*=
Example:
var score = 10
score += 5
print(score)
Result:
15
Comparison Operators
Comparison operators compare values.
Common examples:
== Equal
!= Not equal
> Greater than
< Less than
>= Greater than or equal
<= Less than or equal
Example:
def main():
var age = 20
print(age >= 18)
if Statements
Use if to execute code conditionally.
Example:
def main():
var age = 20
if age >= 18:
print("Adult")
The basic syntax is:
if condition:
statement
if and else
Example:
def main():
var age = 16
if age >= 18:
print("Adult")
else:
print("Minor")
Output:
Minor
elif
Use elif when you have multiple conditions.
Example:
def main():
var score = 80
if score >= 90:
print("Excellent")
elif score >= 70:
print("Good")
else:
print("Needs improvement")
Output:
Good
Nested Conditions
Conditions can also be placed inside other conditions.
Example:
def main():
var age = 25
var has_license = True
if age >= 18:
if has_license:
print("Can drive")
Keep nesting limited when possible because excessive nesting can make code difficult to read.
for Loops
A for loop repeats code over a sequence or range.
Example:
def main():
for i in range(5):
print(i)
This repeatedly executes:
print(i)
for the values generated by the range.
while Loops
A while loop repeats as long as a condition remains true.
Conceptually:
def main():
var count = 0
while count < 5:
print(count)
count += 1
The execution flow is:
Check Condition
↓
True?
↓
Run Code
↓
Update Value
↓
Check Again
break
break exits a loop early.
Example:
for i in range(10):
if i == 5:
break
print(i)
When the condition is reached, the loop stops.
continue
continue skips the rest of the current iteration and moves to the next one.
Example concept:
for i in range(5):
if i == 2:
continue
print(i)
This skips printing the value 2.
Function Error Syntax
Mojo functions can declare that they may raise errors using:
raises
Example:
def validate(value: Int) raises:
if value < 0:
raise Error("Value must be non-negative")
The raises keyword marks a function that can propagate an error.
raise
Use:
raise
to raise an error.
Example:
raise Error("Something went wrong")
Error handling becomes increasingly important as programs grow.
try and except
Mojo supports error-handling constructs including:
try
except
These allow code to respond to errors instead of simply terminating.
Mojo’s language reference includes try/except under compound statements.
Struct Syntax
A struct is Mojo’s primary way to define your own custom type.
Basic structure:
struct Player:
var score: Int
A struct can contain:
- Fields
- Methods
- Initializers
- Static methods
Struct Fields
Fields store data inside a struct.
Example:
struct Player:
var name: String
var score: Int
Here:
name
score
are fields.
Struct Initializers
An initializer prepares a new struct value.
The syntax can look like:
struct Player:
var score: Int
def __init__(out self, score: Int):
self.score = score
The out self convention allows the initializer to construct the value.
Mojo structs can define fields, methods, initializers, destructors, and trait conformance.
Struct Methods
Methods are functions defined inside structs.
Example:
struct Player:
var score: Int
def show_score(self):
print(self.score)
Here:
show_score()
is a method.
self in Mojo
Inside a struct method:
self
refers to the current struct instance.
Example:
def show_score(self):
print(self.score)
Mojo’s argument conventions distinguish immutable self from mutable mut self.
mut self
If a method needs to modify the current struct, it can use:
mut self
For example:
def increase_score(mut self):
self.score += 1
This tells Mojo that the method modifies the existing value.
ref Syntax
Mojo supports reference bindings using:
ref
For example:
var data = [1, 2, 3]
ref view = data
A reference does not create an independent owned copy of the value.
The official keyword reference distinguishes var as an owned mutable value from ref as a non-owning reference.
This becomes important when learning Mojo’s ownership and memory model.
Imports
Imports allow code from other modules to be used.
Typical syntax includes:
import module_name
or:
from module_name import something
Imports help organize larger projects into reusable files and packages.
The Mojo language reference includes import and related forms among simple statements.
Basic Module Example
Imagine:
project/
│
├── main.mojo
└── math_utils.mojo
You could place reusable functionality inside:
math_utils.mojo
and import it into:
main.mojo
This prevents every part of your application from being placed inside one huge source file.
Compile-Time Parameters
Mojo supports compile-time parameters using square brackets in declarations.
The general function syntax can include:
def function_name[parameters](arguments):
For example, the official function reference shows compile-time parameters between square brackets before runtime arguments.
This is an advanced feature and is commonly used in generic and performance-oriented programming.
Beginners can learn normal functions first.
Function Declaration Structure
A more complete Mojo function declaration can look like:
def function_name[parameters](arguments) -> ReturnType:
function_body
For simple programs, you might only need:
def add(a: Int, b: Int) -> Int:
return a + b
Traits
Mojo also supports traits.
Traits can describe behavior that types must provide.
They are conceptually useful for writing generic, reusable abstractions.
The Mojo 1.0 language reference includes syntax for trait declarations, associated types, inheritance, composition, and conformance.
Traits are an advanced topic, so beginners do not need to master them immediately.
Mojo Literals
A literal is a value written directly in the source code.
Examples:
10
3.14
"Hello"
True
False
None
Mojo’s reference includes integer, floating-point, string, boolean, None, Self, and other literal forms.
Integer Literal
Example:
var count = 10
Here:
10
is an integer literal.
String Literal
Example:
var name = "Mojo"
Here:
"Mojo"
is a string literal.
Boolean Literal
Example:
var enabled = True
Here:
True
is a boolean literal.
Mojo Expressions
An expression produces a value.
Examples:
10 + 20
age >= 18
square(5)
These can be assigned:
var total = 10 + 20
or passed into functions:
print(10 + 20)
Mojo supports expressions for function calls, member access, indexing, tuples, collections, comprehensions, and conditional expressions.
Operator Precedence
Consider:
var result = 2 + 3 * 4
Multiplication is evaluated before addition.
The result is therefore conceptually:
2 + 12
which gives:
14
Parentheses can make the intended order explicit:
var result = (2 + 3) * 4
The Mojo reference defines precedence and associativity rules for its operators.
Accessing Struct Members
Use a dot:
.
to access fields and methods.
Conceptually:
player.score
or:
player.show_score()
This is called member access.
A Complete Beginner Mojo Syntax Example
Here is a small example combining several concepts:
def square(number: Int) -> Int:
return number * number
def main():
var number: Int = 5
var result = square(number)
if result > 20:
print("Result is greater than 20")
else:
print("Result is 20 or less")
print(result)
This example demonstrates:
def- Functions
- Parameters
- Types
return- Variables
- Function calls
ifelse- Comparisons
print()
Another Mojo Syntax Example
def add(a: Int, b: Int) -> Int:
return a + b
def main():
var first = 10
var second = 20
var total = add(first, second)
print("Total:")
print(total)
Output:
Total:
30
Mojo Syntax vs Python Syntax
Mojo looks similar to Python at first.
Python:
def add(a, b):
return a + b
Mojo:
def add(a: Int, b: Int) -> Int:
return a + b
The main difference here is explicit static type information.
Mojo also includes systems-level concepts that Python normally does not expose directly.
Important Difference From Older Mojo Tutorials
If you find older tutorials online, you may encounter:
fn add(a: Int, b: Int) -> Int:
return a + b
Current Mojo should instead use:
def add(a: Int, b: Int) -> Int:
return a + b
fn is deprecated and def is now the standard function keyword.
This is particularly important when learning Mojo from older blog posts or videos.
Common Mojo Syntax Errors
Wrong Indentation
Incorrect:
def main():
print("Hello")
Correct:
def main():
print("Hello")
Missing Colon
Incorrect:
def main()
print("Hello")
Correct:
def main():
print("Hello")
Wrong Type
Incorrect concept:
var age = 25
age = "Twenty Five"
Because age has already been inferred as an integer type.
Using Deprecated fn
Avoid writing new code with:
fn calculate():
pass
Use:
def calculate():
pass
instead.
Incorrect Function Call
Definition:
def greet(name: String):
print(name)
Call it using:
greet("Alex")
not by omitting the required argument.
Mojo Syntax Cheat Sheet
# Comment
# ------------------
var age = 25
# Explicit type
var score: Int = 100
# Function
def greet():
print("Hello")
# Typed function
def add(a: Int, b: Int) -> Int:
return a + b
# Condition
if age >= 18:
print("Adult")
else:
print("Minor")
# Loop
for i in range(5):
print(i)
# Struct
struct Player:
var score: Int
# Error-capable function
def validate(value: Int) raises:
if value < 0:
raise Error("Invalid value")
Recommended Order to Learn Mojo Syntax
A good beginner learning sequence is:
Program Structure
↓
Variables
↓
Types
↓
Operators
↓
Conditions
↓
Loops
↓
Functions
↓
Error Handling
↓
Structs
↓
Modules
↓
References
↓
Ownership
↓
Traits
↓
Compile-Time Programming
Do not try to master every advanced syntax feature immediately.
Frequently Asked Questions
Is Mojo syntax the same as Python?
No. Mojo intentionally uses many Python-like syntax conventions, but Mojo is a separate statically typed systems programming language with additional concepts such as ownership, references, traits, and compile-time programming.
Does Mojo use indentation?
Yes. Indentation defines code blocks, similar to Python.
How do you declare a variable in Mojo?
Use:
var age = 25
or specify the type:
var age: Int = 25
Is Mojo statically typed?
Yes. Variable types are determined at compile time and do not dynamically change at runtime.
How do you define a function in Mojo?
Use def:
def greet():
print("Hello")
Current Mojo uses def for all normal function declarations.
Does Mojo still use fn?
Older Mojo versions used fn, but it is now deprecated. New Mojo code should use def.
How do you specify a function return type?
Use:
->
Example:
def add(a: Int, b: Int) -> Int:
return a + b
What does var mean in Mojo?
var creates a scoped mutable variable that owns its value.
What does ref mean?
ref creates a reference binding instead of an independent owned copy.
What is mut self?
It indicates that a struct method can modify the current instance.
What is a struct in Mojo?
A struct is Mojo’s primary mechanism for creating custom types that combine fields and behavior.
Does Mojo support error handling?
Yes. Mojo supports constructs including raises, raise, try, and except.
Final Thoughts
Mojo syntax is designed to offer a familiar high-level programming style while also supporting the capabilities needed for high-performance and systems programming.
For beginners, the core syntax can be summarized as:
Variables → var
Functions → def
Conditions → if / elif / else
Loops → for / while
Custom Types → struct
Return Values → return
Errors → raises / raise / try / except
References → ref
Mutable Methods → mut self
A simple Mojo program might look like:
def multiply(a: Int, b: Int) -> Int:
return a * b
def main():
var first = 5
var second = 4
var result = multiply(first, second)
print(result)
Output:
20
Start by mastering variables, data types, operators, conditions, loops, and functions. After those concepts feel comfortable, move into structs, references, ownership, traits, compile-time programming, and Mojo’s performance-oriented features.
Also remember one important point when following tutorials: current Mojo 1.0 uses def for functions. Older examples using fn are outdated because fn is deprecated.




