A 30,000-line Rust GPU engine on Expo, and 120,000 installs without ads

Source: Expo Blog•

A 30,000-line Rust GPU engine on Expo, and 120,000 installs without ads

Doodraw wraps a 30,000-line Rust engine in one Expo app for iPhone, iPad, Android and Windows, and passed 120,000 installs in 180+ countries with no ads.

This is a guest post from Alexis Chân Gridel - co-founder and CEO of Doodraw - an Expo App Award submission. He also runs Écrin Digital, a design and engineering studio building premium websites and mobile apps.

Animating a drawing usually means timelines, keyframes and redrawing the same frame over and over. We wanted the opposite. In Doodraw, you draw a line and it's already alive. The hand-drawn "boiling line" look that animators build frame by frame happens live, inside the brush, so a 10-second doodle turns into something you can post.

We started building Doodraw in May 2026, shipped a first iOS version in August and officially launched in September 2026. By October 19 we had passed 120,000 installs (counted as app first opens), with zero paid ads.

Who we are

I'm Alexis, co-founder and CEO. I build Doodraw: the Rust engine, the app and every release. My co-founder and CMO Elodie Mayade is an illustrator and a content-creator. She shapes how the brushes look and feel, and she runs all our content on Shorts, Reels and TikTok, which is where nearly all our installs come from. I also run Écrin Digital, a design and engineering studio building premium websites and mobile apps, so shipping cross-platform wasn't new. Writing a GPU engine was.

No generative AI was a deliberate choice. Our users are artists, and they want their own hand and their own lines. Doodraw is for illustrators, hobby artists, students and creators posting on Instagram and TikTok, people who used to reach for Procreate's animation tools, FlipaClip, After Effects, or browser toys like WigglyPaint.

Why Expo around a Rust engine

Rewriting everything natively twice wasn't an option for a team of two, and the engine had to be shared anyway, so Rust was the core from day one. The real question was the shell around it. Expo let us to have one codebase for iPhone, iPad and Android while the heavy lifting stays native.

The engine is about 30,000 lines of Rust on wgpu. It compiles to an XCFramework for iOS and native libraries for Android. The canvas is a native view, and Expo drives the tools, layers and UI, talking to the engine through native modules in Swift and Kotlin, including native MP4 export. The app runs on Expo SDK 57 and React Native 0.86 with Expo Router, Reanimated 4, Gesture Handler and React Native Skia.

Keeping native folders out of git

Continuous Native Generation was the key decision. Our ios/ and android/ folders aren't in git. A config plugin called withRustEngine copies the compiled engine and our Swift and Kotlin bridge files at prebuild and wires them into the native projects. If a binary is missing, the plugin stops the build immediately instead of letting Xcode fail half an hour later.

Upgrading Expo means bumping versions and re-running prebuild. We don't merge native projects by hand.

One pipeline, then Android, then Windows

EAS Build and EAS Submit ship both stores from one pipeline. The compiled engine is included in the EAS upload. Android shipped in late August, a few weeks after iOS, with almost no extra build work.

Because the UI is plain Expo, the same screens run on Windows. We export the app for web and run it in a Tauri 2 shell, with the same Rust core compiled to WebAssembly and drawing through WebGPU. The Windows app launched in late September, and nothing in the UI was rewritten for desktop.

OTA updates with the fingerprint policy

We use EAS Update with the fingerprint runtime policy. An update only ships JavaScript changes, and the fingerprint tells us when a change touched native code and needs a store build. We even keep our desktop-only config out of app.json so the iOS and Android fingerprints stay identical.

Our first production update shipped fixes and small UX changes to 1,389 iOS devices with zero failed launches. Now we ship a store build every 2 to 4 weeks (iOS 1.0, 1.1, 1.1.2) and OTA updates several times a week for JS-only changes, like new export options and a "continue your last drawing" card in October.

The numbers

  • 120,000+ installs (app first opens) by October 19, 2026, about two and a half months after the first iOS release, with zero paid ads
  • Users in 180+ countries
  • About two thirds of our iOS downloads are on iPad
  • Our best Short passed 4.6M views, and our videos crossed 14M views across YouTube Shorts, Instagram Reels and TikTok in the last 90 days

You can see what people make on our YouTube channel and on Instagram at @doodraw.app, including the Short with 4.6M+ views.

What's next

Performance improvements on more Android devices, an upgrade to Expo SDK 58, a faster first run (start drawing in one tap and export your first loop), more languages, and new brushes every season.

My Expo wish list: an easier way to ship prebuilt native binaries to EAS builds without re-uploading them every time, and a more official path to desktop. Today we export for web and wrap it in Tauri ourselves.

If you have a native or Rust core and you've been assuming Expo can't hold it, read the config plugins guide and try moving your native glue into a plugin that runs at prebuild. Get Doodraw on the App Store, Google Play or Windows.

What this article says