Native apps written in TypeScript and CSS(github.com) |
Native apps written in TypeScript and CSS(github.com) |
https://www.microsoft.com/en-us/research/publication/static-...
Used in Make Code,
https://www.microsoft.com/en-us/research/project/microsoft-m...
One of the biggest complaints I get is about missing documentation on what TypeScript is not supported.
For example, the following is obviously impossible:
const a = eval("...something....");
or even: a: unknown, or a: any.
The rest of it is largely doable. But people want to see what's not supported. Otherwise it's not clear to them what to avoid.We also have limited support for `new Function("...")` via a small evaluator written in C++ that parses and runs the generated body. We mainly built this for Fastify's generated routing functions so it doesn't support classes, asynchronous, destructuring, etc, but conditionals, loops, variable declarations etc work.
There is no "eval" yet, but the same support shape could be added for it too, as the mechanism is already there.
The approaches and the limitations are documented here:
https://github.com/geastack/compiler/blob/main/docs/EVAL.md https://github.com/geastack/compiler/blob/main/docs/DYNAMIC-...
> so it doesn't support classes, asynchronous, destructuring
For users, this general category of problems (not knowing these edges) is the hardest. It's amplified if you pull libs from npm. One of the best ways to test compatibility is to test with non-trivial projects, or existing codebases. For example, one which has helped me a lot is trying to compile Microsoft's typescript-go compiler, after translating it from golang to TypeScript via a separately written tool. Large projects surface a ton of issues.
What I still don't understand (and can't find documentation for) is how Gea defines the portable abstraction boundary.
The targets are radically different: embedded devices, native UI kits, framebuffer-style rendering, and webviews. The docs don't make it clear which Typescript/JS/node/browser semantics are guaranteed. If I write something like `requestAnimationFrame` and `fetch` and `queueMicrotask`, does it work on every target? The lack of caveats in the documentation implies "Yes" but provides no assurance. Where is the compatibility matrix?
Does an application developer mostly stay inside a portable Gea model, or do they need to understand both Gea internals and the target platform to know what will work? If it's the latter, then it's hard to see the advantage of Gea vs just writing a native app.
My impression right now is: potentially VERY interesting, but needs clearer technical documentation about the portability/limitations and convincing real world proof before I can believe it and let myself be excited about it :)
Looking at the compiler repo, it looks like there is just one contributor. So I'm curious, what AI coding tools did you use? Which models? What's your workflow like? (I'm really interested in first hand experience on how models perform on truly difficult projects, not just at drawing pelicans)
> Android Gea apps packaged as a native Android APK, rendered through a WebView
Why webview? No love for android?
In the docs of the repo of their TS to C++ compiler. https://github.com/geastack/compiler
The whole thing is like this
But to be fair, it's late 2026 so it's to be expected now that the vast majority of code and surrounding artifacts are AI generated. It's just a fact of life.
I will keep an eye on this for future use.
The code is on GitHub, for example for the first video that renders a 3D cube with CSS the code is at https://github.com/geastack/examples/tree/main/apps/css-3d-c.... It takes only a couple of CLI commands to get it running. For reference, I'm using a WaveShare ESP32-S3 AMOLED Touch 2.06" device here, but the same code renders on every target Gea compiles for.
[refusing to reword the "it is not X, it is Y" - I'm not an LLM but I don't care that much if you think I am!]
how does it compile js to c++? js is so dynamic it makes me think it either compiles to some kind of bytecode or its a heavily restricted subset of the language.
We should ship a compatibility matrix... at some point we were hoping to report test262 coverage for ECMAScript compliance, but we had to prioritize the release. Of course any of the typical web APIs work, including localStorage, and even so far as the Web Audio API (and we're working on WebRTC to make it cross platform. It's especially interesting to be able to build real-time communication apps, say, on an ESP32-S3, with just the web semantics).
In short, most app code stays inside the portable model. You need to know the target when you use host APIs that are constrained on small devices: blocking I/O, memory limits, file sizes, and of course you can combine it with native code for the target. I'm building a guitar effects processor, for example, where the UI is powered by Gea Stack but all the audio processing happens natively (https://github.com/dashersw/coyopedal).
On AI: yes, it's mostly me plus agents for the compiler. We have a team at Coyotiv that helps with everything else. I use Claude Code with Claude Opus as the main model and Sonnet subagents for parallel work, with a fair bit of Fable. I also combine this with whatever GPT model is available over Codex. During the past 6 months I've started working on the compiler, I've changed several model versions :)
What makes AI perform on a compiler:
Hard gates the agents can't argue with, like a diff gate that names every program whose output changed, plus conformance sweeps, a diary that captures past failures so they don't repeat, and treating a passing exit code as insufficient and the outputs get checked against Node.js behavior and unit tests.
The biggest differentiator for me is, even though I'm a pretty relaxed manager for humans, I'm a heavy micro-manager for AI. I read its thinking tokens and its code live and as soon as I spot something I don't like, I intervene and guide the model to the output I want to see.
It wasn't easy, Gea Stack in total I think burnt more than a million dollars in AI credits, and I've been working on it literally non-stop for 6 months.
And just to clarify, of course, this limitation is only for "eval", not regular TypeScript :)
Most libs from npm compile fine, including Hono, and we are now working on Fastify and MongoDB native driver.
We had an earlier prototype with a full-stack Gea-compiled app with dynamic fallbacks, but I believe we can do better.
And yes, of course, we tried compiling TypeScript compiler to C++ via Gea Stack, but had to deprioritize to get the release out the door.
Regular arrays are dense, but we keep a presence bit for every element so we can identify sparse arrays and differentiate holes from undefined's. And finally, there's no Error.stack support right now.
TLDR; it's 11x slower than Node.js and 23x slower than Gea Stack with Hono. With raw HTTP server, Perry is ~27% faster than Node.js and Gea is 3.5x faster than Perry.
So there's no byte code, and while not every single dynamic language feature has a corresponding static compilation, the base is pretty broad. So much so that Hono, the web framework, with all its dependencies, compile just fine.
It does appear most JS features can be translated to C++, even if at some overhead. Did you encounter any which wasn't straightforward?
There were a lot of hurdles along the way and we solve them as we come across them. Keeping values native when JS uses them dynamically was a challenge. d = new Date(); d.foo = 1 is easy if you box everything, but then it's a slow interpreter (like some other projects in the field). So we had to invent a new mechanism; native types get a side table for extra properties.
Generics and union types were also challenging: one JS generic can need several different C++ layouts.
eval is limited: new Function runs on a small evaluator written in C++, and direct eval isn't supported yet.
There's a broader philosophy of "firmware freedom" that we want to bring to the world. Practically, you should buy hardware for what it is, and run your own firmware on it. E-book readers and unlocked bootloaders in the Android world is doing a pretty good job at this, so we want to contribute to this movement by making the development of such solutions dead simple, both for humans and AI. Incidentally, TypeScript, JSX, and CSS happen to be the languages AI knows best.
So, it's an ambitious project with a real team behind it, with commercialization on the horizon.
Having said that, I personally designed the logo and visual aesthetic and it serves a purpose. We believe in firmware freedom and hardware hackability, just like it was the norm in 70s and 80s. Of course it could have been executed better, but the current form is a specific choice after many iterations and certainly not low-effort. Too bad it reminds people of AI-slop, for an older generation it reminds other things.