A few days ago Modular published Translating to Mojo via AI Agents, where Brad walks through using the official modular/skills to translate a CUDA softmax kernel into portable Mojo and to upgrade five community projects to mojo == 1.0.0b1 in a single agent pass. That post answers "can an agent port one well-defined thing to Mojo today?" The answer is yes.
This post answers the next question: how far does that scale? With the same skills, the same 1.0.0b1 compiler, and a few weeks of side-project time, can one developer plus an agent stand up a whole greenfield ecosystem? mobin and its 10 libraries are the result.
I shipped a production pastebin service (HTTP server, WebSocket live feed, SQLite database, JSON serialization, URL routing, gzip compression, etc.) with zero Python in the backend. It is all Mojo. You can try it right now at mobin.fly.dev.
The story is not the pastebin. The story is that to build this one app, I ended up building 10 Mojo libraries and a documentation tool from scratch, all with AI coding agents (and agent skills), as a side project. The whole thing took just a few weeks of tinkering, rather than months of dedicated effort.
This is what Andrej Karpathy recently called Agentic Engineering. From his Jan 26 2026 X post:
I rapidly went from about 80% manual+autocomplete coding and 20% agents in November to 80% agent coding and 20% edits+touchups in December. I really am mostly programming in English now... This is easily the biggest change to my basic coding workflow in ~2 decades of programming and it happened over the course of a few weeks.
That ratio matches my experience. I designed the APIs and made the architecture calls. The agent wrote the FFI bindings, the test suites, and most of the cross-repo upgrade work. Karpathy frames the same shift at Sequoia Ascent 2026 as the move from "vibe coding" (which raises the floor) to "Agentic Engineering" (which raises the ceiling): more discipline, more orchestration, more taste, and a lot less typing.
Chris Lattner makes the same point from the platform side in What the Claude C Compiler reveals about the future of software: AI is moving from code completion to engineering participation, the implementation work is getting automated, and the scarce skills are now architecture, design, and judgment.
This was a deliberate exercise. Mojo 1.0 is here in beta, and I wanted to stress-test the ecosystem on mojo == 1.0.0b1 by building something that touches every layer: networking, persistence, serialization, config, testing, documentation. Mojo can already do much more than people think.
What we built
mobin is a pastebin service. You paste code, get a shareable link, and there is a live feed of new pastes via WebSocket. The backend is a 1.1 MB AOT-compiled Mojo binary running on a free-tier Fly.io shared-cpu-1x 256 MB VM, behind flare's multi-worker reactor (one pthread per CPU core, so one worker on the production VM, N on multi-core hosts), with a middleware stack that does gzip compression and ETag-based 304 caching. App-side latency in fly logs is 1 ms per request.
To build it, I needed libraries that did not exist yet or did not support the exact required features. So I built them:
| Library | What it does | Link |
|---|---|---|
| flare | Full networking stack for Mojo🔥 | github.com/ehsanmok/flare |
| json | High-performance JSON library for Mojo🔥 with GPU acceleration | github.com/ehsanmok/json |
| sqlite | SQLite with ORM support | github.com/ehsanmok/sqlite |
| morph | Reflection-driven serde (JSON, TOML, CSV) | github.com/ehsanmok/morph |
| mozz | Mutation + property-based fuzz testing | github.com/ehsanmok/mozz |
| uuid | UUID v4/v7, SIMD hex | github.com/ehsanmok/uuid |
| tempo | UTC timestamps, durations, ISO 8601 | github.com/ehsanmok/tempo |
| envo | Typed config from env, TOML, CLI | github.com/ehsanmok/envo |
| mojodoc | API docs generator for Mojo packages | github.com/ehsanmok/mojodoc |
| pprint | Reflection-based pretty-printer | github.com/ehsanmok/pprint |
Note: If you’re deeply familiar with Mojo, you might be asking yourself why I didn’t use community libraries like EmberJson for Json or slight for SQLite, two great Mojo community projects. I wanted to both challenge my agent to build what it needed precisely with full feature completeness and also ensure compatibility with the latest mojo versions. I wanted to test our Mojo skills to their limits.
Here is how they fit together:

A few things to notice. There are only 3 compile-time dependency edges between the Mojo libraries: flare depends on json, sqlite depends on morph, envo depends on morph. The leaf nodes (json, morph, uuid, tempo) have zero ecosystem dependencies. They are the foundation, and everything else composes cleanly on top.
mozz (fuzz testing) and mojodoc (documentation) are not runtime dependencies; they are development-time tools that plug into the ecosystem. Even the quality and documentation tooling was built from scratch.
11 projects. One developer designing the APIs and testing approach with AI agents doing the heavy lifting on boilerplate.
How AI agents accelerated everything
I used Cursor with Mojo agent skills throughout the project. The workflow generally followed the usual agentic development:
- I would describe what a library should do, its API surface, the key types, how it should feel to use according to my taste, in plan mode and iterate a couple of times until I was happy with the approach.
- The agent would scaffold the package structure, write the core logic, and generate an initial test suite.
- I would review the API design, adjust naming and signatures, and push back on anything that felt un-Pythonic.
- The agent would fill in edge cases, add more tests, write docstrings.
- Repeat.
Where agents saved the most time: FFI boilerplate. sqlite has ~40 function pointer bindings to libsqlite3. json wraps simdjson's C API and also has a native Mojo CPU backend. uuid calls into the OS random number generator. Writing that code by hand is tedious and error-prone. The agent generated it correctly on the first or second try every time.
Library research was the other big category. Before writing any new library I would point the agent at the prior art and ask for a synthesis. morph's compile-time-reflection serde is a direct port of reflect-cpp's design. flare's middleware, router, typed-extractor, and per-worker SO_REUSEPORT listener shapes converged on what works in actix_web, hyper, and axum on the Rust side, and FastAPI on the Python side. The agent reads design docs faster than I do and surfaces when two libraries disagree on a primitive.
Test generation was another big win. I would describe the behaviour I wanted tested, and the agent would produce 15 to 20 test functions with edge cases I had not thought of. Across the ecosystem, there are hundreds of tests, and the agent wrote most of them.
Cross-repo dependency updates were surprisingly good too. When the time came to bump every library to mojo = "==1.0.0b1", I told the agent: "update all repos to pin mojo 1.0.0b1 according to the changelog, fix any breakage, test, and push." It went through each repo, updated the pin, fixed compilation errors, ran tests, committed, and pushed. The whole bump went through every repo as one mostly-mechanical pass. The pixi-build source-build dependency model below is the other reason that pass was as smooth as it was.
What still needed my judgment: API design. Architecture trade-offs. Debugging compatibility issues across nightly transitions. The agent is good at executing a well-defined plan; the human decides what the plan should be.
API design: adopt from Python's best with Mojo flavour
The guiding principle for every library was: look at the Python API that developers already know and love, then replicate that feel in Mojo. Do not invent new patterns. Mojo gives you systems-level performance, but the call site should read like the Python equivalent. That is how you ease adoption. A Python developer should be able to read Mojo code and immediately know what it does.
The playbook is simple. Before designing any library, I looked at the established Python API for that domain and used it as the blueprint. Mojo makes it easy because so many of its constructs are themselves Pythonic.
Data models: @dataclass becomes @fieldwise_init struct
Python developers define data with @dataclass. mobin's Paste struct uses the same shape:
If you have used @dataclass in Python, the synthesized constructor will look familiar, but @fieldwise_init is narrower than @dataclass by design. It generates only the positional fieldwise __init__ and nothing else (see more details in Mojolang docs).
Flare's flavour: Rust reactor, Python ergonomics
flare is a thread-per-core reactor (kqueue / epoll) with a FastAPI-shaped handler API on top. Three layers, three sets of prior art.
Bottom (reactor). One event loop per worker, no thread per connection, no locks on the hot path. Same shape as tokio and nginx. The default multi-worker mode binds N listeners with SO_REUSEPORT (matches actix_web); FLARE_REUSEPORT_WORKERS=0 switches to a tokio-style shared accept (matches hyper / axum). On the 4-worker bench, flare posts the cleanest p99.99 of the four.
Top (handlers). def handler(req: Request) -> Response, the signature Flask and FastAPI use. Router.get("/path", handler) registers it. from flare.prelude import * pulls Request, Response, Router, HttpServer, ok, ok_json, not_found, bad_request. Hello-world:
Middle (composition). Typed extractors (PathInt["id"], QueryInt, HeaderStr, Form[T], Json[T], Cookies) are struct fields parsed before serve runs; missing or malformed input becomes a sanitized 400. Same model as axum's extractors and FastAPI's typed params. Middleware (Logger, RequestId, CatchPanic, Compress, Conditional, Cors) nests like tower layers, except the chain monomorphises to one direct call sequence per handler with no vtable dispatch. Shared state uses App[S] / State[S], the same shape as actix_web's Data< T> and axum's State < S> .
Transports (WsClient, TcpStream, TlsConnector, UdpSocket) are context managers, so Python's with block runs the cleanup:
mobin uses every layer.
Database: sqlite3 becomes sqlite
Python's sqlite3 module is one of the most widely used APIs in the standard library. The sqlite library mirrors it directly:
Database(":memory:"), execute(), prepare(), parameterized queries with ? placeholders. These are the same patterns every Python developer uses. The ORM layer on top follows the same principle: define a struct, and the library handles table creation and CRUD.
JSON: the json module becomes the json library
Python's json.loads() and json.dumps() are probably the most universally known API in the entire ecosystem. The json library mirrors them exactly:
Same function names, same behavior. load() reads from a file handle, dump() writes to one. A Python developer does not need to learn anything new.
But here is where Mojo's parametric system adds something Python cannot do. The same loads function accepts a compile-time target parameter that selects the parsing backend:
The API surface is identical to Python's json module. The parametric [target=...] is the Mojo flavour: you opt into a faster backend at compile time without changing the call site. Python cannot express this. You would need separate libraries or runtime flags. In Mojo, it is one function with a compile-time switch.
Serialization: Pydantic becomes morph
Pydantic taught Python developers that serialization should be automatic from your model definition. morph does the same thing through compile-time reflection, but across multiple formats from a single struct definition:
One struct, three output formats. No schema definitions, no manual field mapping, no format-specific annotations. morph reflects over struct fields at compile time and generates the serialization code for each format. The mental model is identical to Pydantic's model_dump() and model_validate(), extended across JSON, TOML, and CSV without writing a single adapter.
Fuzz testing: Hypothesis / atheris become mozz
Python developers who use Hypothesis for property-based testing or atheris for mutation fuzzing will recognise mozz immediately:
Mutation fuzzing in one call, just like atheris. Property-based testing with automatic shrinking, just like Hypothesis. Define a property, provide a generator, and mozz minimises failing inputs to the smallest reproducing case.
This is a deliberate strategy, not just a stylistic preference. Mojo's biggest adoption advantage is that Python developers already outnumber every other systems programming community. If your Mojo library feels like the Python library they already use, the learning curve drops to nearly zero. They get the familiar API with compiled performance, SIMD, and comptime underneath. You do not need to sell them on a new paradigm. You just need to show them the same patterns running faster.
Testing
Every library follows the same testing pattern. Tests use std.testing assertions, run against in-memory fixtures, and need no external test runner.
Here is a typical test from mobin:
Database(":memory:") gives each test a fresh SQLite database. No shared state, no cleanup, no fixtures to manage. Tests run in parallel without interfering with each other.
For libraries that handle untrusted input (flare, sqlite), I use mozz for fuzz testing. mozz has two modes.
Mutation fuzzing throws random byte sequences at your parser and checks that it raises cleanly instead of panicking:
Property-based testing generates typed values and verifies invariants:
When a property fails, mozz automatically minimises the failing input to the smallest reproducing case. This caught real bugs in sqlite's text handling and flare's HTTP header parsing.
CI runs on every push via GitHub Actions with Pixi:
Two lines of YAML after checkout. The CI config is identical across all Mojo repos.
Consistent structure across every library
Every library in the ecosystem follows the same layout:
Same CI template everywhere: setup-pixi then pixi run tests, matrix across ubuntu-latest and macos-15. Same testing pattern: std.testing assertions, in-memory fixtures, one def main() entry point per test file.
This consistency matters more than it might seem. When every library works the same way, you can contribute to any of them without learning a new project structure. The AI agent can also work faster because the patterns are predictable.
Pixi as the package manager
If you have ever used uv, then pixi feels like uv++. For PyPI dependencies (added through --pypi) pixi uses uv under the hood, and for Conda packages it uses its own fast Rust solver. It is the right tool for Mojo projects for two specific reasons.
The first is pixi-build, which is the source-build path for Mojo libraries. With preview = ["pixi-build"] enabled, pixi resolves your git-tagged Mojo dependencies through rattler-build, which builds each library from source against the consumer's declared mojo version. There is no Conda channel for Mojo packages and no pre-built .mojopkg to ship. Every library in the graph compiles against the same compiler your project pins, which means two libraries cannot disagree on what Mojo version they were built with. The MLIR-bytecode incompatibility trap that used to haunt early Mojo development is gone in this model.
The second is that pixi.lock pins every transitive dependency to exact builds. Two developers running pixi install get byte-identical environments. Combined with source builds, one declared mojo == 1.0.0b1 flows down through the entire graph reproducibly.
Here is what mobin's actual pixi.toml looks like:
Every dependency is a git ref pointing at a tagged release. flare is the most mature library and sits at v0.7.0 with the multi-worker reactor, middleware, and typed-extractor work; the rest of the ecosystem sits at v0.1.x as smaller, focused libraries. System libraries like openssl, ca-certificates, and zlib still come from Conda channels because they are not Mojo packages, and pixi handles that side fine.
Cold pixi install for the entire mobin project (Mojo compiler, all 8 Mojo deps, system libs) takes under 30 seconds with the source-build pipeline warm. Warm installs are near-instant.
Build on Mojo 1.0.0b1 today
Mojo’s Beta-1 is shipped. The semver promise is real: packages built against 1.0.x will keep working across the 1.x series. The path to Mojo 1.0 post lays out the rest of the story.
The ecosystem needs libraries. When 1.0 ships, projects that already exist become the foundation everyone else builds on. HTTP servers, database bindings, serialization, testing tools, CLI frameworks. All of these should exist, and the window to be early is right now.
I have a belief about this: year one after Mojo 1.0 will look like at least year five after Rust 1.0 if we leverage Agentic Engineering correctly. Rust's ecosystem took years to build because every crate was written by hand. With Agentic Engineering, one developer can ship a well-tested library in days with their own taste, instead of months. I built 10 libraries and a production app in weeks. Multiply that across a community of developers all working the same way and the ecosystem fills out fast.
The approach works for anyone. Pick a gap in the ecosystem. Use Pixi for package management with preview = ["pixi-build"] for source builds. Follow a consistent project structure. Plan first, then write Pythonic APIs. Test with std.testing and mozz. Set up CI with GitHub Actions. Ship it.
All of the code from this project is MIT-licensed and on GitHub:
- mobin: the production pastebin service
- flare: full networking stack for Mojo🔥
- json: high-performance JSON library for Mojo🔥 with GPU acceleration
- sqlite: SQLite FFI plus ORM
- morph: reflection-driven serde
- uuid: UUID v4/v7
- tempo: timestamps and durations
- envo: typed config loading
- pprint: debug pretty-printing
- mozz: fuzz and property testing
- mojodoc: API documentation generator
Karpathy described the December 2025 inflection as the moment agents crossed "some kind of threshold of coherence" and caused a phase shift in software engineering. That is what made all of this possible in weeks, on a fresh 1.0 ecosystem. Fork anything, build on top, and ship something on 1.0.0b1.
Share what you build. The Mojo community lives on the Modular forum: Community Showcase for projects on MAX and Mojo, Mojo for language questions. The ecosystem fills out fastest when the work is in the open.



