Make Hardware Personal GeaStack launched an open-source toolchain that compiles TypeScript, JSX, and CSS into C++ for embedded devices, desktop apps, and consoles, built on the Gea reactive web framework. The stack includes the geatsc TypeScript-to-C++ compiler and the gea CLI for browser previews, native builds, and flashing, and was used to build the ESP32-S3-based CoyoPedal amp and effects processor and to compile Three.js games including Aviator and SkyTail for Xbox and macOS. GeaStack Open source Explore the source ↗ https://github.com/geastack Make hardware personal. We let you write it in TypeScript, JSX, and CSS. GeaStack brings Gea’s reactive UI https://geajs.com/ to devices. Our geatsc compiler https://github.com/geastack/compiler turns supported app code into C++, and the gea CLI https://github.com/geastack/cli handles browser previews, native builds, and flashing. Build with your coding agent → op-agent-label Why GeaStack From a web framework to our own devices. JavaScript is enough. We believed the language already gave us the tools to model an app. Classes keep state and behaviour together, properties hold values, methods change them, and getters calculate derived values. We built Gea https://geajs.com/ for the web around that belief. In Gea, stores are reactive classes. You change their data directly with code like this.count++ or this.users.push user . Components describe the interface in JSX, and CSS handles its appearance. Gea analyses JSX at build time and generates the DOM update code. Its runtime observes state changes and applies those updates, taking the repetitive wiring out of application code. Gea remains an independent web framework, with its own examples and benchmarks https://geajs.com/ . Its apps run as JavaScript in the browser. We wanted to carry that way of writing apps onto our own hardware, which became the starting point for GeaStack. Then we wanted to take it onto a guitar. We play MIDI guitar and wanted a controller we could attach to our guitar to manage sounds while playing. We already had a way of building interfaces that we liked. We wanted to use that same approach on a small device, which meant taking Gea’s application model beyond the browser. That guitar work also led to CoyoPedal https://github.com/dashersw/coyopedal , our open-source ESP32-S3 amp and effects processor. Its GeaStack touchscreen UI runs alongside a dedicated audio engine. You can play the browser version https://coyopedal.playtaurus.com/ or read how we made NAM A2-Full fit on the chip https://playtaurus.com/blog/running-nam-a2-full-natively-on-an-esp32-s3 . The app had to run on a small chip. On an ESP32, memory and processing time are tight. We wanted to keep writing TypeScript, JSX, and CSS while running compiled code on the device. That is where geatsc https://github.com/geastack/compiler , our TypeScript-to-C++ compiler, comes in: it translates supported application code into C++, which the board’s toolchain builds into firmware. We used that path to build touch interfaces and brought familiar web APIs to embedded devices. Some examples are fetch https://geastack.com/docs-tutorials-esp32-04-network-request.html for network requests, Canvas 2D https://geastack.com/docs-concepts-canvas.html for drawing, and localStorage https://geastack.com/docs-concepts-components-and-state.html persisting-state for saving state. From a small screen to native desktop apps. The next step was to bring the same development model to desktop and mobile platforms, so you can use the same codebase across supported targets and compile it natively where a native target is available. Each target supplies the rendering, input, and platform APIs the app needs. On macOS, that includes real AppKit controls https://github.com/geastack/apple . Our Notes demo https://github.com/geastack/examples/tree/main/apps/notes-native uses native views and a toolbar, with application state and interface code written in TypeScript and JSX. Gea still manages the reactive UI; the target connects it to the operating system. Then we took a Three.js game to Xbox. We also wanted to bring browser game development to native targets. We compiled Three.js https://threejs.org/ games for Xbox, including Aviator and SkyTail example-xbox , the game featuring our coyote mascot. The launch walkthrough shows SkyTail running on both Xbox and macOS. The compiler opened another direction: native HTTP services https://github.com/geastack/node-compat . We could compile supported Node-style server code and measure it against the same code running in Node.js. The benchmarks op-bench show throughput, memory, startup, and latency together. Xbox support is experimental and the repo is private. Watch the Xbox and SkyTail walkthrough → example-xbox And we ended up building GeaStack. What started with a guitar controller became a way to build native applications in TypeScript, from an ESP32 to an Xbox. We brought the framework https://github.com/geastack/core , compiler https://github.com/geastack/compiler , and device targets op-targets together as GeaStack, so you can use them to build your own apps. We invite all of you to build cool stuff with it. Our public repositories https://github.com/geastack are open source, each under its own licence https://geastack.com/license.html licences , and we’d love to see your contributions. Share what you’re building in our Discord https://discord.gg/aKNbDU7hW , report an issue, or send a pull request. We believe in PERSONALIZED HARDWARE. Code From app state to native code. With GeaStack, we write the app in TypeScript, JSX, and CSS, then compile it for the device. Store counter-store.ts js import { Store } from '@geastack/core' class CounterStore extends Store { count = 0 increment { this.count = this.count + 1 } } export const counter = new CounterStore We use a Store https://geastack.com/docs-concepts-components-and-state.html reactivecomponent-or-store when several components need the same state. If only App needs the count, we can keep it on the ReactiveComponent https://geastack.com/docs-concepts-components-and-state.html reactivecomponent-or-store itself. Component App.tsx js import { ReactiveComponent } from '@geastack/core' import { counter } from './counter-store' import './styles.css' export class App extends ReactiveComponent { template { return