Quick Start
Welcome to Codables - High-performance, extensible, and declarative “anything to/from JSON” serializer.
Experiment with Codables in the playground
Rationale
Codables addresses two main problems:
- JSON Serialization: Extends JSON to handle JavaScript types that JSON can’t serialize (
Date,BigInt,Map,Set, etc.) with excellent performance
Open playground to test your own data.
- Declarative Serialization: Makes it easy to define serializable nested and complex classes with minimal boilerplate.
Declarative Serialization Overview
Key Features
- 🚀 High Performance: ~3x faster encoding and ~2x faster or comparable (if using reference equality) decoding than SuperJSON
- 🔒 Type Safety: Full TypeScript support with compile-time checking
- 🔄 Reference Preservation: Handles circular references and maintains object identity
- 🛡️ Security: Built-in protection against prototype pollution
- 🎯 Zero Boilerplate: No manual conversion logic or separate data interfaces
- 🔧 Extensible: Easy to add custom serialization types
- 📦 Lightweight: Even with a lot of powerful features, Codables API is relatively small and (hopefully) easy to understand.
Installation
npm install codables
# or
yarn add codables
# or
pnpm add codablesQuick Examples
JSON Serialization
import { encode, decode } from "codables";
const data = {
date: new Date("2025-01-01"),
set: new Set(["a", "b", "c"]),
map: new Map([["key", "value"]]),
};
const encoded = encode(data);
/**
* {
* date: { $$Date: "2025-01-01T00:00:00.000Z" },
* set: { $$Set: ["a", "b", "c"] },
* map: { $$Map: [["key", "value"]] }
* }
* */
const decoded = decode(encoded);
// decoded.date instanceof Date === trueDeclarative Class Serialization
Instead of manually converting your data to/from JSON, you can use Codables to serialize and deserialize your data in declarative way by marking your classes and properties as codable.
First, define your classes and mark them as codable:
import { codableClass, codable, Coder } from "codables";
// Mark your classes as codable with `@codableClass("ClassName")`
@codableClass("Player")
class Player {
// Mark properties as codable with `@codable()`
@codable() name: string;
@codable() score: number;
// Constructor is optional and not needed for Codables to work.
constructor(data: Pick<Player, "name" | "score">) {
this.name = data.name;
this.score = data.score;
}
}
@codableClass("GameState")
class GameState {
@codable() players: Set<Player> = new Set();
@codable() createdAt = new Date();
@codable() activePlayer: Player | null = null;
// Custom methods work like normal.
addPlayer(player: Player) {
this.players.add(player);
this.activePlayer = player;
}
}
const gameState = new GameState();
gameState.addPlayer(new Player({ name: "Alice", score: 100 }));Then, create a custom coder instance that is aware of your classes and encode:
const gameCoder = new Coder([GameState]);
const encoded = gameCoder.encode(gameState);Above will be serialized as:
{
$$GameState: [
{
players: {
$$Set: [{ $$Player: [{ name: "Foo", score: 100 }] }],
},
createdAt: { $$Date: "2025-11-27T23:00:00.000Z" },
activePlayer: { $$ref: "/$$GameState/0/players/$$Set/0" },
},
],
}Later, you can decode your data back to your classes. All types, references, and circular dependencies are preserved!
const decoded = gameCoder.decode<GameState>(encoded);
// decoded.players is Set<Player>
// decoded.createdAt is Date
// decoded.activePlayer is Player | nullNext Steps
- JSON Serialization: Learn about built-in types, custom types, and reference handling
- Declarative Serialization: Master the decorator-based class serialization system
- Recipes: See real-world examples and integrations
- Performance: Understand performance characteristics and optimization strategies
For simple JSON serialization needs, Codables is lightweight and only imports what you need. Advanced features like class decorators are available from codables/decorators when you need them.