fourchan-rs
Async 4chan JSON API client and type bindings for Rust.
Hits the read-only endpoints and normalizes the responses into typed structs. Async-only, built on reqwest + tokio. Published as fourchan-rs; the library import name is chan.
Features
- Typed bindings for every read-only endpoint: boards, catalog, index pages, thread lists, full threads, and archives.
If-Modified-Sincepolling variants that returnOk(None)on304 Not Modified.- Normalized posts: 4chan mixes post and attachment metadata into one object; chan-rs splits attachments out so
post.attachment.is_some()is the single source of truth. - Attachment helpers for CDN URLs (
url,thumbnail_url) and kind checks (is_image,is_video,is_animated). - Cheap-to-clone
Client(Arc-shared config). Accepts a user-suppliedreqwest::Clientto share connection pools / proxy / TLS config. - No imposed rate limit. Callers stay within 4chan's published limits themselves.
Requirements
- Rust 1.85 or newer.
- A tokio async runtime, re-exported as
chan::tokio(no separate dependency required). - Network access to
a.4cdn.org(API) andi.4cdn.org(attachment CDN). - TLS via rustls, no system OpenSSL needed.
Install
[]
= "0.1"
The tokio runtime is re-exported as chan::tokio, so no separate tokio dependency is needed.
Quick start
async
Endpoints
| Method | API path |
|---|---|
get_boards() |
/boards.json |
get_board_catalog(board) |
/{board}/catalog.json |
get_threads(board) |
/{board}/threads.json |
get_archive(board) |
/{board}/archive.json |
get_index_page(board, page) |
/{board}/{1..=15}.json |
get_full_thread(board, no) |
/{board}/thread/{no}.json |
Conditional (If-Modified-Since) variants: get_threads_if_modified, get_catalog_if_modified, get_full_thread_if_modified. Each takes the previous Last-Modified value and returns Option<Conditional<T>>, None on 304.
A missing board or thread errors with Error::NotFound.
Polling
The previous Last-Modified is fed back in; Ok(None) signals no change, so re-rendering happens only when content actually changes:
let mut since: = None;
loop
Examples
Custom client
let http = builder
.user_agent
.build?;
let client = with_client;
// Or override the API host:
let client = new.with_api_host;
A chan-rs/<version> User-Agent is sent on every request even when the supplied reqwest::Client carries none.