Skip to main content
Version: 1.0

v0.25.7 (2025-11-20)

✨ Highlights

  • A new, improved UnsafePointer type has been added, and the old version renamed to LegacyUnsafePointer. The new version fixes several issues with the old LegacyUnsafePointer.

    • LegacyUnsafePointer had constructors that allowed unsafe implicit mutability and origin casts, making it easy to make unsafe changes by accident. The new UnsafePointer eliminates these.
    • The new UnsafePointer now has an inferred mutability parameter, simplifying the API.
    • UnsafePointer does not have a default value for its origin parameter, so it must be explicitly specified or unbound. LegacyUnsafePointer defaults to MutAnyOrigin, which results in the lifetimes of many values being extended needlessly.

    For more information, see Pointer and memory changes.

  • Many enhancements to compile-time errors, including suppressing extraneous messages and preserving more human-readable display for many aliases and parameters. For details, see Tooling changes.

  • Added a new document on GPU block and warp operations and synchronization.

Language enhancements

  • Mojo now supports the comptime keyword as a synonym for alias. The comptime keyword can be used interchangeably with alias for compile-time declarations. Both keywords are fully supported and produce identical behavior. For example:

    comptime x = 5      # New preferred syntax
    alias y = 10 # Still fully supported
    comptime MyType[T: AnyType] = T # Works with parametric declarations

    Note: Future updates will migrate error messages and internal terminology to use "comptime". The alias keyword will remain supported for backward compatibility for now.

  • Mojo now supports unpacking an alias/comptime tuple with a single statement when it is not inside a struct or trait. For example:

    comptime i, f = (1, 3.0)
    comptime q, v = divmod(4, 5)
  • Issue #3925: Mojo now allows methods to be overloaded based on "owned" vs "by-ref" argument conventions, selecting the owned overload when given an owned value, and selecting the by-ref version otherwise. This allows somewhat more efficient algorithms, e.g. consuming vs borrowing iterators:

    struct MyCollection:
    fn __iter__(var self) -> Self.ConsumingIterator: ...
    fn __iter__(self) -> Self.BorrowingIterator: ...
  • Collection literals now have a default type. For example, you can now bind [1,2,3] to T in a call to a function defined as fn zip[T: Iterable](impl:T) because it will default to the standard library's List type.

  • Mojo now has a __functions_in_module() experimental intrinsic that allows reflection over the functions declared in the module where it is called. For example:

    fn foo(): pass

    def bar(x: Int): pass

    def main():
    alias funcs = __functions_in_module()
    # equivalent to:
    alias same_funcs = Tuple(foo, bar)

    The intrinsic is currently limited for use from within the main() function. For an example of using __functions_in_module() in a test suite, see Running tests with TestSuite

  • The @implicit decorator now accepts an optional deprecated keyword argument. This can be used to phase out implicit conversions instead of just removing the decorator (which can result in another, unintended implicit conversion path). For example, the compiler now warns about the following:

    struct MyStuff:
    @implicit(deprecated=True)
    fn __init__(out self, value: Int):
    pass

    fn deprecated_implicit_conversion():
    # warning: deprecated implicit conversion from 'IntLiteral[1]' to 'MyStuff'
    _: MyStuff = 1

    _ = MyStuff(1) # this is okay, because the conversion is already explicit.
  • The @deprecated decorator can now take a target symbol with the use keyword argument. This is mutually exclusive with the existing positional string argument. A deprecation warning will be automatically generated.

    @deprecated(use=new)
    fn old():
    pass

    fn new():
    pass

    fn main():
    old() # 'old' is deprecated, use 'new' instead
  • In struct instances that declare a parametric __call__() method, but not one of the subscript methods (__getitem__(), __setitem__(), or __getattr__()), the __call__() method can now be invoked with parameters:

    struct Callable:
    fn __init__(out self):
    pass

    fn __call__[x: Int](self, y: Int) -> Int:
    return x + y

    fn main():
    var c = Callable()
    print(c[1](2)) # 3

    Previously you would have needed to explicitly look up __call__():

    print(c.__call__[1](2))
  • Added DType.float4_e2m1fn as the 4bit float e2m1 format. This Float4_e2m1 type is defined by the Open Compute MX Specification.

  • deinit methods may now transfer all of self to another deinit method.

  • Mojo now uses system allocators in programs built with mojo build --sanitize address. This means ASan can see Mojo heap allocations and should now be able to detect many more heap memory errors.

Language changes

  • The __type_of() magic function has been renamed to type_of(). Using the old spelling will yield an error. Similarly, __origin_of() has been renamed to origin_of().

  • An expression like (Int, Float64) is no longer syntax sugar for a tuple types like Tuple[Int, Float64].

Library changes

Pointer and memory changes

  • UnsafePointer has been renamed to LegacyUnsafePointer and a new UnsafePointer has taken its place. Similarly, OpaquePointer has been renamed to LegacyOpaquePointer and a new OpaquePointer has taken its place. The primary difference is the ordering of parameters, which now looks like this:

    struct UnsafePointer[
    mut: Bool, //, # Inferred mutability
    type: AnyType,
    origin: Origin[mut], # Non-defaulted origin
    *,
    address_space: AddressSpace = AddressSpace.GENERIC,
    ]

    alias OpaquePointer[
    mut: Bool, //, # Inferred mutability
    origin: Origin[mut], # Non-defaulted origin
    *,
    address_space: AddressSpace = AddressSpace.GENERIC,
    ] = UnsafePointer[NoneType, origin, address_space=address_space]

    Its implicit constructors now no longer allow for unsafe casting between pointers with different mutability and origin values. Code will need to update to the new UnsafePointer, however, in the interim, users can find-and-replace their current usages of UnsafePointer and rename them to LegacyUnsafePointer. Another option is users can add the following import statement to the beginning of any files relying on the old pointer type:

    from memory import LegacyUnsafePointer as UnsafePointer, **_]
    # and/or if you use OpaquePointer
    from memory import LegacyOpaquePointer as OpaquePointer

    Users can also use the as_legacy_pointer() and as_unsafe_pointer() conversion methods to convert between the two pointer types during this migration period.

    Note: LegacyUnsafePointer and LegacyOpaquePointer will eventually be deprecated and removed in a future version of Mojo.

    There are a few new helpful type aliases for UnsafePointer:

    • MutUnsafePointer
    • ImmutUnsafePointer
    • MutOpaquePointer
    • ImmutOpaquePointer

    Lastly, alloc() has been moved from a static method on UnsafePointer to a free standing alloc() function. Therefore, code that was written as:

    var ptr = UnsafePointer[Int].alloc(3)

    Must be changed to:

    var ptr = alloc[Int](3)

    For more details on migrating to the new UnsafePointer, see the migration guide provided in the

    UnsafePointer v2 proposal.

  • Added a swap_pointees() function to UnsafePointer as an alternative to swap() when the pointers may potentially alias each other.

  • origin_cast() for LayoutTensor, NDBuffer and UnsafePointer has been deprecated and removed. LayoutTensor and NDBuffer now support a safer as_any_origin() origin casting method. UnsafePointer has the same safe alternative and in addition, it has a safe as_immutable() casting function and explicitly unsafe unsafe_mut_cast() and unsafe_origin_cast() casting methods.

  • The empty origin has been renamed to external. This origin represents a value that's not tracked by the Mojo lifetime checker. Newly-allocated memory from alloc() is returned with the origin MutOrigin.external.

  • Renamed MutableOrigin to MutOrigin and ImmutableOrigin to ImmutOrigin.

  • Renamed MutableAnyOrigin to MutAnyOrigin and ImmutableAnyOrigin to ImmutAnyOrigin.

  • memcpy() and parallel_memcpy() without keyword arguments are deprecated.

Collections and iterators

  • Span and StringSlice constructors now accept Int for length parameters instead of UInt. This change makes these types more ergonomic to use with integer literals and other Int-based APIs.

  • Added Span.binary_search_by() which allows binary searching with a custom comparator function.

  • Added unsafe_get(), unsafe_swap_elements() and unsafe_subspan() to the Span struct.

  • Optional now conforms to Iterable and Iterator acting as a collection of size 1 or 0.

  • New ContiguousSlice and StridedSlice types were added to the builtin_slice module to support specialization for slicing without strides.

  • List slicing without a stride now returns a Span, instead of a List and no longer allocates memory.

  • Several standard library APIs have been updated to use Int instead of UInt for improved ergonomics, eliminating the need for explicit casts when using Int values (the default type for integer literals and loop indices):

    • BitSet[size: Int] - Changed parameter from UInt to Int
    • BitSet.set(idx: Int), BitSet.clear(idx: Int), BitSet.toggle(idx: Int), BitSet.test(idx: Int) - Changed from UInt to Int
    • String(unsafe_uninit_length: Int) - Changed from UInt to Int
    • String.capacity() -> Int - Changed return type from UInt to Int
    • String.reserve(new_capacity: Int) - Changed from UInt to Int
    • List(length: Int, fill: T) - Changed from UInt to Int
    • Codepoint.unsafe_write_utf8() -> Int - Changed return type from UInt to Int
    • Codepoint.utf8_byte_length() -> Int - Changed return type from UInt to Int
  • Added repeat() function to the itertools module that creates an iterator which repeats an element a specified number of times. Unlike Python's itertools.repeat(), infinite iteration is not currently supported - the times parameter is required. Example usage:

    from itertools import repeat

    for val in repeat(42, times=3):
    print(val) # Prints: 42, 42, 42
  • Tuples now support comparison operations if the element types are also comparable. For example, one can now write (1, "a") == (1, "a") or (1, "a") < (1, "b").

String and text

  • Codepoint now conforms to Writable.

  • Codepoint now conforms to Comparable adding __le__(), __lt__(), __ge__(), and __gt__() implementations.

Math and numeric types

  • The deprecated DType.index is now removed in favor of the DType.int.

  • Added DType.float4_e2m1fn as the 4bit float e2m1 format. This Float4_e2m1 type is defined by the Open Compute MX Specification.

  • math.isqrt() has been renamed to rsqrt() since it performs reciprocal square root functionality.

  • The math package now has a Mojo native implementation of acos(), asin(), cbrt(), and erfc().

  • SIMD now implements the DivModable trait.

  • Implicit conversions between Int and UInt are now deprecated.

    The @implicit decorator on Int.__init__(UInt) and UInt.__init__(Int) will be removed in a future version of Mojo. Code that currently performs implicit conversions between Int and UInt will issue a deprecation warning, and should be updated to explicitly read Int(uint_val) or UInt(int_val) respectively.

  • The ImplicitlyIntable trait has been removed. Types implementing this trait could be implicitly converted to Int.

    Bool was the only Mojo standard library type to implement ImplicitlyIntable. Conversions from Bool to Int can now be performed explicitly, using Int(bool-val) (via the remaining Intable trait, which only supports explicit conversions).

GPU support

  • Added support for NVIDIA GeForce GTX 970.

  • gpu.sync.syncwarp() now supports Apple GPUs via SIMDGROUP barrier implementation. On Apple GPUs, this provides execution synchronization for all active lanes using a SIMDGROUP barrier with no memory fence. For threadgroup memory ordering, use barrier() instead. Note that lane masks are not supported on Apple GPUs, so the mask argument is ignored.

  • gpu.primitives.warp now supports Apple GPUs with native SIMD-group shuffle operations. This enables shuffle_idx(), shuffle_up(), shuffle_down(), and shuffle_xor() on Apple hardware by mapping Metal simd_shuffle* intrinsics to AIR (llvm.air.simd_shuffle[_up/_down/_xor]) instructions, achieving feature parity with NVIDIA and AMD backends.

  • gpu.intrinsics.store_release() and gpu.intrinsics.load_acquire() now support Apple silicon GPUs, expanding support for proper memory synchronization on these devices.

  • The gpu package has been reorganized into logical subdirectories for better code organization:

    • gpu/primitives/ - Low-level GPU execution primitives (warp, block, cluster, id, grid_controls)
    • gpu/memory/ - Memory operations (async_copy, TMA, address spaces)
    • gpu/sync/ - Synchronization primitives (barriers, semaphores)
    • gpu/compute/ - Compute operations (mma, tensor cores, tcgen05)

    Backward compatibility: All existing imports continue to work unchanged. Deprecated import paths (gpu.id, gpu.mma, gpu.cluster, gpu.grid_controls, gpu.warp, gpu.semaphore, gpu.mma_sm100, gpu.tcgen05, gpu.mma_util, gpu.mma_operand_descriptor, and gpu.tensor_ops) are preserved as re-export wrappers with deprecation notices. Users can migrate to the new recommended import patterns at their own pace:

    # Old (deprecated but still works):
    from gpu.id import block_idx, thread_idx
    from gpu.mma import mma
    from gpu.mma_sm100 import UMMAKind
    from gpu.tcgen05 import tcgen05_alloc
    from gpu.semaphore import Semaphore
    from gpu.cluster import cluster_sync

    # New (recommended):
    from gpu import block_idx, thread_idx, cluster_sync
    from gpu.compute.mma import mma
    from gpu.compute.mma_sm100 import UMMAKind
    from gpu.compute.tcgen05 import tcgen05_alloc
    from gpu.sync.semaphore import Semaphore
  • The _GPUAddressSpace type has been removed and consolidated into AddressSpace. GPU-specific address space constants (GLOBAL, SHARED, CONSTANT, LOCAL, SHARED_CLUSTER) are now available as aliases on the unified AddressSpace type. The GPUAddressSpace alias has also been removed in favor of using AddressSpace directly. Since AddressSpace is part of the prelude, it no longer needs to be explicitly imported in most code.

  • TMA (Tensor Memory Accelerator) types have been moved to a dedicated module. The types TMADescriptor, TensorMapSwizzle, TensorMapDataType, TensorMapInterleave, TensorMapL2Promotion, TensorMapFloatOOBFill, and the functions create_tma_descriptor() and prefetch_tma_descriptor() are now available from gpu.host.nvidia.tma instead of gpu.host._nvidia_cuda.

Testing

  • assert_equal() now displays colored character-by-character diffs when string comparisons fail, making it easier to spot differences. Differing characters are highlighted in red for the left string and green for the right string.

  • The mojo test command has been removed. The recommended testing strategy is to define test functions, call them explicitly from main() (or use the new TestSuite framework), and run with mojo run.

  • TestSuite now can generate test reports with .generate_report(). Also, TestReport and TestSuiteReport structs were added.

  • TestSuite now allows explicitly skipping registered tests using the TestSuite.skip() method.

  • TestSuite now allows basic control from CLI arguments. Tests can be skipped from the CLI by passing test function names after a --skip flag, e.g.

    mojo run test_my_stuff.mojo --skip test_currently_failing test_also_failing

    Similarly, the --only flag enables the specification of an allowlist, e.g. the following will skip any other registered test cases:

    mojo run test_my_stuff.mojo --only test_only_this test_this_as_well

    The --skip-all flag will skip all registered test cases in the suite. Note that --only respects skipped tests, i.e. it does not run tests that are skipped using TestSuite.skip().

System and OS

  • Added os.isatty() function to check whether a file descriptor refers to a terminal. This function accepts an Int file descriptor. If you have a FileDescriptor object, use its isatty() method instead.

  • Added sys.compile.SanitizeAddress providing a way for Mojo code to detect --sanitize address at compile time.

  • DLHandle is no longer part of the public API. To access a dynamically-linked library from Mojo, use OwnedDLHandle instead. The new type provides RAII-based automatic resource management for dynamically-linked libraries. DLHandle has been renamed to _DLHandle and remains available internally for use by the standard library.

Performance optimizations

  • Optimized float-to-string formatting performance by eliminating unnecessary stack allocations. Internal lookup tables used for float formatting (cache_f32 and cache_f64) are now stored as global constants instead of being materialized on the stack for each conversion. This reduces stack overhead by ~10KB for Float64 and ~600 bytes for Float32 operations, improving performance for all float formatting operations including print(), string interpolation, and str() conversions.

  • Optimized number parsing performance by eliminating stack allocations for large lookup tables. Internal lookup tables used for number parsing (powers_of_5_table and POWERS_OF_10) are now stored as global constants using the global_constant function instead of being materialized on the stack for each parsing operation. This reduces stack overhead by ~10.6KB for number parsing operations, improving performance for string-to-number conversions including atof() and related float parsing operations.

Other library changes

  • The Hasher trait's _update_with_bytes() method now takes Span[Byte] instead of UnsafePointer[UInt8] and a separate length parameter. This change applies to all hasher implementations including AHasher and Fnv1a.

  • The Philox random number generator (Random and NormalRandom) has been moved from gpu.random to random.philox. These types now work on both CPU and GPU. Import them using from random import Random, NormalRandom or from random.philox import Random, NormalRandom.

Tooling changes

  • Error and warning messages now preserve comptime/alias names in many cases, to prevent extremely long type names for complex types. The compiler will expand these when necessary to understand the type based on a simple heuristic, for example:

    struct Dep[T: AnyType, v: T]: pass
    alias MyDep[T: AnyType, v: T] = Dep[T, v]
    alias MyDepGetAlias0 = MyDep.hello

    produces:

    $ mojo t.mojo
    t.mojo:10:29: error: 'MyDep' needs more parameters bound before accessing attributes
    alias MyDepGetAlias0 = MyDep.hello
    ^
    t.mojo:10:29: note: 'MyDep' is aka 'alias[T: AnyType, v: T] Dep[T, v]'

    Please file issues in cases where more information needs to be exposed.

  • Error messages now preserve symbolic calls to always_inline("builtin") functions rather than inlining them into the error message.

  • This release includes a number of improvements to elaboration errors. The elaborator is the compiler pass where final parameter values are determined and code is transformed from parametric to concrete. Common errors from elaboration include "function instantiation failed" and "call expansion failed" messages, when it's determined that the actual parameter values don't match any viable function overload.

    The elaborator also checks constraints (defined using the constrained() function), so constraint failures are generated during this pass.

    • Elaboration errors now report the full call instantiation failure path. For this Mojo file:

      fn fn1[T: ImplicitlyCopyable, //] (a: T):
      constrained[False]()
      fn fn2[T: ImplicitlyCopyable, //] (a: T):
      return fn1(a)
      fn main():
      fn2(1)

      Now the error prints the path of main -> fn2 -> fn1 -> constrained[False] instead of just constrained[False].

    • Elaboration errors now print out trivial parameter values with call expansion failures. For this simple Mojo program:

      fn fn1[a: Int, b: Int]():
      constrained[a < b]()

      fn fn2[a: Int, b: Int]():
      fn1[a, b]()

      fn main():
      fn2[4, 2]()

      Now the error message shows parameter value(s): ("a": 4, "b": 2):

      test.mojo:6:14: note: call expansion failed with parameter value(s): ("a": 4, "b": 2)
      fn1[a, b]()

      Only string and numerical values are printed out by default now, other values are shown as .... Use --elaboration-error-verbose to show all parameter values.

    • Elaboration error messages related to the prelude are omitted by default. The prelude is the set of APIs exported from std/builtin/_startup.mojo. These APIs persist in all call expansion paths but are rarely the source of reported errors. These APIs are now omitted by default to de-clutter elaboration errors.

      Use --elaboration-error-include-prelude to include prelude.

      • By default (without prelude):

        test.mojo:43:4: error: function instantiation failed
        fn main():
        ^
        test.mojo:45:12: note: call expansion failed
        my_func()
        ...
      • With prelude:

        oss/modular/mojo/stdlib/std/builtin/_startup.mojo:119:4: error: function instantiation failed
        fn __mojo_main_prototype(
        ^
        oss/modular/mojo/stdlib/std/builtin/_startup.mojo:119:4: note: call expansion failed with parameter value(s): (...)
        oss/modular/mojo/stdlib/std/builtin/_startup.mojo:42:4: note: function instantiation failed
        fn __wrap_and_execute_main[
        ^
        oss/modular/mojo/stdlib/std/builtin/_startup.mojo:68:14: note: call expansion failed
        main_func()
        ^
        test.mojo:43:4: note: function instantiation failed
        fn main():
        ^
        test:45:12: note: call expansion failed
        my_func()
        ...
    • An --elaboration-error-limit option has been added to the mojo run and mojo build commands. This option sets a limit to the number of elaboration errors that get printed. The default value is 20. To change the limit, use --elaboration-error-limit=limit, where a limit of 0 means unlimited.

  • --help-hidden option has been added to all Mojo CLI commands to show hidden options.

  • mojo debug now rejects unknown options between debug and the target.

  • The Mojo language server will now report more coherent code actions.

  • The mojo CLI now has an --experimental-fixit flag that automatically applies FixIt hints emitted by the parser. This feature is highly experimental, and users should ensure they back up their files (or check them into source control) before using it.

❌ Removed

  • mojo test has been deprecated and removed as described in the deprecation proposal. For more information, see the Testing section.

  • LayoutTensorBuild type has been removed. Use LayoutTensor with parameters directly instead.

  • The following traits have been removed: LessThanComparable, GreaterThanComparable, LessThanOrEqualComparable, GreaterThanOrEqualComparable. It is extremely rare that a type would only implement one of these, so one can just use Comparable instead.

  • All telemetry-related code has been removed from the Mojo compiler. This should eliminate the source of some hangs and misbehavior on poor internet connections.

🛠️ Fixed

  • Issue #5111: The math.cos() and math.sin() function can now be evaluated at compile time.

  • Fixed IntTuple.value(i) method returning incorrect values when elements are stored as nested single-element tuples. Previously, calling Layout.row_major(M, N).stride.value(i) would return negative offset values (e.g., -65536, -65537) instead of the actual stride values. This affected any code that accessed layout stride or shape values using the value() method.

  • Fixed LayoutTensor.shape[idx]() method returning incorrect values for nested layouts. The bug occurred when accessing shape dimensions of tensors with nested layouts like ((32, 2), (32, 4)), where the method would return garbage values instead of the correct product (e.g., 64).

  • Fixed LayoutTensor element-wise arithmetic operations (+, -, *, /) between tensors with different memory layouts. Previously, operations like a.transpose() - b would produce incorrect results when the operands had different layouts, because the same layout index was incorrectly used for both operands. This now correctly computes separate indices for each tensor based on its layout.

  • Fixed LayoutTensor.shape[idx]() method returning incorrect values for nested layouts. The bug occurred when accessing shape dimensions of tensors with nested layouts like ((32, 2), (32, 4)), where the method would return garbage values instead of the correct product (e.g., 64).

  • Fixed arange() function in layout._fillers to properly handle nested layout structures. Previously, the function would fail when filling tensors with nested layouts like Layout(IntTuple(IntTuple(16, 8), IntTuple(32, 2)), ...) because it attempted to extract shape values from nested tuples incorrectly.

  • Issue #5479: Mojo crashes when compiling standalone __del__ function without struct context.

  • Issue #5500: Added comprehensive documentation to gpu/host/info.mojo explaining GPU target configuration and LLVM data layout strings. The documentation now includes detailed explanations of all MLIR target components, vendor-specific patterns for NVIDIA/AMD/Apple GPUs, step-by-step guides for adding new GPU architectures, and practical methods for obtaining data layout strings.

  • Issue #5492: Fixed FileHandle "rw" mode unexpectedly truncating file contents. Opening a file with open(path, "rw") now correctly preserves existing file content and allows both reading and writing, similar to Python's "r+" mode. Previously, "rw" mode would immediately truncate the file, making it impossible to read existing content and causing potential data loss.

  • Issue #3849: Added support for append mode ("a") when opening files. The open() function now accepts "a" as a valid mode, which opens a file for appending. Content written to a file opened in append mode is added to the end of the file without truncating existing content. If the file doesn't exist, it will be created.

  • Issue #3208: Fixed FileHandle raising "unable to remove existing file" error when opening a FIFO (named pipe) in write mode. Opening special files like FIFOs, devices, and sockets with open(path, "w") now works correctly. Previously, write mode would attempt to remove the existing file before opening it, which failed for special files that should not be removed.

  • Issue #5142: The sys.intrinsics.compressed_store function now includes a debug_assert to catch null pointer usage, providing a clear error message instead of crashing with a segmentation fault.

  • The sys.intrinsics.strided_load(), sys.intrinsics.strided_store(), sys.intrinsics.masked_load(), and sys.intrinsics.masked_store() functions now include a debug_assert() to catch null pointer usage, providing a clear error message instead of crashing with a segmentation fault.

  • The logger package now prints its levels in color.

  • Throwing deinit methods now understand that self is deinitialized in error paths, avoiding redundant calls to implicit destructors and improving linear type support.

Special thanks

Special thanks to our community contributors: Brian Grenier (@bgreni), c-pozzi (@c-pozzi), Christoph Schlumpf (@christoph-schlumpf), cudawarped (@cudawarped), David Faden (revfad.com) (@fadend), Ethan Wu (@YichengDWu), Hardik Gupta (@hardikkgupta), j_rutzmoser (@Rutzmoser), Johnny Lin (@johnny19436), Jose (@josetorrs), josiahls (@josiahls), Luis Chamberlain (@mcgrof), Manuel Saelices (@msaelices), Marius S (@winding-lines), martinvuyk (@martinvuyk), MaxMeyberg (@MaxMeyberg), Monal (@Monal-Patel), skrript (@skrript), soraros (@soraros), and Thomas Mader (@ThomasMader).