https://github.com/ipld/js-ipld-schema
IPLD Schema Implementation: parser and utilities
https://github.com/ipld/js-ipld-schema
Last synced: 4 months ago
JSON representation
IPLD Schema Implementation: parser and utilities
- Host: GitHub
- URL: https://github.com/ipld/js-ipld-schema
- Owner: ipld
- Created: 2019-04-30T06:18:02.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2026-01-23T00:31:59.000Z (5 months ago)
- Last Synced: 2026-01-23T18:26:50.108Z (5 months ago)
- Language: JavaScript
- Homepage:
- Size: 633 KB
- Stars: 16
- Watchers: 16
- Forks: 5
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# @ipld/schema
JavaScript [IPLD](http://ipld.io/) Schema parser, validator, and code generator.
## What are IPLD Schemas?
IPLD Schemas define a type system for content-addressed data. Think of them like TypeScript or Protocol Buffers, but designed for immutable, linked data structures. They help you:
- 🛡️ **Validate** that your data matches an expected structure
- 🔄 **Transform** between compact binary formats and developer-friendly JSON
- 🏗️ **Generate** type-safe code in multiple languages (Go, Rust, TypeScript)
- 🔗 **Link** between data structures using content identifiers (CIDs)
Learn more at https://ipld.io/docs/schemas/
## Features
- **Parse and validate** IPLD Schema DSL (Domain Specific Language)
- **Runtime validation** with automatic format conversion
- **Code generation** for Go, Rust, and TypeScript
- **Advanced type features**: optional fields, defaults, renames, type aliases
- **Multiple data representations** for space-efficient storage
- **CLI tools** for validation and code generation
## Installation
```bash
npm install @ipld/schema
```
For CLI usage:
```bash
npm install -g @ipld/schema
```
## Quick Start
### Basic Schema Definition
IPLD Schemas use a simple, readable syntax:
```js
import { fromDSL } from '@ipld/schema/from-dsl.js'
import { create } from '@ipld/schema/typed.js'
// Define your schema
const schema = fromDSL(`
# A simple user profile schema
type UserProfile struct {
username String
email String
age Int
isActive Bool
}
`)
// Create a validator
const validator = create(schema, 'UserProfile')
// Validate some data
const userData = {
username: 'alice',
email: 'alice@example.com',
age: 25,
isActive: true
}
const validatedData = validator.toTyped(userData)
if (validatedData === undefined) {
console.error('Invalid data!')
} else {
console.log('Valid user profile:', validatedData)
}
```
## Schema Language Basics
### Basic Types
```ipldsch
type MyString String # UTF-8 string
type MyInt Int # Signed integer
type MyFloat Float # Floating point
type MyBool Bool # Boolean
type MyBytes Bytes # Binary data
type MyLink &Any # IPLD Link (CID)
```
### Structs (Objects)
```ipldsch
type Person struct {
name String
age Int
email String optional # Optional field
nickname String (implicit "") # Default value
}
```
### Lists and Maps
```ipldsch
# List of strings
type Names [String]
# Map from string to integers
type Scores {String: Int}
# Nested structures
type Team struct {
name String
members [Person]
metadata {String: String}
}
```
### Enums
```ipldsch
type Status enum {
| Active
| Inactive
| Pending
}
# With custom string values
type Color enum {
| Red ("red")
| Green ("green")
| Blue ("blue")
} representation string
```
### Type Aliases
```ipldsch
type UserID = String
type Timestamp = Int
type EmailAddress = String
```
## Data Representations
IPLD Schemas separate the logical structure (what developers work with) from the storage format (how it's encoded). This allows for space-efficient storage while maintaining developer-friendly APIs.
### Example: Tuple Representation
```js
import { fromDSL } from '@ipld/schema/from-dsl.js'
import { create } from '@ipld/schema/typed.js'
const schema = fromDSL(`
# Store as array instead of object to save space
type Point struct {
x Float
y Float
} representation tuple
`)
const validator = create(schema, 'Point')
// Work with nice objects in your code
const point = { x: 10.5, y: 20.3 }
// But it's stored as a compact array
const stored = validator.toRepresentation(point)
console.log(stored) // [10.5, 20.3]
// And automatically converted back
const restored = validator.toTyped(stored)
console.log(restored) // { x: 10.5, y: 20.3 }
```
## Code Generation
Generate type-safe code from your schemas:
### Go
```js
import { fromDSL } from '@ipld/schema/from-dsl.js'
import { generateGo } from '@ipld/schema/gen/go.js'
const schema = fromDSL(`
type Person struct {
name String
age Int optional
}
`)
const goCode = generateGo(schema, { packageName: 'person' })
// Generates Go structs with proper JSON tags and pointer types for optionals
```
### Rust
```js
import { generateRust } from '@ipld/schema/gen/rust.js'
const rustCode = generateRust(schema)
// Generates Rust structs with serde derives and Option for optionals
```
### TypeScript
```js
import { generateTypeScript } from '@ipld/schema/gen/typescript.js'
const tsCode = generateTypeScript(schema)
// Generates TypeScript interfaces and runtime validators
```
## Advanced Features
### Field Renames
Control JSON field names separately from your schema field names:
```ipldsch
type ServerConfig struct {
serverPort Int (rename "server_port")
debugMode Bool (rename "debug_mode")
apiKey String (rename "api_key")
}
```
### Annotations
Add language-specific type information:
```ipldsch
# Use big integers in Go
# @gotype(big.Int)
type Balance Int
type Transaction struct {
# Custom serialization in Rust
# @rustserde(with = "chrono::serde::ts_seconds")
timestamp Int
# Multiple annotations
# @gotag(`json:"tx_id" db:"transaction_id"`)
id String
}
```
### Custom Transforms
Handle special encoding requirements:
```js
const customTransforms = {
Base64String: {
// Decode base64 strings to bytes
toTyped: (str) => {
try {
return Uint8Array.from(atob(str), c => c.charCodeAt(0))
} catch {
return undefined
}
},
// Encode bytes to base64 strings
toRepresentation: (bytes) => {
return btoa(String.fromCharCode(...bytes))
}
}
}
const validator = create(schema, 'MyType', { customTransforms })
```
## Command Line Interface
The `ipld-schema` command provides tools for working with schemas:
### Validation
```bash
# Validate schema files
ipld-schema validate schema.ipldsch
# Extract and validate schemas from markdown
ipld-schema validate README.md
```
### Conversion
```bash
# Convert to JSON format
ipld-schema to-json schema.ipldsch
# Pretty print as canonical schema
ipld-schema to-schema schema.ipldsch
```
### Code Generation
```bash
# Generate JavaScript validators
ipld-schema to-js schema.ipldsch
# Generate TypeScript definitions
ipld-schema to-tsdefs schema.ipldsch
```
## API Reference
### Parsing Schemas
- `fromDSL(dsl: string)` - Parse schema DSL into an AST
- `toDSL(schema: Schema)` - Convert AST back to DSL
### Validation
- `create(schema: Schema, type: string, options?)` - Create a validator
- Returns `{ toTyped, toRepresentation }`
- `toTyped(data)` - Validate and convert from storage format
- `toRepresentation(data)` - Validate and convert to storage format
### Code Generation
- `generateGo(schema, options)` - Generate Go code
- `generateRust(schema, options)` - Generate Rust code
- `generateTypeScript(schema, options)` - Generate TypeScript code
## License & Copyright
Copyright 2019-2025 Rod Vagg
Licensed under either of
* Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / http://www.apache.org/licenses/LICENSE-2.0)
* MIT ([LICENSE-MIT](LICENSE-MIT) / http://opensource.org/licenses/MIT)
### Contribution
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.