Run high-performance Mojo code from Python - three patterns for any environment
Project description
py-run-mojo ๐ฅ
Notebook-agnostic Mojo integration for Python - three patterns for running high-performance Mojo code from any Python environment.
Status: โ Beta - Three working approaches, evolving based on real-world usage
Note: This library works with any Python notebook system (Jupyter, marimo, VSCode, Google Colab) and even standalone Python scripts. It was previously called
mojo-marimo; the new name reflects its notebook-agnostic scopeโsee ROADMAP.md.
Overview
py-run-mojo (formerly mojo-marimo) provides three distinct patterns for executing Mojo code from Python, each with different trade-offs:
- Decorator (
@mojo) - Clean Pythonic syntax with template parameters and caching - Executor (
run_mojo()) - Dynamic execution from strings or files, great for code generation - Extension Module - Compiled
.sofiles for zero-overhead FFI calls (~1000ร faster than subprocess)
Works everywhere: Jupyter notebooks, marimo, VSCode notebooks, Google Colab, IPython REPL, or standalone Python scripts. The core library has no notebook-specific dependencies.
from py_run_mojo import mojo
@mojo
def fibonacci(n: int) -> int:
"""
fn fibonacci(n: Int) -> Int:
if n <= 1:
return n
var prev: Int = 0
var curr: Int = 1
for _ in range(2, n + 1):
var next_val = prev + curr
prev = curr
curr = next_val
return curr
fn main():
print(fibonacci({{n}}))
"""
pass
# Use like normal Python!
result = fibonacci(10)
Why This Exists
Python notebooks are brilliant for exploration, but hit a wall when you need serious performance. Traditional solutionsโrewriting in C/C++, using Numba/JAX, or pure Python optimisationโare either too complex or don't deliver the 10-100ร speedup you need.
The question: What if you could write high-performance Mojo code and run it interactively from Python notebooks with minimal friction?
This matters for:
- Data scientists exploring algorithms that need real performance
- Quant developers prototyping trading strategies or risk models
- ML engineers benchmarking preprocessing pipelines or custom operators
- Educators teaching performance engineering with immediate visual feedback
Features
Current (v0.1.0)
- Three integration patterns (decorator, executor, extension modules)
- Works with any Python environment (Jupyter, marimo, VSCode, IPython, scripts)
- Interactive example notebooks in marimo and Jupyter (
.ipynb) formats - SHA256-based binary caching (
~/.mojo_cache/binaries/) - Pre-compilation validation (catches common syntax errors)
- Cache management utilities (
clear_cache(),cache_stats()) - Monte Carlo and Mandelbrot examples with visualisation
- 44 passing tests (75% coverage)
- Comprehensive documentation + roadmap
Planned
See ROADMAP.md for full details:
- Validate Jupyter compatibility with real-world testing
- Auto-generate extension module boilerplate
- Pattern library for common algorithms
- Enhanced error handling and debugging
- Multiple Mojo version support
- Potential package rename (community feedback requested)
Installation
py-run-mojo supports both uv (recommended) and pixi for environment management.
Prerequisites
None! Mojo is now installed automatically as a Python package dependency.
Option 1: uv (Recommended)
# Clone the repository
git clone https://github.com/databooth/py-run-mojo
cd py-run-mojo
# Install dependencies (includes mojo)
uv sync --extra dev
# Verify setup
uv run python scripts/verify_setup.py
# Launch example notebook
uv run marimo edit notebooks/example_notebook.py
Option 2: pixi
# Clone the repository
git clone https://github.com/databooth/py-run-mojo
cd py-run-mojo
# Install with pixi
pixi install
# Verify setup
pixi run test-setup
# Launch example notebook
pixi run notebook-example
Quick Start
Pattern 1: Decorator (Recommended)
from py_run_mojo import mojo
@mojo
def sum_squares(n: int) -> int:
"""
fn sum_squares(n: Int) -> Int:
var total: Int = 0
for i in range(1, n + 1):
total += i * i
return total
fn main():
print(sum_squares({{n}}))
"""
pass
# Use like normal Python!
result = sum_squares(10) # First call: ~1-2s, subsequent: ~10-50ms
print(result) # 385
Pattern 2: Executor
from py_run_mojo import run_mojo
mojo_code = """
fn compute(n: Int) -> Int:
return n * n
fn main():
print(compute(42))
"""
result = run_mojo(mojo_code) # Or run_mojo("path/to/file.mojo")
print(result) # "1764"
Pattern 3: Extension Module
import mojo.importer # Enables auto-compilation of .mojo โ .so
import monte_carlo_mojo_ext
# Direct FFI call - no subprocess overhead!
x, y, inside, pi_est, error = monte_carlo_mojo_ext.generate_samples(1_000_000)
print(f"ฯ โ {pi_est:.6f} ยฑ {error:.6f}")
See examples/ and notebooks/ for complete working examples.
Usage
Verify Setup
# Using just
just test-setup
# Using uv
uv run python scripts/verify_setup.py
# Using pixi
pixi run test-setup
This checks that mojo is available and tests both approaches.
Interactive Notebooks
# Using just
just notebook-decorator # @mojo decorator examples
just notebook-executor # run_mojo() examples
just benchmark # Performance comparison
# Using uv
uv run marimo edit notebooks/pattern_decorator.py
uv run marimo edit notebooks/pattern_executor.py
uv run marimo edit notebooks/benchmark.py
# Using pixi
pixi run notebook-decorator
pixi run notebook-executor
pixi run benchmark
Command-Line Demos
# Using just
just demo-examples
just demo-decorator
# Using uv
uv run python examples/examples.py
uv run python -m py_run_mojo.decorator
# Using pixi
pixi run demo-examples
pixi run demo-decorator
Performance Comparison
Testing on Apple Silicon (M-series) with fibonacci(10), sum_squares(100), and is_prime(104729):
| Approach | First Call | Subsequent Calls | Use Case |
|---|---|---|---|
| Uncached | ~50-200ms | ~50-200ms | Development, debugging |
| Cached | ~1-2s | ~10-50ms | Repeated execution |
| Decorator | ~1-2s | ~10-50ms | Production, clean code |
Key insights:
- Caching wins for repeated calls: 5-10ร faster after first compilation
- Decorator has zero performance cost: Same speed as explicit caching, better developer experience
- All approaches deliver real Mojo performance: No Python fallbacks or compromises
See the benchmark notebook for detailed comparisons.
Documentation
Project Documentation
- CONTRIBUTING.md - Contribution guidelines
- CHANGELOG.md - Version history
- Implementation Guide - Detailed usage guide
- Technical Summary - Implementation overview
Blog & Announcements
- Blog Post Draft - Long-form explanation
- Modular Forum - Mojo community announcement
- marimo Community - marimo community announcement
- Compiled Languages Integration - How compiled languages work with marimo
Project Structure
py-run-mojo/
โโโ src/
โ โโโ py_run_mojo/ # Core library
โ โโโ executor.py # Cached Mojo execution
โ โโโ decorator.py # @mojo decorator
โ โโโ validator.py # Pre-compilation validation
โ โโโ __init__.py # Package exports
โโโ examples/ # Example implementations
โ โโโ examples.py # Python wrappers (fibonacci, etc.)
โ โโโ examples.mojo # Standalone Mojo code
โ โโโ reference/ # Reference .mojo files
โโโ benchmarks/ # Performance benchmarking
โ โโโ python_baseline.py # Pure Python implementations
โ โโโ mojo_implementations.py # Mojo implementations
โ โโโ python_vs_mojo.py # Python vs Mojo comparison notebook
โ โโโ execution_approaches.py # Execution patterns comparison
โโโ notebooks/ # Interactive marimo notebooks
โ โโโ pattern_decorator.py # @mojo decorator examples
โ โโโ pattern_executor.py # run_mojo() examples
โ โโโ interactive_learning.py # Learning notebook
โ โโโ gpu_puzzles/ # marimo notebooks scaffolding Mojo GPU Puzzles
โโโ scripts/ # Utility scripts
โ โโโ verify_setup.py # Setup verification
โโโ tests/ # Test suite
โโโ docs/ # Documentation
โ โโโ project/ # Project docs (contributing, changelog)
โ โโโ blog_post_draft.md # Blog post
โ โโโ COMPILED_LANGUAGES.md # Compiled language integration
โ โโโ MODULAR_FORUM_ANNOUNCEMENT.md
โ โโโ MARIMO_ANNOUNCEMENT.md
โโโ README.md # This file
Development
Using just (Recommended)
We provide a justfile with common tasks synced across uv and pixi:
# Show all available commands
just --list
# Install dependencies
just install
# Run tests
just test
just test-coverage
# Code quality
just format
just lint
just typecheck
just check # Run all quality checks
# Notebooks
just notebook-decorator
just notebook-executor
just benchmark
# Development
just clean
just clean-mojo-cache
just cache-stats
# CI checks locally
just ci
Using uv
# Install in development mode
uv sync --extra dev
# Run tests
uv run pytest tests/
# Format code
uv run ruff format .
# Lint
uv run ruff check .
# Type check
uv run ty check
Using pixi
# Run tests
pixi run test
# Format code
pixi run format
# Lint
pixi run lint
# Type check
pixi run typecheck
# All quality checks
pixi run check
Why marimo?
marimo is a reactive Python notebook with several advantages:
- Reactive execution: Change a slider, Mojo re-runs automatically
- Pure Python files: Version control friendly (unlike Jupyter JSON)
- Type-safe: Built-in UI elements with proper types
- Reproducible: Dependency graph prevents hidden state bugs
Contributing
Contributions welcome! This is a living experiment, evolving based on real-world usage.
Areas for contribution:
- Additional notebook examples
- Performance profiling on diverse hardware
- Integration with other notebook environments
- Error handling improvements
- Documentation enhancements
Related Projects
- mojo-fireplace - Collection of Python-to-Mojo example projects
- mojo-dotenv - Modern
.envfile parser for Mojo - mojo-toml - TOML parser for Mojo
License
Apache License 2.0 - See LICENSE for details.
About
Created by Michael Booth at DataBooth.
Part of an ongoing exploration of Mojo for real-world data and AI workflows. See the full series at databooth.com.au/posts/mojo.
DataBooth helps medium-sized businesses leverage high-performance computing for data analytics and AI, now offering Mojo-powered services that deliver 10-100ร faster solutions without vendor lock-in.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_run_mojo-0.1.3.tar.gz.
File metadata
- Download URL: py_run_mojo-0.1.3.tar.gz
- Upload date:
- Size: 193.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.16.3 cpython/3.14.0 HTTPX/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
438dd39a799d64603ed6416c6ffa0d2fc56010ee7577af5bd8109e1630feca3f
|
|
| MD5 |
99794a0a53dc4e8eba88a57d7d52eb6c
|
|
| BLAKE2b-256 |
4681b95393c5819a4bf150962f2125a706f6ec2cd53454f5944abf7502013ca9
|
File details
Details for the file py_run_mojo-0.1.3-py3-none-any.whl.
File metadata
- Download URL: py_run_mojo-0.1.3-py3-none-any.whl
- Upload date:
- Size: 17.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.16.3 cpython/3.14.0 HTTPX/0.28.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69ee3b0c949c741f8254448b92fc2d2d7e5a103edb31e8e4c3f737c3c105f11e
|
|
| MD5 |
a62ee3730599952912bbada48a0b2ef8
|
|
| BLAKE2b-256 |
5429fdeef561e98c8d048f2fd6939ee9ec796784635f5531ca9692e9e44ccff4
|