Coi
A type-safe, component-based language for building reactive WASM web apps.
Install / Use
/learn @coi/CoiREADME
Coi
A modern, component-based language for building reactive web apps.
Type-safe. Fast. WASM-powered.
Components with native performance. Fine-grained reactivity, zero internal GC pauses, tiny bundles.
</div>[!NOTE] Coi is in early development. Things change fast and I want your feedback. Not ready for production, but perfect for experimenting, especially if you want to influence where the language goes.
What You Can Build
Coi is designed for building reactive, interactive web applications:
- Web Apps: Dashboards, admin panels, SPAs with real-time updates
- Canvas Apps: Drawing tools, image editors, animations, or games
- Computation-Heavy Apps: Simulations, data processing, physics engines, where WASM shines
- Content Sites: Blogs, documentation sites, landing pages with dynamic components
Coi gives you composable components, fine-grained reactivity, type safety, and tiny bundle sizes.
Why Coi?
[!IMPORTANT] Coi isn't another JavaScript framework, it's a new language for the web, built from scratch to feel like a component framework but compile to high-performance WebAssembly. You get static types, strict checking, and native-speed execution without the overhead of a heavy JavaScript runtime.
- Bundle Size Matters: In our counter app example, Coi is 40% smaller than Svelte, 72% smaller than Vue, and 88% smaller than React (see benchmarks). Faster downloads, faster startup, better mobile experience.
- Animations & Real-Time Apps: No garbage collection pauses means consistent 60fps animations and responsive interactions. Perfect for dashboards, games, and live data apps.
- Type Safety from Day One: Catch bugs at compile-time, not runtime. Props, state, and platform APIs are fully typed.
- No Virtual DOM: Coi uses a fine-grained reactive system. Instead of "diffing" a virtual tree in JS, the compiler generates direct, surgical DOM updates triggered by WASM logic. This eliminates VDOM overhead and minimizes the work the browser has to do.
- WASM Performance: Computation-heavy features run at native speed. Great for simulations, physics, data processing, and canvas-based apps.
- One Codebase, Multiple Platforms (Roadmap): Web today, native platforms and server-side Coi tomorrow. Full-stack with a single language.
Features
Type System & Safety
- Strict Typing: Compile-time error checking with strongly typed parameters and state.
- Reference Parameters: Pass state by reference with
&for seamless parent-child synchronization. - Move Semantics: Explicit ownership transfer with
:to prevent accidental copying. - Private by Default: Component members are private; use
pubto expose them.
Developer Experience
- Component-Based: Composable, reusable components with props, state, and lifecycle blocks.
- Integrated DOM & Styling: Write HTML elements and scoped CSS directly in components.
- View Control Flow: Declarative
<if>,<else>,<for>tags for conditional rendering and iteration. - Component Lifecycle: Built-in
init {},mount {}, andtick {}blocks for setup and animations. - Type-Safe Platform APIs: Full type safety for Canvas, Storage, Audio, Fetch, and other browser APIs.
- Editor Extensions: Syntax highlighting and completions available for VS Code, Sublime Text, and Zed.
Example
// Type-safe enum
enum Status { Todo, Done }
// Define a data structure
pod Task {
int id;
string text;
Status status;
}
component App {
mut Task[] tasks;
mut int nextId = 0;
init {
tasks.push(Task{nextId++, "Learn Coi", Status::Done});
tasks.push(Task{nextId++, "Build something cool", Status::Todo});
}
def add(string text) : void {
tasks.push(Task{nextId++, text, Status::Todo});
}
def toggle(int id) : void {
for task in tasks {
if (task.id == id) {
task.status = match (task.status) {
Status::Todo => Status::Done;
Status::Done => Status::Todo;
};
}
}
}
style {
.app { padding: 24px; font-family: system-ui; }
.done { text-decoration: line-through; color: #999; }
}
view {
<div class="app">
<h1>Tasks ({tasks.size()})</h1>
<for task in tasks key={task.id}>
<div onclick={toggle(task.id)}>
<if task.status == Status::Done>
<span class="done">{task.text}</span>
<else>
<span>{task.text}</span>
</else>
</if>
</div>
</for>
<button onclick={add("New task")}>Add Task</button>
</div>
}
}
app {
root = App;
title = "Task List";
description = "A task management app built with Coi";
}
Benchmarks
In benchmarks comparing Coi, React, Vue, and Svelte, Coi delivers the smallest bundle size and competitive DOM performance. See the results below:
<p align="center"> <img src="https://github.com/coi/benchmarks/blob/main/suites/framework/results/benchmark_results.svg" alt="Benchmark Results" width="600"> </p>Quick Start
Install
Prerequisites:
- Clang 16+ (required for full C++20 support)
- Ubuntu/Debian:
sudo apt install clang-16 - macOS:
brew install llvm lld - Fedora:
sudo dnf install clang
- Ubuntu/Debian:
git clone https://github.com/coi/coi.git
cd coi
./build.sh
Create a Project
coi init my-app
cd my-app
coi dev
Open http://localhost:8000 in your browser.
[!NOTE] Coi has a built-in package manager for installing community packages from the Coi Registry. See Package Manager.
CLI Commands
| Command | Description |
|---------|-------------|
| coi init [name] | Create a new app project |
| coi init [name] --pkg | Create a new package |
| coi build | Build the project |
| coi dev | Build and start dev server (with hot reload) |
| coi dev --no-watch | Dev server without hot reload |
| coi add <package> [version] | Add latest compatible release or a specific version |
| coi install | Install packages from coi.lock |
| coi remove <package> | Remove a package |
| coi upgrade [package] | Upgrade package(s) to latest |
| coi self-upgrade | Pull latest Coi source and rebuild compiler |
| coi list | List installed packages |
| coi version | Show the Coi compiler version |
| coi <file.coi> --out <dir> | Compile a single file |
Project Structure
my-app/
├── assets/
│ └── images/
├── src/
│ ├── App.coi # Entry point (required)
│ ├── layout/
│ │ ├── Footer.coi
│ │ └── NavBar.coi
│ ├── pages/
│ │ ├── About.coi
│ │ └── Home.coi
│ └── ui/
│ └── Button.coi
├── styles/
│ └── reset.css
├── dist/ # Build output
└── README.md
src/App.coi— The compiler always looks for this as the entry point.assets/— Automatically copied todist/assets/on build.styles/— CSS files here are bundled intoapp.css.
Documentation
- Getting Started: Installation, first project, imports
- Language Guide: Types, enums, control flow, operators
- Components: State, lifecycle, props, references
- View Syntax: JSX-like templates,
<if>,<for>, events - Styling: Scoped and global CSS
- Platform APIs: Canvas, Storage, Audio, Fetch, and more
- Package Manager: Registry packages, lockfile workflow, add/install/update/remove
- Versioning: Pond & Drop compatibility model and release philosophy
- Editor Support: VS Code, Sublime Text, and Zed extensions
Community
Join the Coi community on Discord to get help, share projects, and discuss the language:
Editor Support
Coi has syntax highlighting and language support for VS Code, Sublime Text, and Zed.
See the Editor Support & Tooling documentation for installation instructions and features.
