Skip to content

Mantou

Native desktop apps in TypeScript, on Bun.

Mantou lets you write desktop apps in TypeScript and TSX, run them on Bun, and show UI that Mantou draws itself on the GPU. It never shows a webview. The main thread never runs app JavaScript and never waits for it. That keeps scrolling, resizing and animation smooth while the app’s JS is busy or paused for garbage collection.

import { Index, Text, View, createSignal, defineStyle, run } from "mantou-ui";
const dot = defineStyle({ width: 28, height: 28, backgroundColor: "#f59e0b" });
function Counter() {
const [count, setCount] = createSignal(0);
return (
<View style={{ flexGrow: 1, padding: 24, gap: 16 }}>
<View style={{ width: 88, height: 44, borderRadius: 8, justifyContent: "center", backgroundColor: "#16a34a" }} onPress={() => setCount((n) => n + 1)}>
<Text style={{ color: "#ffffff", fontWeight: 600, textAlign: "center" }}>+1</Text>
</View>
<Text style={{ fontSize: 32, fontWeight: 700 }}>{count()}</Text>
<View style={{ flexDirection: "row", flexWrap: "wrap", gap: 8 }}>
<Index each={Array.from({ length: count() })}>{() => <View style={dot} />}</Index>
</View>
</View>
);
}
run(() => <Counter />, { title: "Counter" });

This runs today (examples/counter). For something bigger, Mantou Mail is a three-pane mail client built the same way (Text and Mantou Mail).

Early development. The threading model works with a real window on Linux, macOS and Windows. Solid-style JSX, flexbox layout, text, text input, rounded corners and borders, clipping, presses, keys and the wheel work, and so do headless test instances. Images and shadows don’t exist yet. See threading, UI tree, layout and rendering, text and Mantou Mail and text input.