Write web code.
Ship nativeapps.
Morph compiles .mx files into lightweight native binaries with OpenGL rendering. No browser. No Electron. Under 1 MB.
import { morphState } from 'morph'export default function App() {const [count, setCount] = morphState(0);return (<body><div className="app"><div className="title">Hello, {count}!</div><button onClick={() => setCount(count + 1)}>Increment</button></div></body>);}
Everything you love about the web.
Everything you need for native.
Native Binaries
Compile to standalone native binaries under 1 MB. No browser runtime, no Electron, no WebView — just raw OpenGL.
Full CSS + Tailwind
Write styles with standard CSS or 500+ Tailwind utilities. Flexbox, animations, transforms, transitions — all supported.
Instant Hot Reload
Dev mode watches your files, recompiles only the logic, and hot-swaps it via dlopen. Window never restarts.
JSX + TypeScript
Build UIs with familiar JSX syntax and TypeScript logic. Your JS is translated to C++ at compile time.
C++ Interop
Import C++ functions directly into your JSX. Full access to native libraries with zero-cost FFI.
Dead Code Elimination
Feature-based tree-shaking at compile time. Only link what you use — text, flex, animation, transforms.
From JSX to native.
No runtime required.
.mx Files
JSX + TypeScript + CSS
Parse
Tree-sitter AST
Style
CSS + Tailwind resolve
Layout
Box model + Flexbox
Codegen
C++ via Jinja2
Binary
Native OpenGL app
Dev Mode
File changes trigger incremental recompilation. The IR is sent over a Unix socket to a pre-compiled dev runtime. Only the logic shared library is recompiled and hot-swapped via dlopen — signals and effects are re-wired in place.
Build Mode
Full compilation to a standalone native binary. TypeScript is translated to C++ via tree-sitter. Jinja2 templates emit optimized C++ code with feature-based dead code elimination. Optional UPX compression.
Familiar syntax.
Native power.
import { CSS, morphState } from 'morph'CSS.load("style.css")export const windowConfig = {title: "Counter",width: 400,height: 300,}export default function App() {const [count, setCount] = morphState(0);return (<body><div className="counter"><div className="count">{count}</div><div className="actions"><buttonclassName="btn btn-primary"onClick={() => setCount(count + 1)}>+1</button><buttonclassName="btn btn-secondary"onClick={() => setCount(0)}>Reset</button></div></div></body>);}
One CLI to rule them all.
From scaffolding to production builds, everything you need is one command away.
morph init my-appmorph devmorph buildmorph runmorph build --static --upxmorph doctormorph translate src/logic.tsReady to go native?
Install Morph, scaffold a project, and build your first native app in under a minute.