# Asio Project Structure Explained: chriskohlhoff/asio Repository Layout

> Explore the Asio project structure, detailing the include and src directories and understanding its versatile header-only or compiled library build modes.

- Repository: [chriskohlhoff/asio](https://github.com/chriskohlhoff/asio)
- Tags: internals
- Published: 2026-07-16

---

**The Asio project structure organizes a cross-platform C++ networking library into `include/` for header-only public APIs, `src/` for optional compiled implementations, and Autotools/Visual Studio build scripts supporting both header-only and compiled library modes.**

The chriskohlhoff/asio repository provides a comprehensive C++ library for asynchronous I/O operations. Understanding the Asio project structure helps developers choose between header-only integration or compiled library linking. The layout separates public interfaces from platform-specific implementation details while maintaining compatibility across Unix-like systems and Windows.

## Directory Layout and Organization

### Public Headers in `include/`

The `include/` directory contains the complete public API as header-only files. The master header **[`include/asio.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio.hpp)** aggregates the entire interface, allowing single-include usage. All user-visible symbols, including `io_context`, socket types, and timer classes, are declared within this hierarchy. According to the chriskohlhoff/asio source code, this design enables zero-configuration integration for projects that prefer header-only dependencies.

### Implementation Sources in `src/`

The `src/` directory contains minimal compiled sources required when building Asio as a static or shared library. The file **[`src/asio.cpp`](https://github.com/chriskohlhoff/asio/blob/main/src/asio.cpp)** provides the entry point for the library implementation, containing the `io_context` runtime and platform-specific glue code. This directory also houses platform-specific makefiles such as **`src/Makefile.msc`** for Visual Studio and **`src/Makefile.mgw`** for MinGW.

### Build Configuration Files

Root-level configuration files support multiple build workflows:

- **`configure.ac`** – Autoconf script generating the `configure` script for Unix-like builds
- **`Makefile.am`** – Automake description defining library targets, headers, and tests
- **`asio.pc.in`** – Template for pkg-config file generation at install time
- **`asio.manifest`** – Metadata for Boost build system integration

## Core Architectural Components

### io_context and Event Loop

The **`io_context`** class (defined in [`include/asio/io_context.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/io_context.hpp)) serves as the central I/O dispatcher. It owns the event loop, schedules asynchronous work, and provides an executor type (`io_context::executor_type`) for submitting handlers. This component forms the backbone of Asio's asynchronous operation model.

### Executors and Execution Context

Asio's modern execution model resides in the `execution/` sub-namespace (e.g., `execution::blocking`, `execution::relationship`). Executors are lightweight wrappers that submit work to an `io_context` without exposing the underlying implementation details. The **[`include/asio/executor.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/executor.hpp)** header defines these interfaces.

### Networking and Timer Types

All networking primitives—including **`ip::tcp::socket`**, **`ip::udp::socket`**, and acceptors—are implemented as header-only templates depending on `io_context` for event handling. Timer classes such as **`steady_timer`**, **`deadline_timer`**, and **`high_resolution_timer`** (defined in [`include/asio/steady_timer.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/steady_timer.hpp)) implement asynchronous waiting operations.

### Coroutine Support

Modern C++20 coroutine integration is provided through **[`include/asio/awaitable.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/awaitable.hpp)** and **[`include/asio/co_spawn.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/co_spawn.hpp)**. These facilities enable structured concurrency with `co_spawn`, `compose`, and `awaitable` wrapper types, allowing asynchronous code to be written with linear control flow.

## Build System Options

### Header-Only Mode

When the macro **`ASIO_HEADER_ONLY`** is defined, implementation files from `src/impl/*.ipp` are included directly through the headers. This mode requires no compiled library and eliminates the need for linking against `libasio`.

### Compiled Library Mode

Using the Autotools chain (`configure.ac` + `Makefile.am`) or Visual Studio makefiles (`src/Makefile.msc`), users can build static or shared libraries. This approach minimizes binary size in applications linking multiple translation units.

### Continuous Integration

The **`.github/workflows/`** directory contains CI pipelines testing Linux, BSD, and Windows configurations, ensuring cross-platform compatibility for both header-only and compiled modes.

## Implementation Examples

### Basic Timer with io_context

This example demonstrates the fundamental `io_context` and `steady_timer` usage:

```cpp
#include <asio.hpp>
#include <iostream>

int main()
{
  asio::io_context ctx;

  // Create a timer that expires after 1 second.
  asio::steady_timer timer(ctx, std::chrono::seconds(1));

  timer.async_wait([&](const asio::error_code& ec)
  {
    if (!ec)
      std::cout << "Timer expired after 1 second.\n";
  });

  // Run the event loop until there is no more work.
  ctx.run();
}

```

*Key symbols:* `asio::io_context`, `asio::steady_timer`, `async_wait`.  
*Source links:* [`include/asio/io_context.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/io_context.hpp), [`include/asio/steady_timer.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/steady_timer.hpp).

### Asynchronous TCP Echo Server

Using C++20 coroutines with the modern executor API:

```cpp
#include <asio.hpp>
#include <iostream>

using asio::ip::tcp;

asio::awaitable<void> session(tcp::socket sock)
{
  try {
    char data[1024];
    for (;;) {
      std::size_t n = co_await sock.async_read_some(
          asio::buffer(data), asio::use_awaitable);
      co_await asio::async_write(sock,
          asio::buffer(data, n), asio::use_awaitable);
    }
  } catch (std::exception& e) {
    std::cerr << "Session error: " << e.what() << '\n';
  }
}

int main()
{
  asio::io_context ctx;
  tcp::acceptor acceptor(ctx, tcp::endpoint(tcp::v4(), 12345));

  // Spawn a coroutine for each incoming connection.
  for (;;) {
    tcp::socket sock = co_await acceptor.async_accept(asio::use_awaitable);
    asio::co_spawn(ctx, session(std::move(sock)), asio::detached);
  }

  ctx.run();
}

```

*Key symbols:* `asio::awaitable`, `asio::co_spawn`, `asio::detached`, `asio::use_awaitable`.  
*Source links:* [`include/asio/awaitable.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/awaitable.hpp), [`include/asio/co_spawn.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/co_spawn.hpp).

### Explicit Executor Usage

Submitting work through an executor explicitly:

```cpp
#include <asio.hpp>
#include <iostream>

int main()
{
  asio::io_context ctx;
  auto ex = ctx.get_executor();               // executor bound to ctx

  // Submit a plain function.
  asio::post(ex, []{
    std::cout << "Running in the io_context thread.\n";
  });

  ctx.run();
}

```

*Key symbols:* `io_context::get_executor`, `asio::post`.  
*Source links:* [`include/asio/executor.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/executor.hpp), [`include/asio/post.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/post.hpp).

## Summary

- The **Asio project structure** in chriskohlhoff/asio separates public headers (`include/`) from optional compiled sources (`src/`), supporting both header-only and library builds.
- **Autotools** (`configure.ac`, `Makefile.am`) and **Visual Studio** makefiles (`src/Makefile.msc`) provide flexible build options across platforms.
- The **`io_context`** class serves as the central event loop, with executors providing lightweight work submission interfaces.
- **Header-only mode** (activated by `ASIO_HEADER_ONLY`) includes implementation files directly, while compiled mode links against `libasio` for smaller binaries.
- Modern **coroutine support** via `co_spawn` and `awaitable` enables structured asynchronous programming with C++20.

## Frequently Asked Questions

### What is the difference between header-only and compiled library mode in Asio?

Header-only mode, enabled by defining `ASIO_HEADER_ONLY`, includes implementation files directly from `src/impl/*.ipp` into translation units at compile time. This eliminates the need to link against a library but may increase binary size. Compiled library mode builds [`src/asio.cpp`](https://github.com/chriskohlhoff/asio/blob/main/src/asio.cpp) into a static or shared library using the Autotools or Visual Studio makefiles, reducing binary size when multiple translation units use Asio.

### Which file serves as the main entry point for including the entire Asio library?

The file **[`include/asio.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio.hpp)** acts as the master header that aggregates the complete public API. According to the chriskohlhoff/asio source code, this single-include header pulls in all networking, timer, and executor components, making it the canonical entry point for users.

### How does the Asio project structure support cross-platform builds?

The repository provides **`configure.ac`** and **`Makefile.am`** for Unix-like systems using Autotools, while **`src/Makefile.msc`** and **`src/Makefile.mgw`** support Windows builds with Visual Studio and MinGW respectively. Additionally, the `.github/workflows/` directory contains CI configurations that validate builds across Linux, BSD, and Windows platforms.

### What is the role of the `io_context` in the Asio project structure?

The **`io_context`** class, defined in [`include/asio/io_context.hpp`](https://github.com/chriskohlhoff/asio/blob/main/include/asio/io_context.hpp), serves as the central I/O execution context and event loop. It owns the queue of pending asynchronous operations, dispatches completion handlers, and provides an executor type for submitting work. All asynchronous I/O objects such as sockets and timers require an `io_context` reference to operate.