shamaton/msgpack

easier, faster, but extendable MessagePack Serializer for Golang. / msgpack.org[Go]

Go

186

399 commits

updated Oct 11, 2026

See the code

README

MessagePack for Golang

Go Reference test Go Report Card codecov FOSSA Status

📣 Announcement: time.Time decoding defaults to UTC in v3

Starting with v3.0.0, when decoding MessagePack Timestamp into Go’s time.Time, the default Location will be UTC (previously Local). The instant is unchanged. To keep the old behavior, use SetDecodedTimeAsLocal().

Features

  • Supported types : primitive / array / slice / struct / map / interface{} and time.Time
  • Renaming fields via msgpack:"field_name"
  • Omitting fields via msgpack:"-"
  • Omitting empty fields via msgpack:"field_name,omitempty"
  • Supports extend encoder / decoder (example)
  • Can also Encoding / Decoding struct as array

Installation

Current version is msgpack/v3.

go get -u github.com/shamaton/msgpack/v3

Upgrading from v2

If you are upgrading from v2, please note the time.Time decoding change mentioned in the announcement above. To keep the v2 behavior, use msgpack.SetDecodedTimeAsLocal() after upgrading.

Quick Start

package main

import (
  "github.com/shamaton/msgpack/v3"
  "net/http"
)

type Struct struct {
  String string
}

// simple
func main() {
  v := Struct{String: "msgpack"}

  d, err := msgpack.Marshal(v)
  if err != nil {
    panic(err)
  }
  r := Struct{}
  if err = msgpack.Unmarshal(d, &r); err != nil {
    panic(err)
  }
}

// streaming
func handle(w http.ResponseWriter, r *http.Request) {
  var body Struct
  if err := msgpack.UnmarshalRead(r, &body); err != nil {
    panic(err)
  }
  if err := msgpack.MarshalWrite(w, body); err != nil {
    panic(err)
  }
}

v3: time.Time decoding defaults to UTC

TL;DR: Starting with v3.0.0, when decoding MessagePack Timestamp into Go’s time.Time, the default Location will be UTC (previously Local). The instant is unchanged—only the display/location changes. This avoids host-dependent differences and aligns with common distributed systems practice.

What is changing?

  • Before (v2.x): Decoded time.Time defaults to Local.
  • After (v3.0.0): Decoded time.Time defaults to UTC.

MessagePack’s Timestamp encodes an instant (epoch seconds + nanoseconds) and does not carry timezone info. Your data’s point in time is the same; only time.Time.Location() differs.

Why?

  • Eliminate environment-dependent behavior, such as different hosts showing different local zones.
  • Make “UTC by default” the safe, predictable baseline for logs, APIs, and distributed apps.

Who is affected?

  • Apps that display local time without explicitly converting from UTC.
  • If your code already normalizes to UTC or explicitly sets a location, you’re likely unaffected.

Keep the old behavior (Local)

If you want the v2 behavior on v3:

msgpack.SetDecodedTimeAsLocal()

Or convert after the fact:

var t time.Time
_ = msgpack.Unmarshal(data, &t)
t = t.In(time.Local)

Preview the new behavior on v2 (optional)

You can opt into UTC today on v2.x:

msgpack.SetDecodedTimeAsUTC()

Benchmarks

These results are recorded by msgpack_bench. Our package results show in Shamaton. Prefix ShamatonGen shows another our messagepack serialization library. See also: msgpackgen.

Benchmark Encode

Benchmark Decode

License

This library is under the MIT License. See the LICENSE file for details.

encoder-decoder
go
golang
messagepack-serializer
msgpack
serializer

shamaton/msgpack

easier, faster, but extendable MessagePack Serializer for Golang. / msgpack.org[Go]

Go

186

399 commits

updated Oct 11, 2026

See the code

README

MessagePack for Golang

Go Reference test Go Report Card codecov FOSSA Status

📣 Announcement: time.Time decoding defaults to UTC in v3

Starting with v3.0.0, when decoding MessagePack Timestamp into Go’s time.Time, the default Location will be UTC (previously Local). The instant is unchanged. To keep the old behavior, use SetDecodedTimeAsLocal().

Features

  • Supported types : primitive / array / slice / struct / map / interface{} and time.Time
  • Renaming fields via msgpack:"field_name"
  • Omitting fields via msgpack:"-"
  • Omitting empty fields via msgpack:"field_name,omitempty"
  • Supports extend encoder / decoder (example)
  • Can also Encoding / Decoding struct as array

Installation

Current version is msgpack/v3.

go get -u github.com/shamaton/msgpack/v3

Upgrading from v2

If you are upgrading from v2, please note the time.Time decoding change mentioned in the announcement above. To keep the v2 behavior, use msgpack.SetDecodedTimeAsLocal() after upgrading.

Quick Start

package main

import (
  "github.com/shamaton/msgpack/v3"
  "net/http"
)

type Struct struct {
  String string
}

// simple
func main() {
  v := Struct{String: "msgpack"}

  d, err := msgpack.Marshal(v)
  if err != nil {
    panic(err)
  }
  r := Struct{}
  if err = msgpack.Unmarshal(d, &r); err != nil {
    panic(err)
  }
}

// streaming
func handle(w http.ResponseWriter, r *http.Request) {
  var body Struct
  if err := msgpack.UnmarshalRead(r, &body); err != nil {
    panic(err)
  }
  if err := msgpack.MarshalWrite(w, body); err != nil {
    panic(err)
  }
}

v3: time.Time decoding defaults to UTC

TL;DR: Starting with v3.0.0, when decoding MessagePack Timestamp into Go’s time.Time, the default Location will be UTC (previously Local). The instant is unchanged—only the display/location changes. This avoids host-dependent differences and aligns with common distributed systems practice.

What is changing?

  • Before (v2.x): Decoded time.Time defaults to Local.
  • After (v3.0.0): Decoded time.Time defaults to UTC.

MessagePack’s Timestamp encodes an instant (epoch seconds + nanoseconds) and does not carry timezone info. Your data’s point in time is the same; only time.Time.Location() differs.

Why?

  • Eliminate environment-dependent behavior, such as different hosts showing different local zones.
  • Make “UTC by default” the safe, predictable baseline for logs, APIs, and distributed apps.

Who is affected?

  • Apps that display local time without explicitly converting from UTC.
  • If your code already normalizes to UTC or explicitly sets a location, you’re likely unaffected.

Keep the old behavior (Local)

If you want the v2 behavior on v3:

msgpack.SetDecodedTimeAsLocal()

Or convert after the fact:

var t time.Time
_ = msgpack.Unmarshal(data, &t)
t = t.In(time.Local)

Preview the new behavior on v2 (optional)

You can opt into UTC today on v2.x:

msgpack.SetDecodedTimeAsUTC()

Benchmarks

These results are recorded by msgpack_bench. Our package results show in Shamaton. Prefix ShamatonGen shows another our messagepack serialization library. See also: msgpackgen.

Benchmark Encode

Benchmark Decode

License

This library is under the MIT License. See the LICENSE file for details.

encoder-decoder
go
golang
messagepack-serializer
msgpack
serializer

Project health

Overall

6.9/10

Maintained

10/10

Code review

0/10
OpenSSF Scorecard

Latest release

v2.4.2 · Aug 30, 2026

Releases this year

3

Significant stargazers

Daniel G. Taylor

543 followers · starred Apr 2022

Igor Anić

64 followers · starred Apr 2021

ttys3

241 followers · starred May 2026