JS Object to DynamoDB Schema Converter
Convert JavaScript objects to DynamoDB JSON schema and back. Supports dataToItem, itemToData, and deltaToUpdateParams with reserved word handling.
About
DynamoDB stores attributes using typed descriptors: a simple value like 42 becomes {"N": "42"}, and a nested object becomes an M-wrapped map. Manual construction of these schemas is error-prone and tedious, especially with nested structures exceeding 3 - 4 levels of depth. A mistyped descriptor letter or a forgotten string coercion on numbers silently corrupts your data. This tool implements the full dataToItem and itemToData conversion algorithms, handling all DynamoDB attribute types: S, N, BOOL, NULL, L, M, SS, NS, and BS. It also generates UpdateExpression parameters from delta objects, automatically escaping all 573 DynamoDB reserved words into ExpressionAttributeNames. Values of undefined produce REMOVE actions; defined values produce SET actions. The tool approximates the behavior of the dynamo-converters npm package but runs entirely in your browser with zero dependencies.
Formulas
The dataToItem function applies a recursive type-mapping function T to each value v in the input object:
S: v} if typeof v = "string"{N: String(v)} if typeof v = "number"{BOOL: v} if typeof v = "boolean"{NULL: TRUE} if v = NULL{L: v.map(T)} if Array.isArray(v){M: mapValues(v, T)} if typeof v = "object"omitted if v = undefinedThe reverse function T−1 inspects the single key of each attribute descriptor and unwraps accordingly. For N types, the string is parsed via Number() to restore the numeric value.
The deltaToUpdateParams function partitions keys into three action sets:
REMOVE k1, k2 SET k3 = :k3 ADD k4 :k4Where k ∈ R (the set of 573 DynamoDB reserved words) triggers aliasing: the key is replaced with #k in the expression and mapped in ExpressionAttributeNames.
Reference Data
| JS Type | DynamoDB Descriptor | DynamoDB Example | Notes |
|---|---|---|---|
string | S | {"S": "hello"} | Non-empty strings only |
number | N | {"N": "42"} | Stored as string representation |
boolean | BOOL | {"BOOL": true} | Native boolean |
null | NULL | {"NULL": true} | Explicit null marker |
undefined | - | Omitted | Stripped from output; triggers REMOVE in delta |
object (plain) | M | {"M": {"a": {"S": "x"}}} | Recursive map wrapping |
Array | L | {"L": [{"N": "1"}]} | Heterogeneous list |
string[] (set) | SS | {"SS": ["a", "b"]} | Homogeneous string set (opt-in) |
number[] (set) | NS | {"NS": ["1", "2"]} | Homogeneous number set (opt-in) |
Buffer[] (set) | BS | {"BS": ["dGVzdA=="]} | Binary set, base64 encoded |
Date | S | {"S": "2024-01-01T00:00:00.000Z"} | With date serialization enabled |
Empty string "" | S | {"S": ""} | Allowed since DynamoDB update 2020 |
NaN | - | Error | Not a valid DynamoDB number |
Infinity | - | Error | Not a valid DynamoDB number |
| Nested depth > 32 | M/L | Deep nesting | DynamoDB supports up to 32 levels |
| Item size | - | - | Max 400 KB per item |