Web Standard APIs for Elixir

A protocol-agnostic, Web API-compliant library for Elixir that mirrors the JavaScript Fetch Standard.

Built with a "Dispatcher" architecture, Web provides a unified interface for HTTP, TCP, and connection-string-based protocols while maintaining a zero-buffer, streaming-first approach.

Quick Start (Script / Livebook)

You can try Web immediately without creating a project using Mix.install:

Mix.install([
  {:web, "~> 0.1.0"}
])

# 1. Construct a new Web.URL
url = Web.URL.new("https://api.github.com/search/repositories")

# 2. Modify properties via URLSearchParams
params = 
  Web.URL.search_params(url)
  |> Web.URLSearchParams.set("q", "elixir")
  |> Web.URLSearchParams.append("sort", "stars")

# 3. Apply params back to the URL
url = Web.URL.search(url, Web.URLSearchParams.to_string(params))

# 4. Construct a Web.Request with the URL
request = Web.Request.new(url, 
  method: "GET",
  headers: %{"Accept" => "application/vnd.github.v3+json"}
)

# 5. Send to Web.fetch
{:ok, response} = Web.fetch(request)

IO.puts("Fetching: #{Web.URL.href(url)}")
IO.puts("Status: #{response.status}")

# Stream the body lazily (Zero-Buffer)
# The body is an Elixir Stream yielding chunks as they arrive from the socket
response.body 
|> Stream.take(5) 
|> Enum.each(&IO.write/1)

Key Features

Installation

Add :web to your dependencies in mix.exs:

def deps do
  [
    {:web, "~> 0.1.0"}
  ]
end

Core Components

Request

The Request struct represents a complete I/O operation. It is protocol-agnostic, allowing the same struct to be used for HTTP, TCP, or custom dispatchers.

Response

The result of a successful fetch.

Headers

A case-insensitive, multi-value container for protocol headers.

URL & URLSearchParams

Pure data structs that handle both standard URIs and rclone-style connection strings.

AbortController& AbortSignal

Standardized mechanism for coordinating the cancellation of one or more asynchronous operations.