Sitemap
Jayesh

Jayesh

Software Engineer.

I tried Exact, Expo’s new app framework, and built a calculator in 15 mins from scratch.

5 min read1 day ago

--

Press enter or click to view image in full size

Exact by Expo: A Rust-based cross-platform native app runtime

Exact showed up this week as a preview from Charlie Cheever. It is an app framework written in Rust. You describe the interface once, in a small language called Contract, and the same app runs on the web, macOS, iOS, and Linux.

I used it to build a calculator. The interface is the dark one with a backspace key, round keys, and the expression sitting above the result. One Contract file is the screen. TypeScript holds the arithmetic. That same project ran in the browser and on an iPhone 17 Pro simulator.

The announcement is here: Charlie Cheever on X.
The source code is at github.com/expo/exact.

The Demo is here:

https://x.com/jayesssssh/status/2119851949512384658/video/1

What Exact actually is

An Exact app has two parts.

The view is Contract. It is a short, declarative language: state, actions, and a tree of boxes styled with CSS names. It does not fetch, read files, or run arbitrary code. The compiler turns that file into a compact plan.

The data lives beside it, in TypeScript or Rust. The calculator’s addition, percent, clear, and backspace are a plain TypeScript module. Contract asks it for the next screen, and the answer has to match a shape the view declared.

On the web, that plan becomes one small script that drives the browser’s own DOM. On iOS it is drawn with UIKit. On the Mac it is drawn with AppKit. There is no web view in the native UI, and the app’s JavaScript does not run before the first pixel. The first frame comes from data baked into the plan at build time.

Press enter or click to view image in full size
Contract and TypeScript compile into one plan, then the web, iOS, and macOS each draw it

Exact is pre-1.0. The project says so up front: the API changes daily, and there is no compatibility promise yet.

How this differs from the usual cross-platform app

I spend most of my time in React and React Native, so that is the comparison I kept making.

Get Jayesh’s stories in your inbox

Join Medium for free to get updates from this writer.

The UI is a compiled plan: In React Native, JavaScript describes the tree and a runtime reconciles it onto native views. In Exact, Contract is compiled ahead of time. The native runner executes that plan. The web build is a separate, small runtime over the real DOM, measured by the project at about 20 KB.

Press enter or click to view image in full size
React Native reconciles a JavaScript tree while the app runs. Exact compiles the interface first, and JavaScript only answers data

The language is aimed at agents: Contract is intentionally small. A whole screen fits in a context window. Writes are declared, lists are keyed, and a mistake comes back as a refusal that says what to write instead. I had Cursor build the calculator from the repo’s own guide. The compiler’s errors were specific enough that the next edit was obvious.

Tests are the same script on every platform: A test taps a button by a stable id, advances a virtual clock, and reads the text on screen. I ran those tests in the browser. The same file is what you run against the simulator. The clock belongs to the test, so a passing run does not depend on sleeping until an animation finishes.

What you leave unsaid is the platform’s: Layout names are CSS. A button you do not paint is the system button. I did paint this one, because a calculator has its own colors: charcoal background, gray keys, orange operators. That is a choice the framework allows, and it warns you that a hard-coded color will not follow light and dark mode.

Where the time went

Building the calculator in Cursor took about 15 minutes. Checking the basic behavior, addition, percent, sign, clear, and divide-by-zero, took about 2 minutes.

The first native build is the slow part. Toolchains, the iOS simulator target, and the Swift host all have to exist. Once that was in place, the first simulator build finished in a couple of minutes.

After that, the loop is the thing I noticed. I changed the keypad to match a screenshot, backspace on the top row, a round zero, the expression above the result. The rebuild was installed and showing on the iPhone 17 Pro simulator in about 10 seconds.

Press enter or click to view image in full size
Writing took about 15 minutes, basic tests about 2 minutes, the first simulator build a couple of minutes, and the next UI change about 10 seconds

That matches how the project talks about itself. The README budgets a tenth of a second from an edit to the screen on the web, and a minute or two for a later native build. My 10 seconds was a full simulator relaunch of a UI change, which is the number I would quote.

What I would tell someone trying it

Start on the web. `exact new` makes a standalone app that points at a checkout of the repo. The browser loop is where you find out whether the screen is right. Move to the simulator when the Contract tests pass.

Read the one guide the repo points at, then look up a name when the compiler rejects it. Contract uses the web’s spelling. `font-size`, not `size`. `background-color`, not the `background` shorthand. A number is unquoted. The compiler tells you that directly.

Expect the first hour to be setup. Rust, Bun, and an iOS simulator target were the pieces I had to install. The app work after that was the short part.

Links

--

--

Jayesh
Jayesh
0 followers

Software Engineer.