mojo 言語が 2026年8月11日、ついに 1.0.0 に到達しました。Modular が「Python の書きやすさと C の速度」を掲げて 2023年に発表してから約3年、ようやく正式版です。ただし 1.0 は「安定した」という意味であると同時に、そこに至るまでに文法が大きく変わったという意味でもあります。本記事では macOS(Apple Silicon)に実際に導入し、Mojo の象徴だった fn キーワードが削除されたことをはじめとする破壊的変更を、1行ずつ実行して確かめます。
30秒でわかる Mojo 1.0(2026年8月26日時点・実測)
・いつ:2026-08-11、MAX 26.5 と同時に Mojo 1.0.0 公開(タグ max/v26.5.0)
・入れ方:macOS なら pip install mojo のみ。Apple Silicon 向けホイールが配布されている
・最大の破壊的変更:fn が削除された。エラーは “‘fn’ has been removed; use ‘def’ instead”
・次点:let も削除(var のみ)。from math import … は std.math へ
・std と max:pip install mojo だけでは max.* は解決できない。max は別パッケージ
・既存の日本語入門記事のコードは、ほぼ最初の数行で止まる
mojo 言語とは:Python の見た目でネイティブに落とす
Mojo は Modular(LLVM・Swift の設計者である Chris Lattner 氏が共同創業)が開発するプログラミング言語です。Python に似た構文を持ちながら、静的型・所有権・SIMD といった低レベルの制御を備え、インタプリタを介さずネイティブコードにコンパイルすることを狙っています。
リポジトリは modular/modular に統合されており、GitHub 実測で ★29,143・fork 3,105、直近 push は 2026-08-25 です。リポジトリ名が示すとおり、ここには言語である Mojo と、推論エンジンである Modular MAX の両方が入っています。GitHub API が返すライセンスは NOASSERTION で、リポジトリ全体が単一ライセンスではないことを示しています。
日本語圏では 2023年のローンチ時に「Python の 35000 倍速い」という見出しが広く出回り、その印象のまま止まっている読者も多いはずです。実際、mojo 言語 で検索したときに上位に並ぶ日本語記事は、ほぼすべてがローンチ期〜ベータ期の内容です。
Mojo 1.0.0 到達までの時系列
GitHub Releases API の実測値です。
| 日付 | タグ | 内容 |
|---|---|---|
| 2025-09-22 | modular/v25.6.0 | Modular 25.6 |
| 2025-11-20 | modular/v25.7.0 | Modular 25.7 |
| 2026-01-29 | modular/v26.1.0 | Modular 26.1 |
| 2026-03-19 | modular/v26.2.0 | Modular 26.2 |
| 2026-05-07 | max/v26.3.0 | MAX 26.3 / Mojo 1.0.0b1(ベータ) |
| 2026-06-18 | max/v26.4.0 | MAX 26.4 / Mojo 1.0.0b2(ベータ) |
| 2026-08-11 | max/v26.5.0 | MAX 26.5 / Mojo 1.0.0(正式版) |
タグの接頭辞が modular/ から max/ に変わっている点にも注目してください。2026年3月までは「Modular リリース」だったものが、5月以降は MAX のバージョンに Mojo が同梱される形に整理されています。Mojo は単体の言語処理系というより、MAX プラットフォームの一部として配布されるという位置づけが、リリース体系にも表れています。
macOS に入れて動かす:pip install mojo で完結する
かつて Mojo インストールは専用の modular CLI や magic / pixi といったツール経由が必要で、そこが最初の関門でした。1.0 では PyPI からそのまま入ります。
# Apple Silicon の Mac で、venv を切って導入する
python3 -m venv venv-mojo
./venv-mojo/bin/pip install mojo
./venv-mojo/bin/mojo --version
実行結果は Mojo 1.0.0 (ed45d567) でした。PyPI に配布されているホイールは次の3つで、macosx_13_0_arm64 が含まれています。
・mojo-1.0.0-py3-none-macosx_13_0_arm64.whl
・mojo-1.0.0-py3-none-manylinux_2_34_aarch64.whl
・mojo-1.0.0-py3-none-manylinux_2_34_x86_64.whl
hello world を書いて実行します。
def main():
print("hello from Mojo")
./venv-mojo/bin/mojo run hello.mojo # => hello from Mojo
./venv-mojo/bin/mojo build hello.mojo -o ./binout
./binout # => built
mojo build で生成されたネイティブ実行ファイルは 35,912 バイトで、単体で動作しました。インタプリタを介さずバイナリになるという主張は、この最小例では確かに成立しています。
実行のたびに
Failed to initialize Crashpad. Crash reporting will not be available. という警告が標準エラーに出ます。クラッシュレポータのハンドラが見つからないというもので、プログラムの実行自体には影響しません。ただしスクリプトで mojo run の出力を判定する場合、この行が混ざるため grep -v などで除く必要があります(本記事の計測もそうしました)。
速度を測ってみる——起動は遅く、計算は速い
「Python の何倍速いのか」は多くの読者が気にする点なので、実際に測りました。倍率の主張を検証したのではなく、手元で再現できる範囲の数字を出しただけである点を先に断っておきます。
まず hello world の実行時間(5回平均)です。
| 実行方法 | 1回あたり |
|---|---|
mojo run(毎回コンパイルする) |
567 ms |
| ビルド済みネイティブバイナリ | 60 ms |
python3 |
32 ms |
計算量のある処理でこそ差が出ます。sqrt を 2億回加算する同じ処理を両方で書いて実行しました(mojo build 済みバイナリと python3)。
| 実行 | real | user | 出力 |
|---|---|---|---|
| Mojo(ビルド済み) | 0.54 s | 0.32 s | 1885618090235.04 |
| Python 3.14 | 43.76 s | 43.11 s | 1885618090235.04 |
出力は完全に一致しており、同じ計算をしています。wall clock で約 81倍、CPU 時間で約 135倍 の差です。
この数字を出すにあたって、ループがコンパイラに最適化で消されていないかを確認しました。ループ回数を 200万・2000万・2億と変えたときの CPU 時間は 0.01s / 0.03s / 0.32s と、2000万→2億でおよそ10倍に線形増加しています。消されていれば回数を増やしても時間は変わらないため、実際に計算が行われていると判断できます。小さい回数で時間が頭打ちに見えるのは、約 0.22 秒あるプロセス起動の下駄が支配的なためです。
測ったのはスカラのループ1本だけです。SIMD も並列化も GPU も使っていません。したがってこの 81倍という数字は、Mojo の性能の上限でも代表値でもありません。ローンチ期に広まった「35000倍」のような数字は、SIMD・並列化・特定のワークロードを前提にした条件下のもので、本記事の計測とは比較できません。ここで示したのは「素直に書いたループでも桁が変わる」という水準までです。
mojo 言語の旧コードは動かない:fn・let・import が消えた
ここからが本題です。2023〜2024年期の Mojo 入門記事に載っていた典型的なコードを、そのまま 1.0.0 に食わせました。
from math import sqrt
from memory import UnsafePointer
fn main():
let x: Float64 = 2.0
print(sqrt(x))
結果は、3種類のエラーが同時に出ます。
error: unable to locate module 'math'
error: unable to locate module 'memory'
error: 'fn' has been removed; use 'def' instead
構文ごとに切り分けて1つずつ実行した結果が次の表です。すべて macOS(arm64) 上の Mojo 1.0.0 で実測しています。
| 旧来の書き方 | Mojo 1.0.0 での結果 | 移行先 |
|---|---|---|
fn main(): |
❌ 'fn' has been removed; use 'def' instead |
def |
def main(): |
✅ 通る | — |
let x = 1 |
❌ use of unknown declaration 'let' |
var |
var x = 1 |
✅ 通る | — |
from math import sqrt |
❌ unable to locate module 'math' |
std.math |
from std.math import sqrt |
✅ 通る(2.0 を出力) |
— |
List[Int](1,2,3) |
❌ no matching function in initialization |
[1,2,3] |
var l = [1,2,3] |
✅ 通る(len は 3) |
— |
SIMD[DType.float32, 4](1.0) |
✅ 通る | — |
fn の削除は、Mojo という言語の説明の仕方そのものを変えます。ローンチ以来ずっと「Python 互換の def と、厳密な型・所有権を要求する fn の二本立て」が Mojo の特徴として説明されてきました。その片方が消えたということは、過去の解説記事の中核部分がまるごと古くなったことを意味します。書き直すとこうなります。
from std.math import sqrt
def main():
var x: Float64 = 2.0
print(sqrt(x))
これは正しく 1.4142135623730951 を出力しました。移行そのものは機械的で難しくありませんが、「機械的な置換で済む」ことと「既存記事を読んでそのまま書ける」ことは別です。エラーメッセージが移行先を明示してくれる点(use 'def' instead)は親切な設計で、let については use of unknown declaration 'let' と、やや素っ気ない表示になります。
Mojo チュートリアルのコード"] --> B{"1.0.0 でコンパイル"} B --> C["fn → 削除済み"] B --> D["let → 削除済み"] B --> E["from math import → 移動"] B --> F["List[Int](1,2,3) → 構築子変更"] C --> G["def へ書き換え"] D --> G E --> H["std.math へ書き換え"] F --> I["[1,2,3] リテラルへ"] G --> J["1.0.0 で動くコード"] H --> J I --> J
移行の当たりを付けるための std モジュール一覧
旧コードの from <名前> import … を書き換えるとき、まず「その名前が std. の下にあるか」を知りたくなります。pip install mojo だけの環境で、代表的なモジュール名を std.<名前> として import できるか総当たりで確かめました。
| 判定 | モジュール |
|---|---|
✅ std. の下で解決できる |
math / memory / collections / sys / os / time / random / bit / hashlib / algorithm / benchmark / gpu / complex / utils / testing |
| ❌ 解決できない | string / tensor / buffer |
つまり旧コードの大半は、from math import sqrt を from std.math import sqrt にするという機械的な置換で通ります。memory や collections も同様です。
解決できなかった3つには理由が推測できます。String は import なしで使えることを確認しており(var s = String("hi") はそのまま通った)、prelude に取り込まれたとみられます。tensor と buffer は 1.0 に至る整理の過程で姿を消したか、max 側へ移ったと考えられますが、どちらであるかは本記事では確認していません(未検証)。
同様に、List の構築も変わっています。旧来の可変長引数による List[Int](1, 2, 3) は通らず、角括弧のリテラル構文が使えるようになりました。
def main():
var a = [1, 2, 3] # 通る
var b: List[Int] = [1, 2, 3] # 通る
var c = List[Int]([1, 2, 3]) # 通る(リストを1つ渡す形)
print(len(a), len(b), len(c))
List[Int](1, 2, 3) だけが no matching function in initialization で落ちます。Python に寄せた [...] が第一の書き方になった、と理解しておけば移行時に迷いません。
std と max:標準ライブラリが2つのパッケージに割れた
MAX 26.5 のリリースノートは、標準ライブラリの再編について次の趣旨を書いています——GPU プログラミング API の大半を Mojo の標準ライブラリから新しいトップレベルの max パッケージへ移し、std.algorithm は max.algorithm に、std.benchmark は max.benchmark に、std.gpu.{compute,host,memory,sync} は max.gpu.* になり、layout パッケージもそこに含まれる、と。
これを額面どおり「std.* が max.* になった(=旧名は使えなくなった)」と読むと、実測と食い違います。pip install mojo した状態と、さらに pip install max した状態の2つを用意し、同じ import を両方で試した結果が次です。
| モジュール | mojo 単体 |
mojo + max |
|---|---|---|
std.algorithm |
✅ | ✅ |
std.benchmark |
✅ | ✅ |
std.gpu |
✅ | ✅ |
std.math |
✅ | ✅ |
std.complex |
✅ | ✅ |
max.algorithm |
❌ | ✅ |
max.benchmark |
❌ | ✅ |
max.gpu |
❌ | ✅ |
algorithm(旧トップレベル) |
❌ | ✅ |
layout(旧トップレベル) |
❌ | ✅ |
math / memory / collections(旧) |
❌ | ❌ |
max.layout / std.layout |
❌ | ❌ |
読み取れることが3つあります。
・std.* は消えていない。max を入れたあとも std.algorithm は解決できる。リリースノートの「is now」は置き換えではなく、少なくとも 1.0.0 時点では並存である
・max は別パッケージ。pip install mojo だけでは max.* は一切解決できない。GPU 関連を触るなら pip install max が要る
・命名は対称ではない。layout は素の名前で解決するのに max.layout も std.layout も解決しない。逆に math / memory / collections は max を入れても素の名前では解決しない
上の表は「import が通るか」だけを見た結果で、どれが正式な推奨パスなのかは判定していません(未検証)。解決できることと、公式が使ってほしいと考えていることは別です。移行作業を実際に行う場合は、必ず Modular の公式ドキュメントで各モジュールの正規の位置を確認してください。ここで示したのは「リリースノートの記述をそのまま信じると想定と違う結果になる」という事実までです。
max パッケージ自体は requires_python が <3.15,>=3.10 で、cp310 から cp314 まで各 Python バージョン向けのホイールが用意されています(macOS arm64 版あり)。mojo 側がバージョン非依存の py3-none- ホイールなのと対照的で、max は Python 拡張として深く結び付いていることが分かります。
1.0 は何を約束したのか——「fix-it つき」の主張を検証する
1.0 という数字が実務上何を意味するのかは、リリースノート本文に書かれています。要点は2つです。
・標準ライブラリ API の「安定」マーキングを開始した。安定と印を付けたものは、互換性を壊す形で削除・変更されない。ただしまず小さな集合から始め、以降の 1.x で広げていく
・このリリースには通常より多くの破壊的変更がある。名前・既定値・安全性の境界を 1.0 で正すため。ただしほぼすべての破壊的変更には非推奨エイリアスとコンパイラの fix-it が付くので、移行は機械的である
後者の「ほぼすべての破壊的変更に fix-it が付く」という主張は、手元で確かめられます。実際に旧構文を食わせたときのエラーメッセージを並べると、次のようになりました。
| 旧構文 | エラーメッセージ | 移行先の提示 |
|---|---|---|
fn |
'fn' has been removed; use 'def' instead |
✅ あり(def と明示) |
let |
use of unknown declaration 'let' |
❌ なし |
from math import … |
unable to locate module 'math' |
❌ なし(std.math の示唆なし) |
List[Int](1,2,3) |
no matching function in initialization |
❌ なし |
4つのうち移行先を教えてくれたのは fn だけでした。fn は Mojo の看板だっただけに丁寧な案内が用意されていますが、let の削除や標準ライブラリの std. 移動については、メッセージだけを見ても次に何を書けばいいか分かりません。
「移行は機械的」という説明自体は妥当です——置換規則さえ知っていれば作業は単純だからです。ただし規則を知らない状態でエラーメッセージだけを頼りに進めると、fn 以外では止まるというのが実測の結果です。なお、ここで測ったのは4つの構文だけであり、リリース全体の破壊的変更を網羅したわけではありません(未検証)。移行時は公式のマイグレーションガイドを併読してください。
mojo 言語を今から学ぶなら
Mojo 使い方を今から調べる人にとって、以上を踏まえた注意点は明確です。
・日付を見る。2026年8月11日より前の日本語記事は、fn を前提に書かれている可能性が高い。コードは動かないものとして読む
・fn の解説を見たら年代を疑う。「Mojo には def と fn がある」という説明は、1.0 では成立しない
・倍率の数字を鵜呑みにしない。ローンチ期に広まった速度の見出しは特定条件のもの。本記事でも速度は測っていない
・まず pip install mojo で最小の hello world を通す。環境構築の関門は 1.0 でかなり下がった
・GPU を触るなら pip install max も要ることを最初に知っておく
① 何ができる:Python に似た構文でネイティブバイナリを生成し、MAX 経由で GPU まで扱える。② 何を解決する:「Python で書きたいが速度が要る」ときの言語切り替えコスト。③ 何を代替できる:数値計算カーネルを C++/CUDA で書いていた部分。ただし 1.0 到達直後であり、エコシステムの厚みは既存言語に及ばない。
macOS(Apple Silicon / arm64)、Python 3.14.4。
pip install mojo で Mojo 1.0.0 (ed45d567) を導入し、mojo run / mojo build を実行。import の可否は「mojo のみの venv」と「mojo + max の venv」を別々に作り、同一のテストファイルを両方で実行して比較しました。標準エラーに出る Crashpad の警告は判定から除外しています。GPU 関連 API の実動作と性能は未検証です。
まとめ
Mojo 1.0 の要点(すべて実測)
・2026-08-11、MAX 26.5 と同時に Mojo 1.0.0 が公開された
・macOS では pip install mojo だけで導入できる(Apple Silicon 向けホイールあり)。導入の関門は大きく下がった
・fn が削除された。let も削除。既存チュートリアルのコードはほぼ最初の数行で止まる
・標準ライブラリは std.* に整理され、GPU 関連は別パッケージ max へ。両者は並存しており、リリースノートの「is now」を置き換えと読むと実測と食い違う
・mojo build はネイティブ実行ファイル(hello world で 35,912 バイト)を生成し、単体で動く
・速度の検証は本記事では行っていない
言語が 1.0 に到達したというニュースは、それまでの解説がまとめて古くなる瞬間でもあります。mojo 言語 を検索して出てくる日本語記事の大半がまだ fn を教えている現状では、公式ドキュメントを一次情報として読むのが結局は近道です。
参照ソース
・modular/modular(公式リポジトリ) — ★数・リリース時系列・リポジトリ構成
・MAX 26.5 / Mojo 1.0.0 リリース — 標準ライブラリ再編に関するリリースノート本文
・mojo — PyPI — 1.0.0 の配布ホイール(macOS arm64 版の存在確認)
・max — PyPI — max パッケージの Python バージョン対応
・modular/modular のリリース一覧 — ベータ(1.0.0b1 / 1.0.0b2)から正式版までのタグと公開日