no-std coap-lite

A lightweight CoAP message manipulation crate, ideal for embedded environments

7 releases

new 0.3.5 Jan 19, 2021
0.3.4 Jan 12, 2021
0.3.2 Dec 6, 2020
0.3.1 Nov 25, 2020
0.1.0 Sep 8, 2019

#33 in Embedded development

Download history 9/week @ 2020-10-01 2/week @ 2020-10-08 4/week @ 2020-10-15 5/week @ 2020-10-22 3/week @ 2020-10-29 5/week @ 2020-11-05 3/week @ 2020-11-12 12/week @ 2020-11-19 22/week @ 2020-11-26 38/week @ 2020-12-03 31/week @ 2020-12-10 12/week @ 2020-12-17 1/week @ 2020-12-24 12/week @ 2020-12-31 64/week @ 2021-01-07 97/week @ 2021-01-14

76 downloads per month
Used in coap




Latest version Documentation License

A lightweight low-level CoAP message manipulation crate.

Its goal is to be compliant with the CoAP standards and to provide a building block for libraries (e.g. coap) and applications.

coap-lite supports #![no_std] and embedded environments.

It was originally based on the improved low-level message handling code from the coap crate as well as rust-async-coap, made to work in bare metal environments.

Supported RFCs


This crate provides several types that can be used to build, modify and encode/decode CoAP messages to/from their byte representation.

Note for no_std users: it does require allocation, so you might have to set a global allocator depending on your target.


The following example uses std::net::UdpSocket to send the UDP packet but you can use anything, e.g. smoltcp for embedded.

use coap_lite::{
    CoapRequest, RequestType as Method
use std::net::{SocketAddr, UdpSocket};

fn main() {
    let mut request: CoapRequest<SocketAddr> = CoapRequest::new();


    let socket = UdpSocket::bind("").unwrap();

    let packet = request.message.to_bytes().unwrap();
    socket.send_to(&packet[..], "").expect("Could not send the data");


use coap_lite::{CoapRequest, Packet};
use std::net::{UdpSocket};

fn main() {
    let socket = UdpSocket::bind("").unwrap();
    let mut buf = [0; 100];
    let (size, src) = socket.recv_from(&mut buf).expect("Didn't receive data");

    println!("Payload {:x?}", &buf[..size]);

    let packet = Packet::from_bytes(&buf[..size]).unwrap();
    let request = CoapRequest::from_packet(packet, src);

    let method = request.get_method().clone();
    let path = request.get_path();

    println!("Received CoAP request '{:?} {}' from {}", method, path, src);

    let mut response = request.response.unwrap();
    response.message.payload = b"OK".to_vec();

    let packet = response.message.to_bytes().unwrap();
    socket.send_to(&packet[..], &src).expect("Could not send the data");

Low-level binary conversion

use coap_lite::{
    CoapOption, MessageClass, MessageType,
    Packet, RequestType, ResponseType,

let mut request = Packet::new();
request.header.message_id = 23839;
request.header.code = MessageClass::Request(RequestType::Get);
request.set_token(vec![0, 0, 57, 116]);
request.add_option(CoapOption::UriHost, b"localhost".to_vec());
request.add_option(CoapOption::UriPath, b"tv1".to_vec());
        0x44, 0x01, 0x5D, 0x1F, 0x00, 0x00, 0x39, 0x74, 0x39, 0x6C, 0x6F,
        0x63, 0x61, 0x6C, 0x68, 0x6F, 0x73, 0x74, 0x83, 0x74, 0x76, 0x31,

let response = Packet::from_bytes(&[
    0x64, 0x45, 0x5D, 0x1F, 0x00, 0x00, 0x39, 0x74, 0xFF, 0x48, 0x65,
    0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21,
assert_eq!(23839, response.header.message_id);
assert_eq!(MessageType::Acknowledgement, response.header.get_type());
assert_eq!([0, 0, 57, 116], response.get_token()[..]);
assert_eq!(b"Hello World!", &response.payload[..]);


Licensed under either of

at your option.

This is a modification of the coap and rust-async-coap crates, their licenses are in LICENSE-3RD-PARTY.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

No runtime deps


  • std