⚠️ This software is very raw, and is not yet suitable for use unless you want to learn the codebase. But it is getting close and PRs are welcome!
Bezy is an open-source cross-platform font editor built with the Bevy game engine, the Rust programming language, and various Linebender Crates like Norad, and Kurbo. It is designed for simplicity, customization, user empowerment, education, and AI-agent assisted programming and type design.

A core design principle of this editor is user empowerment. Bezy aims to be the Emacs of font editors. Users should be able to shape Bezy into a custom editor that perfectly fits their needs and aesthetics, like a calligrapher of the Arabic script making their own pens from simple reeds.
Post v1.0, Bezy will have built-in AI-agent functionality using Font Garden and other models allowing for highly automated AI-assisted workflows without giving up fine-grained control and attention to detail.
UFO is the current default source format.
Bezy is loosely inspired by and ported from Runebender, a previous font editor built with Druid, a data-first Rust-native UI design toolkit. It uses many of the same crates like Norad, and Kurbo.
It is also a spiritual successor to the font editor RoboFont, specifically the RoboFont design principles.
Bezy, like the Rust programming language, is fundamentally about empowerment. We believe typeface designers and editors should be encouraged to understand and modify their tools. The idea behind Bezy is to provide a sturdy framework where everyone can add their own functionalities.
# Follow the on-screen instructions and restart your terminal ``` Or visit https://www.rust-lang.org/tools/install for other platforms
Clone the repository:
bash
git clone https://github.com/eliheuer/bezy.git
cd bezy
Build and run:
bash
cargo run
Bezy can also be built as a WebAssembly (WASM) application to run in web browsers. This is useful for web deployment or sharing your font editor in a browser environment.
wasm32-unknown-unknown targetwasm-server-runner for serving the WASM buildInstall the WASM target (if you haven't already):
bash
rustup target add wasm32-unknown-unknown
Install wasm-server-runner:
bash
cargo install wasm-server-runner
Build and run the WASM version:
Option A: Use the provided build script (recommended):
bash
./build-wasm.sh
Option B: Build manually:
bash
cargo run --target wasm32-unknown-unknown
http://127.0.0.1:1334)--load-ufo support currently)The WASM build is perfect for: - Sharing your work online - Demonstrations and tutorials - Web-based font editing workflows - Deployment to platforms like itch.io
For production deployment to your own domain, see the GitHub Pages Deployment Guide. The repository includes automated GitHub Actions for deploying to GitHub Pages with custom domain support.
Quick deployment steps:
1. Enable GitHub Pages in your repository settings
2. Configure DNS for your domain
3. Push to main branch - deployment is automatic!
Simply running cargo run will start Bezy with a default UFO (Bezy Grotesk Regular Latin/Arabic) and the lowercase a glyph (U+0061).
Bezy supports several command line arguments to customize its behavior:
cargo run -- --load-ufo <PATH_TO_UFO>
Example:
cargo run -- --load-ufo assets/fonts/bezy-grotesk-regular.ufo
To test with a specific Unicode character:
cargo run -- --test-unicode <HEXADECIMAL_CODEPOINT>
Example (displays lowercase 'a'):
cargo run -- --test-unicode 0061
You can combine multiple arguments:
cargo run -- --load-ufo assets/fonts/bezy-grotesk-regular.ufo --test-unicode 0061
This loads the Bezy Grotesk font and displays the lowercase 'a' character.
Enable additional debug information:
cargo run -- --debug
You can also control the logging verbosity using the --log-level option:
cargo run -- --log-level debug # Show debug logs
cargo run -- --log-level info # Show only info logs (default)
cargo run -- --log-level warn # Show only warnings and errors
Bezy comes with a test font called "Bezy Grotesk" located in the assets/fonts directory. This is a UFO font format file that you can use to explore the editor's capabilities.
To explore the font's structure, you can examine the UFO directory:
assets/fonts/bezy-grotesk-regular.ufo/
Many of Bezy's settings can be customized by editing the src/settings.rs file. For example, nudge amounts (2, 8, and 32 units) can be modified to better suit your workflow preferences. This aligns with Bezy's core philosophy of user empowerment and customization.
⚠️ Pre-v1.0 Alpha Notice: In the current pre-release state, many features in Bezy are only accessible via keyboard shortcuts. UI buttons for all features will be implemented before v1.0.
These hotkeys are based on the current implementation in the codebase and may evolve as development continues toward v1.0.
If you're new to Rust and want to contribute to Bezy:
src/lib.rs and src/app.rsBezy features a dynamic toolbar system that makes it incredibly easy to add new editing tools. The system uses Bevy's plugin architecture and requires minimal code changes.
src/ui/toolbars/edit_mode_toolbar/my_tool.rs):
```rust
use bevy::prelude::*;
use crate::ui::toolbars::edit_mode_toolbar::{EditTool, ToolRegistry};pub struct MyTool;
impl EditTool for MyTool { fn id(&self) -> crate::ui::toolbars::edit_mode_toolbar::ToolId { "my_tool" }
fn name(&self) -> &'static str {
"My Tool"
}
fn icon(&self) -> &'static str {
"\u{E019}" // Unicode icon
}
fn default_order(&self) -> i32 {
50 // Lower numbers appear first
}
fn update(&self, commands: &mut Commands) {
// Tool behavior while active
}
}
pub struct MyToolPlugin;
impl Plugin for MyToolPlugin { fn build(&self, app: &mut App) { app.add_systems(Startup, register_my_tool); } }
fn register_my_tool(mut tool_registry: ResMut) { tool_registry.register_tool(Box::new(MyTool)); } ```
Add module declaration to src/ui/toolbars/edit_mode_toolbar/mod.rs:
rust
mod my_tool;
pub use my_tool::MyToolPlugin;
Register the plugin in your app:
rust
app.add_plugins(MyToolPlugin);
That's it! Your tool automatically appears in the toolbar with proper ordering and functionality.
default_order() or ToolOrdering resourceshortcut_key()on_enter() and on_exit() for setup/cleanupFor detailed documentation, see src/ui/toolbars/edit_mode_toolbar/USAGE.md.
Bezy has developer documentation available in the docs/ directory:
Contributions to Bezy are welcome! Here's how you can help:
git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)Join the Bezy community:
We're in the process of setting up additional community channels - check back soon!
This project is licensed under the GPL.
The GNU General Public License is a free, copyleft license for software and other kinds of works.
The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.