edubart/minicoro logo

edubart/minicoro

Free

Single header stackful cross-platform coroutine library in pure C.

FreeFree tier
Type
Open Source

About edubart/minicoro

Minicoro is a single-file library for using asymmetric coroutines in pure C. It provides stackful coroutines with support for nesting (resuming a coroutine from another coroutine), custom allocators, a storage system to pass values between yield and resume, customizable stack sizes, and growable stacks via a virtual memory allocator for low memory footprint. The library is implemented via assembly, ucontext, or fibers, making it cross-platform for Linux, macOS, Windows, Android, iOS, WebAssembly, and more. Designed to work in multithread applications, it is minimal, self-contained, free of external dependencies, and compatible with most C89 compilers. The API is inspired by Lua coroutines and returns proper error codes to aid debugging. It also supports running with Valgrind, AddressSanitizer, and ThreadSanitizer.

Key Features

Stackful asymmetric coroutines
Supports nesting coroutines (resuming a coroutine from another coroutine)
Supports custom allocators
Storage system to allow passing values between yield and resume
Customizable stack size
Supports growable stacks and low memory footprint via virtual memory allocator
Coroutine API design inspired by Lua
Yield across any C function
Made to work in multithread applications
Cross-platform (Windows, Linux, macOS, Android, iOS, WebAssembly, Raspberry Pi, RISC-V)

Pros & Cons

Pros
  • Single header file makes integration simple
  • Cross-platform support via multiple backends (assembly, ucontext, fibers)
  • High performance due to efficient assembly implementation
  • Custom allocator support for fine-grained memory control
  • Growable stack option via virtual memory reduces memory footprint
  • Error-prone API with clear error codes helps debugging
  • Works with common sanitizers (Valgrind, ASan, TSan)
  • Compatible with most C89 compilers for legacy projects
Cons
  • Not recommended for use with C++ exceptions (may not behave as expected)
  • The mco_coro object is not thread safe; requires mutex protection in multithread apps
  • Default stack size is limited (56KB), though adjustable
  • Avoid using thread_local inside coroutine code due to potential pointer caching issues
  • On WebAssembly requires -s ASYNCIFY=1 compilation flag
  • WebAssembly Binaryen asyncify method fails on some toolchains like WASI SDK

Best For

Coroutine backend for programming language runtimes (e.g., Nelua)General-purpose coroutines in C for concurrent programmingAsynchronous task scheduling in embedded systemsGame development for cooperative multitaskingMultithread applications requiring coroutine managementImplementing generators and iterators

FAQ

What platforms are supported by minicoro?
Minicoro supports Android, iOS, Raspberry Pi, Linux, macOS, Windows, WebAssembly, and RISC-V. It uses assembly on supported architectures and falls back to ucontext or fibers.
Is minicoro thread-safe?
The mco_coro object is not thread safe. For multithread applications, you must use a mutex to protect it and compile with a C compiler that supports thread_local.
What is the default stack size?
The default stack size is 56KB, but it can be changed at coroutine creation. Enabling the virtual memory backed allocator expands it to 2040KB.
Can I use minicoro with C++?
C++ exceptions are not recommended with minicoro. If you use RAII (destructors), you must resume the coroutine until it dies to properly execute all destructors.