PHPackages                             inodrahq/bcs - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. inodrahq/bcs

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

inodrahq/bcs
============

A PHP implementation of BCS (Binary Canonical Serialization) — the serialization format used by Sui, Aptos, and other Move-based blockchains

v1.0.0(3mo ago)0151MITPHPPHP &gt;=8.2CI passing

Since Mar 10Pushed 3mo agoCompare

[ Source](https://github.com/inodrahq/php-bcs)[ Packagist](https://packagist.org/packages/inodrahq/bcs)[ Docs](https://github.com/inodrahq/php-bcs)[ RSS](/packages/inodrahq-bcs/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (1)Dependencies (2)Versions (2)Used By (1)

PHP BCS
=======

[](#php-bcs)

A PHP implementation of [Binary Canonical Serialization (BCS)](https://github.com/zefchain/bcs) — the serialization format used by Sui, Aptos, and other Move-based blockchains.

Requirements
------------

[](#requirements)

- PHP 8.2+
- ext-bcmath

Installation
------------

[](#installation)

```
composer require inodrahq/bcs
```

Quick Start
-----------

[](#quick-start)

```
use Inodrahq\Bcs\Encoder;
use Inodrahq\Bcs\Decoder;
use Inodrahq\Bcs\U64;
use Inodrahq\Bcs\BcsString;
use Inodrahq\Bcs\Vector;
use Inodrahq\Bcs\Boolean;

// Encode a u64
$encoder = new Encoder();
(new U64(1000000))->encode($encoder);
$bytes = $encoder->getBytes(); // raw BCS bytes

// Decode it back
$decoder = new Decoder($bytes);
$value = U64::decode($decoder);
echo $value->getValue(); // "1000000"

// Encode a string
$encoder = new Encoder();
(new BcsString('hello'))->encode($encoder);

// Encode a vector of u64s
$encoder = new Encoder();
$vec = new Vector(U64::class, [new U64(1), new U64(2), new U64(3)]);
$vec->encode($encoder);
```

Supported Types
---------------

[](#supported-types)

BCS TypePHP ClassDescription`bool``Boolean`True/false`u8``U8`Unsigned 8-bit integer`u16``U16`Unsigned 16-bit little-endian`u32``U32`Unsigned 32-bit little-endian`u64``U64`Unsigned 64-bit little-endian`u128``U128`Unsigned 128-bit little-endian`u256``U256`Unsigned 256-bit little-endian`i8``I8`Signed 8-bit integer`i16``I16`Signed 16-bit little-endian`i32``I32`Signed 32-bit little-endian`i64``I64`Signed 64-bit little-endian`i128``I128`Signed 128-bit little-endian`bytes``Bytes`Fixed-length byte array`string``BcsString`ULEB128-prefixed UTF-8 string`vector``Vector`ULEB128-prefixed sequence`option``Option`0x00 (None) or 0x01 + value (Some)`map``Map`Sorted key-value pairs`struct``Struct`Ordered named fields`enum``Enum`ULEB128 variant index + data`tuple``Tuple`Ordered unnamed fields`fixed_array``FixedArray`Fixed-length array (no length prefix)`byte_vector``ByteVector`ULEB128-prefixed raw bytesAdvanced Usage
--------------

[](#advanced-usage)

### Structs

[](#structs)

```
use Inodrahq\Bcs\Struct;
use Inodrahq\Bcs\U64;
use Inodrahq\Bcs\BcsString;

// Define and encode a struct
$struct = new Struct([
    'name' => new BcsString('Alice'),
    'balance' => new U64(1000),
]);

$encoder = new Encoder();
$struct->encode($encoder);
```

### Enums

[](#enums)

```
use Inodrahq\Bcs\Enum;
use Inodrahq\Bcs\U64;
use Inodrahq\Bcs\BcsString;

// Variant 0 with a string payload
$enum = new Enum(0, new BcsString('hello'));

// Variant 1 with a u64 payload
$enum = new Enum(1, new U64(42));
```

### Options

[](#options)

```
use Inodrahq\Bcs\Option;
use Inodrahq\Bcs\U64;

$some = Option::some(new U64(42));
$none = Option::none();
```

### Maps

[](#maps)

```
use Inodrahq\Bcs\Map;
use Inodrahq\Bcs\BcsString;
use Inodrahq\Bcs\U64;

$map = new Map(BcsString::class, U64::class, [
    [new BcsString('alice'), new U64(100)],
    [new BcsString('bob'), new U64(200)],
]);
```

### Tuples

[](#tuples)

```
use Inodrahq\Bcs\Tuple;
use Inodrahq\Bcs\U64;
use Inodrahq\Bcs\BcsString;

// Heterogeneous ordered collection
$tuple = new Tuple([U64::class, BcsString::class], [new U64(42), new BcsString('hello')]);
$encoder = new Encoder();
$tuple->encode($encoder);

// Decode with type context
$decoder = new Decoder($encoder->getBytes());
$decoded = Tuple::decodeWithTypes($decoder, [U64::class, BcsString::class]);
echo $decoded->get(0)->getValue(); // "42"
echo $decoded->get(1)->getValue(); // "hello"
```

### Fixed Arrays

[](#fixed-arrays)

```
use Inodrahq\Bcs\FixedArray;
use Inodrahq\Bcs\U8;

// Fixed-size array (no length prefix, unlike Vector)
$arr = new FixedArray(U8::class, [new U8(1), new U8(2), new U8(3)], 3);
$encoder = new Encoder();
$arr->encode($encoder);

// Decode with known size
$decoder = new Decoder($encoder->getBytes());
$decoded = FixedArray::decodeWithType($decoder, U8::class, 3);
```

### Decoding

[](#decoding)

All container types require type context for decoding:

```
use Inodrahq\Bcs\Decoder;
use Inodrahq\Bcs\Vector;
use Inodrahq\Bcs\Struct;
use Inodrahq\Bcs\Enum;
use Inodrahq\Bcs\Option;
use Inodrahq\Bcs\Map;

// Decode from hex
$decoder = Decoder::fromHex('03010203');
$vec = Vector::decodeWithType($decoder, U8::class);

// Struct decoding (fields must match encoding order)
$decoder = new Decoder($bytes);
$struct = Struct::decodeWithTypes($decoder, [
    'name' => BcsString::class,
    'balance' => U64::class,
]);
echo $struct->getField('name')->getValue();

// Enum decoding (map variant tag => type class, null for no data)
$decoder = new Decoder($bytes);
$enum = Enum::decodeWithVariants($decoder, [
    0 => BcsString::class, // variant 0 has a string
    1 => U64::class,       // variant 1 has a u64
    2 => null,             // variant 2 has no data
]);

// Option decoding
$decoder = new Decoder($bytes);
$opt = Option::decodeWithType($decoder, U64::class);
if ($opt->isSome()) {
    echo $opt->getValue()->getValue();
}

// Map decoding
$decoder = new Decoder($bytes);
$map = Map::decodeWithTypes($decoder, BcsString::class, U64::class);
```

### Custom Types

[](#custom-types)

Implement the `BcsType` interface:

```
use Inodrahq\Bcs\BcsType;
use Inodrahq\Bcs\Encoder;
use Inodrahq\Bcs\Decoder;

class MyType implements BcsType
{
    public function encode(Encoder $encoder): void
    {
        // Write your bytes
    }

    public static function decode(Decoder $decoder): static
    {
        // Read and return
    }
}
```

Hex Helpers
-----------

[](#hex-helpers)

All encoded types support hex output via the Encoder:

```
$encoder = new Encoder();
(new U64(255))->encode($encoder);
echo bin2hex($encoder->getBytes()); // "ff00000000000000"
```

Testing
-------

[](#testing)

```
composer test
```

228 tests verified against golden vectors generated by the Rust `bcs` crate.

License
-------

[](#license)

MIT

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance80

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

106d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/15949934?v=4)[Dimitris Frangiadakis](/maintainers/mitsosf)[@mitsosf](https://github.com/mitsosf)

---

Top Contributors

[![mitsosf](https://avatars.githubusercontent.com/u/15949934?v=4)](https://github.com/mitsosf "mitsosf (1 commits)")

---

Tags

serializationblockchainmovebcssuibinary-canonical-serializationaptos

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/inodrahq-bcs/health.svg)

```
[![Health](https://phpackages.com/badges/inodrahq-bcs/health.svg)](https://phpackages.com/packages/inodrahq-bcs)
```

###  Alternatives

[opis/closure

A library that can be used to serialize closures (anonymous functions) and arbitrary data.

2.6k233.3M314](/packages/opis-closure)[jms/serializer

Library for (de-)serializing data of any complexity; supports XML, and JSON.

2.3k139.8M905](/packages/jms-serializer)[jms/serializer-bundle

Allows you to easily serialize, and deserialize data of any complexity

1.8k91.4M664](/packages/jms-serializer-bundle)[google/flatbuffers

FlatBuffers for PHP

26.1k144.0k5](/packages/google-flatbuffers)[apache/avro

Apache Avro™ is a data serialization system.

3.3k50.6k3](/packages/apache-avro)[flix-tech/avro-serde-php

A library to serialize and deserialize Avro records making use of the confluent schema registry

674.1M19](/packages/flix-tech-avro-serde-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
