Mojo v1.0.0 | Mojo
IMPORTANT: To view this page as Markdown, append `.md` to the URL (e.g. /docs/manual/basics.md).<br>For the complete Mojo documentation index, see llms.txt.<br>Skip to main content
Mojo will be open source soon! Join us at ModCon '26 for an update.
Highlights
With Mojo 1.0 we're staring to define the stability policies for the Mojo<br>language and standard library. We've started marking standard library APIs as<br>stable, meaning they won't be removed or changed in a way that breaks source<br>compatibility, beginning with a deliberately small set that we'll grow in<br>subsequent releases. For details, see<br>Library stabilizations.
We worked hard on getting names, defaults, and safety boundaries right for 1.0.<br>That does mean you'll find more breaking changes than usual in this release.<br>But nearly every breaking change ships with a deprecated alias and a compiler<br>fix-it, so migration is mechanical.
Language ergonomics : Mojo gained lambda expressions—anonymous,<br>single-expression closures that desugar to a nested def. List expressions<br>now construct an Array rather than a List by default, and keyword<br>variadics can be forwarded to another function with Python-style ** syntax.<br>See Language enhancements.
Memory safety and pointer unification : Pointer and UnsafePointer are<br>unified into a single Pointer type, with unsafety now marked on the<br>individual operation instead of on the type as a whole. UnsafeAnyOrigin is<br>correspondingly harder to acquire by accident: implicit widening to it is<br>deprecated, and a struct field can no longer hide one. See<br>Pointers and memory.
The lifetime checker now understands container interiors : a new<br>experimental feature known as interior origins lets List, Dict,<br>String, and several other types return element references bound to an<br>interior origin, so code that holds an element reference across a mutation is<br>rejected instead of silently dangling after a reallocation. See<br>Language enhancements and<br>Collections and iterators.
Explicit over implicit : a number of inference rules and silent defaults<br>now have to be written down. Declaring a variable without var is deprecated,<br>a method's self must have type Self, and a bare **kwargs must be spelled<br>var **kwargs. The import system has been overhauled to make name resolution<br>explicit and consistent. See Language changes.
One name, and one type, per concept : this release consolidates vocabulary<br>that had drifted. size becomes length throughout, InlineArray becomes<br>Array, StringSlice becomes StringSpan, ImplicitlyDestructible becomes<br>Deinitable with the destructor spelled __deinit__(), and read becomes<br>imm. Duplicated types are consolidated too: Int is now an alias for<br>Scalar[DType.int], and the Int-based and Scalar-based range() types<br>are unified into a single dtype-parameterized family. See<br>Library changes and<br>SIMD and numeric types.
Collections accept more types : a type that models a unique resource can<br>now live in a container. Several collection types conform to Deinitable<br>only when their element type does, so a collection of explicitly-destroyed<br>elements now compiles where it previously did not; such a collection must be<br>drained with the new deinit_with() method. Optional and Variant also<br>accept element types that are not Movable. See<br>Explicitly-destroyed types and deinitialization.
Constraints do more of the work : a where clause accepts a string-literal<br>message the compiler reports when the constraint fails,<br>TypeList.all_conforms_to() refines each element of a parameter pack, and<br>type equality is now spelled with == and !=. Struct types are Movable by<br>default, with Movable where to narrow the conformance. See<br>Language enhancements and<br>Type system and traits.
Correct by default, even at the cost of convenience : APIs that quietly<br>did something defensible but wrong now refuse or do the right thing instead.<br>Indexing with an invalid contiguous slice exits the program instead of<br>silently clamping or wrapping it. Iterating over a string yields grapheme<br>clusters by default, so for c in my_string produces what a user perceives<br>as a single character on screen. range() rejects non-numeric element types<br>and the float forms that used to loop forever, and size_of() returns the<br>allocation size, fixing memory corruption for over-aligned types in List.<br>See Collections and iterators,<br>String and text, and<br>SIMD and numeric types.
Faster Python interoperability : PythonObject arithmetic, comparison,<br>and membership operators now dispatch through CPython's abstract protocols<br>instead of a Python-level attribute lookup followed by a bound-method call.<br>This is roughly 12x faster on the interop hot path and follows standard<br>Python operator semantics more closely. See<br>Python interoperability.
A clearer boundary between Mojo and MAX : some standard library APIs<br>related to accelerator programming have moved to a new max Mojo package,<br>and the layout package is now bundled with MAX instead of Mojo. Relatedly,<br>Int and UInt no longer conform to...