Ebitengine — A Dead Simple 2D Game Engine for Go
Ebitengine is a simple 2D game library for Go with a tiny API that takes minutes to learn. It compiles to WASM, iOS, Android, Nintendo Switch, and desktop — ideal for game jams and indie titles written in Go.
What it is
Ebitengine (formerly Ebiten) is a 2D game library for the Go programming language created by Hajime Hoshi. It offers a tiny API surface that takes minutes to learn. The engine handles rendering, input, audio, and window management while compiling to desktop (Windows, macOS, Linux), mobile (iOS, Android), WebAssembly, and Nintendo Switch.
Ebitengine is ideal for game jams, indie titles, and educational projects where developers want Go's simplicity and type safety without the complexity of larger engines.
How it saves time or tokens
Ebitengine's API consists of three methods: Update(), Draw(), and Layout(). There is no entity-component system to learn, no scene graph to configure, and no editor to install. You write standard Go code, run go build, and get a working game. Cross-compilation to WASM or mobile requires only a build flag change, not a separate toolchain.
How to use
- Initialize a Go module and install Ebitengine.
- Implement the three-method
Gameinterface. - Run with
go run .for immediate feedback.
go mod init mygame
go get github.com/hajimehoshi/ebiten/v2
go run .
Example
A complete Ebitengine program that opens a window and renders text:
package main
import (
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
"log"
)
type Game struct{}
func (g *Game) Update() error { return nil }
func (g *Game) Draw(screen *ebiten.Image) {
ebitenutil.DebugPrint(screen, "Hello, Ebitengine!")
}
func (g *Game) Layout(ow, oh int) (int, int) { return 320, 240 }
func main() {
ebiten.SetWindowSize(640, 480)
ebiten.SetWindowTitle("Hello")
if err := ebiten.RunGame(&Game{}); err != nil {
log.Fatal(err)
}
}
Related on TokRepo
- AI Tools for Coding — Developer tools that complement game development workflows
- Featured Workflows — Discover more popular open-source tools and frameworks
Common pitfalls
- Ebitengine is 2D only. There is no 3D rendering support. For 3D games in Go, consider G3N or Raylib Go bindings.
- Audio playback requires careful sample rate management. Mixing audio sources at different sample rates causes distortion.
- WASM builds need a specific HTML wrapper file. The Ebitengine docs provide a template, but missing it causes a blank browser page.
Frequently Asked Questions
Ebitengine compiles to Windows, macOS, Linux, iOS, Android, WebAssembly, and Nintendo Switch. Desktop and WASM builds work out of the box with standard Go tooling. Mobile builds use gomobile. Nintendo Switch requires the licensed SDK.
Yes. Ebitengine is Apache 2.0 licensed and has been used in published indie games. Performance is sufficient for 2D games with hundreds of sprites, particle effects, and real-time audio. It handles 60fps consistently on modern hardware.
Ebitengine is a code-only library, not a full engine with an editor. It has no visual scene editor, no asset pipeline, and no built-in physics. It trades features for simplicity. Developers who prefer writing all game logic in code and want Go's compile-time safety will prefer Ebitengine.
Yes. Ebitengine supports custom shaders written in Kage, a GLSL-like shading language designed for the engine. Kage shaders compile to the appropriate backend (OpenGL, Metal, DirectX, WebGL) automatically.
No built-in physics engine. You can integrate third-party Go physics libraries like cp (Chipmunk2D bindings) or write simple collision detection yourself. Many 2D games only need AABB or circle collision, which is straightforward to implement.
Citations (3)
- Ebitengine GitHub— Ebitengine 2D game library for Go
- Ebitengine Official Site— Ebitengine API documentation and tutorials
- Ebitengine Shader Docs— Kage shader language for Ebitengine
Related on TokRepo
Discussion
Related Assets
NAPI-RS — Build Node.js Native Addons in Rust
Write high-performance Node.js native modules in Rust with automatic TypeScript type generation and cross-platform prebuilt binaries.
Mamba — Fast Cross-Platform Package Manager
A drop-in conda replacement written in C++ that resolves environments in seconds instead of minutes.
Plasmo — The Browser Extension Framework
Build, test, and publish browser extensions for Chrome, Firefox, and Edge using React or Vue with hot-reload and automatic manifest generation.