wireform-flatbuffers
wireform-flatbuffers implements Google FlatBuffers,
a zero-copy serialization format designed for game engines, mobile apps, and
real-time inference serving. FlatBuffers lay out tables with vtables that index
field offsets, keeping scalars inline and strings or sub-tables behind indirection.
Use this package when you need to read large buffers without deserializing the
entire message, or when sharing the builder infrastructure with Arrow IPC.
Key features
Section titled “Key features”- Typeclass API via
ToFlatBuffersandFromFlatBufferswith Template Haskell deriving - FlatBuffers IDL parser and codegen from
.fbsschema files - Vtable-based wire layout with inline scalars and offset-indirected collections
- Zero-copy view/reader via
FlatBuffers.Viewfor schema-known access patterns - Shared builder with Arrow IPC for cross-format buffer construction
- QuasiQuoter for inline
[flatbuffers| ... |]schemas
Basic usage
Section titled “Basic usage”Derive instances for your table types, then encode and decode through the value-level codec:
{-# LANGUAGE DerivingStrategies #-}{-# LANGUAGE TemplateHaskell #-}
import FlatBuffers.Decode qualified as FBDimport FlatBuffers.Derive (ToFlatBuffers (..), FromFlatBuffers (..), deriveFlatBuffers, deriveView)import FlatBuffers.Encode qualified as FBEimport FlatBuffers.Parser (parseFlatBuffers)import FlatBuffers.Codec (CompiledSchema, compileSchema)import Data.Int (Int32)import Data.Text (Text)import GHC.Generics (Generic)
data Widget = Widget { widgetName :: !Text , widgetCount :: !Int32 , widgetPrice :: !Double } deriving stock (Show, Eq, Generic)
$(deriveFlatBuffers ''Widget)$(deriveView ''Widget)
widgetSchema :: Either String CompiledSchemawidgetSchema = parseFlatBuffers "table Widget { name:string; count:int; price:double; } root_type Widget;" >>= compileSchema
encodeWidget :: Widget -> Either String ByteStringencodeWidget widget = widgetSchema >>= (\schema -> FBE.encodeWith schema (toFlatBuffers widget))
decodeWidget :: ByteString -> Either String WidgetdecodeWidget bs = do schema <- widgetSchema val <- FBD.decodeWith schema bs fromFlatBuffers val
sample :: Widgetsample = Widget "wireform" 42 2.718
roundTrip :: Either String WidgetroundTrip = encodeWidget sample >>= decodeWidgetDynamic encode/decode require a parsed or compiled schema; values follow declaration order.
decodeWith materializes a typed Value tree and validates references, alignment,
and required fields. Defaults and optional scalar presence come from that schema.
For zero-copy reads on known schemas, use the view layer after encoding:
import FlatBuffers.View (decodeRoot)
readWidget :: ByteString -> Either String WidgetreadWidget = decodeRootGenerate types from .fbs files:
{-# LANGUAGE TemplateHaskell #-}import FlatBuffers.QQ (fbs)
[fbs| table Widget { name:string; count:int; price:double; } root_type Widget;|]wireform-gen flatbuffers -i schema.fbs -o src/Gen/Performance
Section titled “Performance”Schema-directed dynamic encode/decode
Section titled “Schema-directed dynamic encode/decode”| Operation | encode | decode | ratio |
|---|---|---|---|
| Person table | 1222 ns | 185 ns | 0.15x |
| Person[100] vector | 99387 ns | 17627 ns | 0.18x |
Last run 2026-11-06 10:08:02 UTC. GHC 9.10.3, Apple Silicon, criterion 1.6.5. Full Value materialization; compiled schemas reused.
Like Cap’n Proto, FlatBuffers decode is a zero-copy cursor. The decode cost is near-constant because only the root table offset is resolved; field access is lazy pointer arithmetic into the original buffer. Encode is proportional to the number of fields and vector elements.
The chart and table above are regenerated by wireform-stats from wireform-flatbuffers/bench-results/summary/flatbuffers-encode-decode.json — the same source the README chart is built from.
Notable modules
Section titled “Notable modules”| Module | Purpose |
|---|---|
FlatBuffers.Derive | ToFlatBuffers / FromFlatBuffers and deriveFlatBuffers |
FlatBuffers.Encode / FlatBuffers.Decode | High-level encoder and value-tree decoder |
FlatBuffers.View | Zero-copy cursor access for schema-known tables |
FlatBuffers.Reader | Low-level pointer-walking decoder |
FlatBuffers.Builder | Vtable and offset builder |
FlatBuffers.Value | Dynamic untyped Value ADT |
FlatBuffers.Schema / FlatBuffers.Parser | Schema AST and .fbs parser |
FlatBuffers.CodeGen / FlatBuffers.QQ | Haskell codegen and quasiquoter |
FlatBuffers.Registry | Runtime schema registry |