Skip to Content
DocumentationQuick Start

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:

  1. 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.

JSON Serialization Overview

  1. 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 codables

Quick 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 === true

Declarative 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 | null

Next Steps

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.

Last updated on