# hyperschema

> Create registries of declarative compact-encoding schemas

Latest version **1.26.1** (published 2026-09-11) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install hyperschema
pnpm add hyperschema
yarn add hyperschema
bun add hyperschema
```

## Health

**Score 65/100 (B)** — status: active.

Positive: esm support; no vulnerabilities; has provenance; recently updated; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 1.26.1 |
| Published | 2026-09-11 |
| First published | 2024-08-29 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Dependencies | 4 |
| Unpacked size | 70.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 17 |
| Author | Holepunch |
| Maintainers | mafintosh |

## Links

- npm: https://www.npmjs.com/package/hyperschema
- Repository: https://github.com/holepunchto/hyperschema
- Homepage: https://github.com/holepunchto/hyperschema#readme
- Issues: https://github.com/holepunchto/hyperschema/issues
- npm.io page: https://npm.io/package/hyperschema

## Dependencies (4)

- [bare-fs](https://npm.io/package/bare-fs.md) ^4.0.1
- [generate-string](https://npm.io/package/generate-string.md) ^1.0.1
- [compact-encoding](https://npm.io/package/compact-encoding.md) ^3.5.0
- [generate-object-property](https://npm.io/package/generate-object-property.md) ^2.0.0

## Recent versions

- 1.26.1 (latest) — 2026-09-11
- 1.26.0 — 2026-09-11
- 1.25.0 — 2026-09-11
- 1.24.0 — 2026-09-09
- 1.23.0 — 2026-09-02
- 1.22.0 — 2026-07-30
- 1.21.0 — 2026-05-05
- 1.20.1 — 2026-02-18
- 1.20.0 — 2026-02-18
- 1.19.1 — 2026-02-09
- 1.19.0 — 2026-01-05
- 1.18.0 — 2025-12-09
- 1.17.1 — 2025-11-06
- 1.17.0 — 2025-10-14
- 1.16.0 — 2025-10-01
- … 60 more at https://npm.io/package/hyperschema/versions

## README

# hyperschema

Create and update declarative/versioned binary encoding definitions.

Hyperschema provides a schema builder and a code generator that's designed to enforce versioning rules across updates. This is particularly useful for P2P systems where different peers will be using different schema versions.

Every schema update produces a corresponding version bump, and due to the append-only rule, you'll always be able to encode/decode an object with a particular schema version.

### Usage

With Hyperschema, you create namespaces and register struct definitions on those namespaces. The `from` function will attept to load an existing schema from an output directory. The `toDisk` function will write a `schema.json` file (for versioning) and a generated encodings file in `index.js`.

```js
const Hyperschema = require('.')

const schema = Hyperschema.from('./schema')
const ns1 = schema.namespace('namespace-1')
ns1.register({
  name: 'basic-struct',
  fields: [
    {
      name: 'id',
      type: 'uint',
      required: true
    },
    {
      name: 'other',
      type: 'uint'
    }
  ]
})

Hyperschema.toDisk(schema)
```

If you want to generate as ESM, simply use `import` instead of `require` above or set the option explictly in `toDisk` like so

```js
Hyperschema.toDisk(schema, { esm: true })
```

`index.js` will contain generated `compact-encoding` definitions. You can then load/use them as follows:

```js
const c = require('compact-encoding')
const { resolveStruct } = require('./schema')

const encoding = resolveStruct('@namespace-1/basic-struct', 1)

// { id: 10, other: 20 }
c.decode(encoding, c.encode(encoding, { id: 10, other: 20 }))
```

You can subsequently update your definition of `@namespace-1/basic-struct`, so long as that update follows append-only rules (i.e. only additional optional fields can be added).

Let's say we perform this update:

```js
ns1.register({
  name: 'basic-struct',
  fields: [
    {
      name: 'id',
      type: 'uint',
      required: true
    },
    {
      name: 'other',
      type: 'uint'
    },
    {
      name: 'another',
      type: 'string'
    }
  ]
})
```

After rebuilding, you'll then be able to encode/decode with different versions of `@namespace-1/basic-struct`:

```js
const encoding1 = resolveStruct('@namespace-1/basic-struct', 1)
const encoding2 = resolveStruct('@namespace-1/basic-struct', 2)

// { id: 10, other: 20, another: null }
c.decode(encoding1, c.encode(encoding1, { id: 10, other: 20, another: 'foo' }))
// { id: 10, other: 20, another: 'foo' }
c.decode(encoding2, c.encode(encoding2, { id: 10, other: 20, another: 'foo' }))
```

### Schema Definition

All struct definitions must take the following form:

```
{
  name: 'struct-name',
  compact?: true|false,
  flagsPosition?: -1,
  fields: [
    {
      name: 'fieldName',
      type: 'uint' || '@namespace/another-type' // either a built-in or a predefined type
    },
    ...
  ]
}
```

#### Struct Definition

- `name`: (required) A string name for you struct
- `fields`: (required) (defined below)
- `compact`: (optional) If true, this struct cannot be extended in the future (if embedded in another struct, will not frame the encoding)
- `flagsPosition`: (optional) The position that the flags for optional fields should be encoded at (default to before first optional field)

#### Struct Field Definitions

- `name`: (required) The name of the field. This should be camel-case.
- `type`: (required) Either a built-in type (i.e. `uint`) or a fully-qualified user-defined type (i.e. `@namespace/another-struct`)
- `required`: (optional - default `false`) Is the field required
- `array`: (optional - default `false`) Is the field an array of values. An array of `bool` is packed into a bitfield: a `uint` length prefix followed by `ceil(length / 8)` bytes, least significant bit first
- `record`: (optional - default `false`) Is the field a record of key/values
- `useDefault`: (optional - default `true`) If there is no value, use a default for the type
- `inline`: (optional) Whether to recursively inline the field using the parent struct's flags bitfield for skipping non-required fields. This can make the encoded size smaller. A field's type must be set as `compact` to be inlined.
- `constant`: (optional) A literal (`bool`, integer, `string` or `null`) that the decoder always emits for this field. A constant field is never encoded, takes no flag bit and adding one does not bump the schema version. Useful for runtime-only properties the caller overwrites after decoding (a seq, a cached value) so the decoded object has a stable shape. Cannot be combined with `required`, `array` or `inline`.

#### Alias Definition

- `name`: (required) The name of the alias.
- `type`: (required) Either a built-in type (i.e. `uint`) or a fully-qualified user-defined type (i.e. `@namespace/another-struct`)

#### Versioned Type Definition

- `name`: (required) The name of the versioned type.
- `versions`: (required) An array of `{ version, type, map }`, where `type` is the struct encoding that version and `map` optionally names an exported function that projects it onto the newest shape.
- `framed`: (optional) When embedded in another struct, length-prefix the encoding for the inner version struct if it is not compact. New types default to `true`. A type loaded from a `schema.json` written before framing existed keeps its unframed layout; set `framed: true` on it to migrate, which changes the bytes it writes.

### API

Hyperschema lets you define structs and aliases. All [`compact-encoding`](https://github.com/holepunchto/compact-encoding) types are available as built-in types.

#### `const schema = Hyperschema.from(json|dir)`

Create a new Hyperschema instance, either from a JSON object or from an output directory path.

#### `Hyperschema.toDisk(schema)`

Persist the generated encodings for a Hyperschema instance (previously loaded with `Hyperschema.from(outputDir)`). If the encodings have changed, the version will be bumped.

#### `const ns = schema.namespace(name)`

Return a new schema namespace. All structs/aliases for this namespace will be registered with the `@name` prefix. You can then reference these structs/aliases in subsequent definitions.

#### `ns.register(definition)`

Register a new schema/alias definition on a namespace, as described in the Schema Definition section above.

### License

Apache 2.0

---
_Source: https://npm.io/package/hyperschema · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
