0
# Serialization Annotations
1
2
Comprehensive reference for all kotlinx.serialization annotations that control serialization behavior.
3
4
## Core Annotations
5
6
### @Serializable
7
8
The primary annotation that marks a class as serializable and instructs the compiler plugin to generate a serializer.
9
10
```kotlin
11
@MustBeDocumented
12
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS, AnnotationTarget.TYPE)
13
public annotation class Serializable(
14
val with: KClass<out KSerializer<*>> = KSerializer::class
15
)
16
```
17
{ .api }
18
19
**Usage:**
20
21
```javascript
22
// Basic serializable class
23
@Serializable
24
class User {
25
constructor(name, age) {
26
this.name = name;
27
this.age = age;
28
}
29
}
30
31
// With custom serializer
32
@Serializable(UserCustomSerializer::class)
33
class User {
34
constructor(name, age) {
35
this.name = name;
36
this.age = age;
37
}
38
}
39
```
40
41
**Parameters:**
42
- `with`: Specifies a custom serializer class to use instead of the generated one
43
44
### @SerialName
45
46
Overrides the default name used in the serialized form for classes or properties.
47
48
```kotlin
49
@MustBeDocumented
50
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
51
public annotation class SerialName(val value: String)
52
```
53
{ .api }
54
55
**Usage:**
56
57
```javascript
58
@Serializable
59
@SerialName("UserProfile")
60
class User {
61
@SerialName("user_name")
62
name;
63
64
@SerialName("user_age")
65
age;
66
67
constructor(name, age) {
68
this.name = name;
69
this.age = age;
70
}
71
}
72
73
// Serialized as: {"user_name": "John", "user_age": 30}
74
```
75
76
## Field Control Annotations
77
78
### @Required
79
80
Marks a property as required during deserialization, even if it has a default value.
81
82
```kotlin
83
@SerialInfo
84
@Target(AnnotationTarget.PROPERTY)
85
annotation class Required
86
```
87
{ .api }
88
89
**Usage:**
90
91
```javascript
92
@Serializable
93
class Config {
94
@Required
95
apiKey = "default"; // Must be present in JSON even though it has default
96
97
timeout = 5000; // Optional, will use default if missing
98
99
constructor(apiKey = "default", timeout = 5000) {
100
this.apiKey = apiKey;
101
this.timeout = timeout;
102
}
103
}
104
105
// This will throw MissingFieldException:
106
// {"timeout": 10000} // Missing required apiKey
107
108
// This works:
109
// {"apiKey": "abc123", "timeout": 10000}
110
```
111
112
### @Transient
113
114
Excludes a property from serialization entirely.
115
116
```kotlin
117
@Target(AnnotationTarget.PROPERTY)
118
annotation class Transient
119
```
120
{ .api }
121
122
**Usage:**
123
124
```javascript
125
@Serializable
126
class User {
127
name;
128
age;
129
130
@Transient
131
password; // Never serialized
132
133
@Transient
134
temporaryData; // Runtime-only data
135
136
constructor(name, age, password = null, temporaryData = null) {
137
this.name = name;
138
this.age = age;
139
this.password = password;
140
this.temporaryData = temporaryData;
141
}
142
}
143
144
// Only serializes: {"name": "John", "age": 30}
145
```
146
147
### @EncodeDefault
148
149
Controls serialization of properties with default values (Experimental API).
150
151
```kotlin
152
@ExperimentalSerializationApi
153
@SerialInfo
154
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
155
annotation class EncodeDefault(val mode: Mode = Mode.ALWAYS) {
156
enum class Mode { ALWAYS, NEVER }
157
}
158
```
159
{ .api }
160
161
**Usage:**
162
163
```javascript
164
@Serializable
165
class Settings {
166
@EncodeDefault(EncodeDefault.Mode.ALWAYS)
167
theme = "dark"; // Always included, even when default
168
169
@EncodeDefault(EncodeDefault.Mode.NEVER)
170
debug = false; // Never included when it's the default value
171
172
language = "en"; // Format-dependent behavior
173
174
constructor(theme = "dark", debug = false, language = "en") {
175
this.theme = theme;
176
this.debug = debug;
177
this.language = language;
178
}
179
}
180
```
181
182
## Contextual Serialization Annotations
183
184
### @Contextual
185
186
Instructs the plugin to use contextual serializer lookup for this property.
187
188
```kotlin
189
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.TYPE)
190
annotation class Contextual
191
```
192
{ .api }
193
194
**Usage:**
195
196
```javascript
197
@Serializable
198
class Event {
199
name;
200
201
@Contextual
202
timestamp; // Serializer looked up from SerializersModule at runtime
203
204
constructor(name, timestamp) {
205
this.name = name;
206
this.timestamp = timestamp;
207
}
208
}
209
210
// Configure contextual serializer in module
211
const module = SerializersModule {
212
contextual(Date, DateSerializer)
213
};
214
```
215
216
### @UseContextualSerialization
217
218
File-level annotation that enables contextual serialization for specified classes.
219
220
```kotlin
221
@Target(AnnotationTarget.FILE)
222
annotation class UseContextualSerialization(
223
vararg val forClasses: KClass<*>
224
)
225
```
226
{ .api }
227
228
**Usage:**
229
230
```javascript
231
@file:UseContextualSerialization(Date::class, BigDecimal::class)
232
233
// Now all Date and BigDecimal properties automatically use contextual lookup
234
@Serializable
235
class Transaction {
236
timestamp; // Automatically contextual (Date)
237
amount; // Automatically contextual (BigDecimal)
238
239
constructor(timestamp, amount) {
240
this.timestamp = timestamp;
241
this.amount = amount;
242
}
243
}
244
```
245
246
### @UseSerializers
247
248
File-level annotation to add serializers to the resolving process.
249
250
```kotlin
251
@Target(AnnotationTarget.FILE)
252
annotation class UseSerializers(
253
vararg val serializerClasses: KClass<out KSerializer<*>>
254
)
255
```
256
{ .api }
257
258
**Usage:**
259
260
```javascript
261
@file:UseSerializers(DateSerializer::class, UUIDSerializer::class)
262
263
// These serializers are now available for automatic resolution
264
@Serializable
265
class Document {
266
id; // Will use UUIDSerializer if id is UUID
267
createdAt; // Will use DateSerializer if createdAt is Date
268
269
constructor(id, createdAt) {
270
this.id = id;
271
this.createdAt = createdAt;
272
}
273
}
274
```
275
276
## Polymorphic Serialization
277
278
### @Polymorphic
279
280
Instructs the plugin to use polymorphic serialization for this property.
281
282
```kotlin
283
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.TYPE)
284
annotation class Polymorphic
285
```
286
{ .api }
287
288
**Usage:**
289
290
```javascript
291
@Serializable
292
abstract class Shape {
293
abstract area;
294
}
295
296
@Serializable
297
class Circle extends Shape {
298
constructor(radius) {
299
super();
300
this.radius = radius;
301
this.area = Math.PI * radius * radius;
302
}
303
}
304
305
@Serializable
306
class Rectangle extends Shape {
307
constructor(width, height) {
308
super();
309
this.width = width;
310
this.height = height;
311
this.area = width * height;
312
}
313
}
314
315
@Serializable
316
class Drawing {
317
@Polymorphic
318
shapes; // Array of Shape - actual type determined at runtime
319
320
constructor(shapes) {
321
this.shapes = shapes;
322
}
323
}
324
```
325
326
## Experimental Annotations
327
328
### @MetaSerializable
329
330
Meta-annotation for creating custom serializable annotations (Experimental).
331
332
```kotlin
333
@ExperimentalSerializationApi
334
@Target(AnnotationTarget.ANNOTATION_CLASS)
335
annotation class MetaSerializable
336
```
337
{ .api }
338
339
**Usage:**
340
341
```javascript
342
@MetaSerializable
343
@Target(AnnotationTarget.CLASS)
344
annotation class JsonSerializable
345
346
// Custom annotation that implies @Serializable
347
@JsonSerializable
348
class User {
349
constructor(name) {
350
this.name = name;
351
}
352
}
353
```
354
355
### @Serializer
356
357
Instructs the plugin to create a serializer for the specified class (Experimental).
358
359
```kotlin
360
@ExperimentalSerializationApi
361
@Target(AnnotationTarget.CLASS)
362
annotation class Serializer(val forClass: KClass<*>)
363
```
364
{ .api }
365
366
**Usage:**
367
368
```javascript
369
// Generate serializer for external class you can't modify
370
@Serializer(ExternalLibraryClass::class)
371
object ExternalClassSerializer : KSerializer<ExternalLibraryClass> {
372
// Implementation generated by plugin
373
}
374
```
375
376
### @KeepGeneratedSerializer
377
378
Keeps the generated serializer accessible when a custom serializer is specified (Experimental).
379
380
```kotlin
381
@ExperimentalSerializationApi
382
@Target(AnnotationTarget.CLASS)
383
annotation class KeepGeneratedSerializer
384
```
385
{ .api }
386
387
**Usage:**
388
389
```javascript
390
@Serializable(CustomUserSerializer::class)
391
@KeepGeneratedSerializer
392
class User {
393
constructor(name, age) {
394
this.name = name;
395
this.age = age;
396
}
397
398
// Both CustomUserSerializer and generated serializer are available
399
static generatedSerializer = /* generated serializer */;
400
}
401
402
// Access both serializers
403
const customSer = User.serializer(); // Returns CustomUserSerializer
404
const generatedSer = User.generatedSerializer; // Returns generated serializer
405
```
406
407
## Meta-Annotations
408
409
### @SerialInfo
410
411
Base meta-annotation for all serialization-related annotations.
412
413
```kotlin
414
@ExperimentalSerializationApi
415
@Target(AnnotationTarget.ANNOTATION_CLASS)
416
annotation class SerialInfo
417
```
418
{ .api }
419
420
### @InheritableSerialInfo
421
422
Meta-annotation for annotations that should be inherited by subclasses.
423
424
```kotlin
425
@ExperimentalSerializationApi
426
@Target(AnnotationTarget.ANNOTATION_CLASS)
427
annotation class InheritableSerialInfo
428
```
429
{ .api }
430
431
**Usage:**
432
433
```javascript
434
@InheritableSerialInfo
435
@Target(AnnotationTarget.CLASS)
436
annotation class ApiVersion(val version: String)
437
438
@ApiVersion("v1")
439
@Serializable
440
abstract class BaseEntity {
441
id;
442
}
443
444
// Inherits @ApiVersion("v1") annotation
445
@Serializable
446
class User extends BaseEntity {
447
constructor(id, name) {
448
super();
449
this.id = id;
450
this.name = name;
451
}
452
}
453
```
454
455
## Annotation Combinations
456
457
Annotations can be combined for sophisticated serialization control:
458
459
```javascript
460
@Serializable
461
class UserProfile {
462
@SerialName("user_id")
463
@Required
464
id; // Custom name and always required
465
466
@SerialName("display_name")
467
name; // Custom name, optional
468
469
@Transient
470
password; // Never serialized
471
472
@Contextual
473
@SerialName("last_login")
474
lastLogin; // Custom name with contextual serializer
475
476
@EncodeDefault(EncodeDefault.Mode.NEVER)
477
theme = "default"; // Don't encode when default
478
479
constructor(id, name, password = null, lastLogin = null, theme = "default") {
480
this.id = id;
481
this.name = name;
482
this.password = password;
483
this.lastLogin = lastLogin;
484
this.theme = theme;
485
}
486
}
487
```
488
489
## JavaScript-Specific Notes
490
491
### Enum Annotations
492
493
On JavaScript, enum classes require explicit `@Serializable` annotation:
494
495
```javascript
496
@Serializable
497
enum class Status {
498
ACTIVE, INACTIVE, PENDING
499
}
500
501
@Serializable
502
class Task {
503
status; // Status enum
504
505
constructor(status) {
506
this.status = status;
507
}
508
}
509
```
510
511
### Type Safety
512
513
TypeScript provides compile-time validation of annotation usage:
514
515
```typescript
516
interface SerializableClass {
517
// Ensures proper annotation usage at compile time
518
readonly serializer: () => KSerializer<this>;
519
}
520
521
@Serializable
522
class User implements SerializableClass {
523
// TypeScript enforces correct implementation
524
}
525
```
526
527
All annotations work consistently across different serialization formats (JSON, ProtoBuf, CBOR, etc.), providing format-independent serialization control.