{"id":28789941,"url":"https://github.com/colyseus/schema","last_synced_at":"2026-05-31T03:02:52.370Z","repository":{"id":34068343,"uuid":"163086984","full_name":"colyseus/schema","owner":"colyseus","description":"An incremental binary state serializer with delta encoding for games.","archived":false,"fork":false,"pushed_at":"2026-05-07T02:05:24.000Z","size":2998,"stargazers_count":164,"open_issues_count":35,"forks_count":55,"subscribers_count":9,"default_branch":"master","last_synced_at":"2026-05-07T04:40:01.480Z","etag":null,"topics":["binary","colyseus","delta-compression","delta-encoding","game-state","schema","serialization"],"latest_commit_sha":null,"homepage":"https://docs.colyseus.io/state/schema/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/colyseus.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-12-25T13:54:44.000Z","updated_at":"2026-05-07T02:04:32.000Z","dependencies_parsed_at":"2023-09-24T06:56:03.908Z","dependency_job_id":"7a393aef-8b28-4f09-ad4a-0261fa40d997","html_url":"https://github.com/colyseus/schema","commit_stats":{"total_commits":789,"total_committers":26,"mean_commits":"30.346153846153847","dds":0.07351077313054499,"last_synced_commit":"925ddc0de1403f35a78d645c7b85f6be82ffa25f"},"previous_names":[],"tags_count":157,"template":false,"template_full_name":null,"purl":"pkg:github/colyseus/schema","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colyseus%2Fschema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colyseus%2Fschema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colyseus%2Fschema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colyseus%2Fschema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/colyseus","download_url":"https://codeload.github.com/colyseus/schema/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/colyseus%2Fschema/sbom","scorecard":{"id":300534,"data":{"date":"2025-08-11","repo":{"name":"github.com/colyseus/schema","commit":"669fd7d7bbb4a1e417f80c2a2834b45de82df532"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/12 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: topLevel 'contents' permission set to 'write': .github/workflows/npm-publish.yml:4","Warn: no topLevel permission defined: .github/workflows/test-suit.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":2,"reason":"dependency not pinned by hash detected -- score normalized to 2","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/npm-publish.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/colyseus/schema/npm-publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/npm-publish.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/colyseus/schema/npm-publish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/npm-publish.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/colyseus/schema/npm-publish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/npm-publish.yml:44: update your workflow using https://app.stepsecurity.io/secureworkflow/colyseus/schema/npm-publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test-suit.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/colyseus/schema/test-suit.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test-suit.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/colyseus/schema/test-suit.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/test-suit.yml:23","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   1 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/npm-publish.yml:12"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 19 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":7,"reason":"3 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T20:29:53.800Z","repository_id":34068343,"created_at":"2025-08-17T20:29:53.800Z","updated_at":"2025-08-17T20:29:53.800Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33717419,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binary","colyseus","delta-compression","delta-encoding","game-state","schema","serialization"],"created_at":"2025-06-17T22:31:08.791Z","updated_at":"2026-05-31T03:02:52.351Z","avatar_url":"https://github.com/colyseus.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"logo.png?raw=true\" width=\"50%\" /\u003e\n  \u003cbr\u003e\n  \u003cp\u003e\n    An incremental binary state serializer with delta encoding for games.\u003cbr\u003e\n    Made for \u003ca href=\"https://github.com/colyseus/colyseus\"\u003eColyseus\u003c/a\u003e, yet can be used standalone.\n  \u003c/p\u003e\n\u003c/div\u003e\n\n# Features\n\n- **Incremental State Synchronization**: Send only the properties that have changed.\n- **Trigger Callbacks at Decoding**: [Bring your own](https://docs.colyseus.io/state/callbacks/custom) callback system at decoding, or use the built-in one.\n- **Instance Reference Tracking**: Share references of the same instance across the state.\n- **State Views**: Filter properties that should be sent only to specific clients.\n- **Reflection**: Encode/Decode schema definitions.\n- **Schema Generation**: Generate client-side schema files for strictly typed languages.\n- **Type Safety**: Strictly typed schema definitions.\n- **Multiple Language Support**: Decoders available for multiple languages ([C#](https://github.com/colyseus/colyseus-unity-sdk/tree/master/Assets/Colyseus/Runtime/Colyseus/Serializer/Schema), [Lua](https://github.com/colyseus/colyseus-defold/tree/master/colyseus/serializer/schema), [Haxe](https://github.com/colyseus/colyseus-haxe/tree/master/src/io/colyseus/serializer/schema)).\n\n## Schema definition\n\n`@colyseus/schema` uses type annotations to define types of synchronized properties.\n\n```typescript\nimport { Schema, type, ArraySchema, MapSchema } from '@colyseus/schema';\n\nexport class Player extends Schema {\n  @type(\"string\") name: string;\n  @type(\"number\") x: number;\n  @type(\"number\") y: number;\n}\n\nexport class MyState extends Schema {\n  @type('string') fieldString: string;\n  @type('number') fieldNumber: number;\n  @type(Player) player: Player;\n  @type([ Player ]) arrayOfPlayers: ArraySchema\u003cPlayer\u003e;\n  @type({ map: Player }) mapOfPlayers: MapSchema\u003cPlayer\u003e;\n}\n```\n\n## Supported types\n\n### Primitive Types\n\n| Type | Description | Limitation |\n|------|-------------|------------|\n| string | utf8 strings | maximum byte size of `4294967295` |\n| number | auto-detects `int` or `float` type. (extra byte on output) | `0` to `18446744073709551615` |\n| boolean | `true` or `false` | `0` or `1` |\n| int8 | signed 8-bit integer | `-128` to `127` |\n| uint8 | unsigned 8-bit integer | `0` to `255` |\n| int16 | signed 16-bit integer | `-32768` to `32767` |\n| uint16 | unsigned 16-bit integer | `0` to `65535` |\n| int32 | signed 32-bit integer | `-2147483648` to `2147483647` |\n| uint32 | unsigned 32-bit integer | `0` to `4294967295` |\n| int64 | signed 64-bit integer | `-9223372036854775808` to `9223372036854775807` |\n| uint64 | unsigned 64-bit integer | `0` to `18446744073709551615` |\n| float32 | single-precision floating-point number | `-3.40282347e+38` to `3.40282347e+38`|\n| float64 | double-precision floating-point number | `-1.7976931348623157e+308` to `1.7976931348623157e+308` |\n\n### Declaration:\n\n#### Primitive types (`string`, `number`, `boolean`, etc)\n\n```typescript\n@type(\"string\")\nname: string;\n\n@type(\"int32\")\nname: number;\n```\n\n#### Child `Schema` structures\n\n```typescript\n@type(Player)\nplayer: Player;\n```\n\n#### Array of `Schema` structure\n\n```typescript\n@type([ Player ])\narrayOfPlayers: ArraySchema\u003cPlayer\u003e;\n```\n\n#### Array of a primitive type\n\nYou can't mix types inside arrays.\n\n```typescript\n@type([ \"number\" ])\narrayOfNumbers: ArraySchema\u003cnumber\u003e;\n\n@type([ \"string\" ])\narrayOfStrings: ArraySchema\u003cstring\u003e;\n```\n\n#### Map of `Schema` structure\n\n```typescript\n@type({ map: Player })\nmapOfPlayers: MapSchema\u003cPlayer\u003e;\n```\n\n#### Map of a primitive type\n\nYou can't mix primitive types inside maps.\n\n```typescript\n@type({ map: \"number\" })\nmapOfNumbers: MapSchema\u003cnumber\u003e;\n\n@type({ map: \"string\" })\nmapOfStrings: MapSchema\u003cstring\u003e;\n```\n\n### Reflection\n\nThe Schema definitions can encode itself through `Reflection`. You can have the\ndefinition implementation in the server-side, and just send the encoded\nreflection to the client-side, for example:\n\n```typescript\nimport { Schema, type, Reflection } from \"@colyseus/schema\";\n\nclass MyState extends Schema {\n  @type(\"string\") currentTurn: string;\n  // ... more definitions\n}\n\n// send `encodedStateSchema` across the network\nconst encodedStateSchema = Reflection.encode(new MyState());\n\n// instantiate `MyState` in the client-side, without having its definition:\nconst myState = Reflection.decode(encodedStateSchema);\n```\n\n### `StateView` / `@view()`\n\nYou can use `@view()` to filter properties that should be sent only to `StateView`'s that have access to it.\n\n```typescript\nimport { Schema, type, view } from \"@colyseus/schema\";\n\nclass Player extends Schema {\n  @view() @type(\"string\") secret: string;\n  @type(\"string\") notSecret: string;\n}\n\nclass MyState extends Schema {\n  @type({ map: Player }) players = new MapSchema\u003cPlayer\u003e();\n}\n```\n\nUsing the `StateView`\n\n```typescript\nconst view = new StateView();\nview.add(player);\n```\n\n## Encoder\n\nThere are 3 major features of the `Encoder` class:\n\n- Encoding the full state\n- Encoding the state changes\n- Encoding state with filters (properties using `@view()` tag)\n\n```typescript\nimport { Encoder } from \"@colyseus/schema\";\n\nconst state = new MyState();\nconst encoder = new Encoder(state);\n```\n\nNew clients must receive the full state on their first connection:\n\n```typescript\nconst fullEncode = encoder.encodeAll();\n// ... send \"fullEncode\" to client and decode it\n```\n\nFurther state changes must be sent in order:\n\n```typescript\nconst changesBuffer = encoder.encode();\n// ... send \"changesBuffer\" to client and decode it\n```\n\n### Encoding with views\n\nWhen using `@view()` and `StateView`'s, a single \"full encode\" must be used for multiple views. Each view also must add its own changes.\n\n```typescript\n// shared buffer iterator\nconst it = { offset: 0 };\n\n// shared full encode\nencoder.encodeAll(it);\nconst sharedOffset = it.offset;\n\n// view 1\nconst fullEncode1 = encoder.encodeAllView(view1, sharedOffset, it);\n// ... send \"fullEncode1\" to client1 and decode it\n\n// view 2\nconst fullEncode2 = encoder.encodeAllView(view2, sharedOffset, it);\n// ... send \"fullEncode\" to client2 and decode it\n```\n\nEncoding changes per views:\n\n```typescript\n// shared buffer iterator\nconst it = { offset: 0 };\n\n// shared changes encode\nencoder.encode(it);\nconst sharedOffset = it.offset;\n\n// view 1\nconst view1Encoded = this.encoder.encodeView(view1, sharedOffset, it);\n// ... send \"view1Encoded\" to client1 and decode it\n\n// view 2\nconst view2Encoded = this.encoder.encodeView(view2, sharedOffset, it);\n// ... send \"view2Encoded\" to client2 and decode it\n\n// discard all changes after encoding is done.\nencoder.discardChanges();\n```\n\n## Decoder\n\nThe `Decoder` class is used to decode the binary data received from the server.\n\n```typescript\nimport { Decoder } from \"@colyseus/schema\";\n\nconst state = new MyState();\nconst decoder = new Decoder(state);\ndecoder.decode(encodedBytes);\n```\n\n### Backwards/forwards compatibility\n\nBackwards/forwards compatibility is possible by declaring new fields at the\nend of existing structures, and earlier declarations to not be removed, but\nbe marked `@deprecated()` when needed.\n\nThis is particularly useful for native-compiled targets, such as C#, C++,\nHaxe, etc - where the client-side can potentially not have the most\nup-to-date version of the schema definitions.\n\n\n## Limitations and best practices\n\n- Each `Schema` structure can hold up to `64` fields. If you need more fields, use nested structures.\n- `NaN` or `null` numbers are encoded as `0`\n- `null` strings are encoded as `\"\"`\n- `Infinity` numbers are encoded as `Number.MAX_SAFE_INTEGER`\n- Multi-dimensional arrays are not supported.\n- Items inside Arrays and Maps must be all instance of the same type.\n- `@colyseus/schema` encodes only field values in the specified order.\n  - Both encoder (server) and decoder (client) must have same schema definition.\n  - The order of the fields must be the same.\n\n## Generating client-side schema files (for strictly typed languages)\n\n\u003e If you're using JavaScript or LUA, there's no need to bother about this.\n\u003e Interpreted programming languages are able to re-build the Schema locally through the use of `Reflection`.\n\nYou can generate the client-side schema files based on the TypeScript schema definitions automatically.\n\n```\n# C#/Unity\nschema-codegen ./schemas/State.ts --output ./unity-project/ --csharp\n\n# C/C++\nschema-codegen ./schemas/State.ts --output ./cpp-project/ --cpp\n\n# Haxe\nschema-codegen ./schemas/State.ts --output ./haxe-project/ --haxe\n```\n\n### Code Generation Options\n\n| Option | Description |\n|--------|-------------|\n| `--output` | The output directory for generated client-side schema files (required) |\n| `--bundle` | Bundle all generated files into a single file |\n| `--namespace` | Generate namespace/package on output code |\n| `--decorator` | Custom name for `@type` decorator to scan for |\n\n### Bundle Mode\n\nBy default, the code generator creates one file per schema class. Use the `--bundle` option to combine all generated classes into a single file:\n\n```\n# Generate a single bundled file\nschema-codegen ./schemas/State.ts --output ./unity-project/ --csharp --bundle\n\n# With namespace\nschema-codegen ./schemas/State.ts --output ./unity-project/ --csharp --bundle --namespace MyGame.Schema\n```\n\nBundle mode output filenames:\n- **TypeScript**: `schema.ts` (or `{namespace}.ts`)\n- **JavaScript**: `schema.js` (or `{namespace}.js`)\n- **C#**: `Schema.cs` (or `{namespace}.cs`)\n- **C++**: `schema.hpp` (or `{namespace}.hpp`)\n- **Haxe**: `Schema.hx` (or `{namespace}.hx`)\n- **Java**: `Schema.java`\n- **Lua**: `schema.lua` (or `{namespace}.lua`)\n- **C**: `schema.h` (or `{namespace}.h`)\n\n## Benchmarks:\n\n| Scenario | `@colyseus/schema` | `msgpack` + `fossil-delta` |\n|---|---|---|\n| Initial state size (100 entities) | 2671 | 3283 |\n| Updating x/y of 1 entity after initial state | 9 | 26 |\n| Updating x/y of 50 entities after initial state | 342 | 684 |\n| Updating x/y of 100 entities after initial state | 668 | 1529 |\n\n## Decoder implementation in other languages\n\nEach Colyseus SDK has its own decoder implementation of the `@colyseus/schema` protocol:\n\n- [C#](https://github.com/colyseus/colyseus-unity-sdk)\n- [Haxe](https://github.com/colyseus/colyseus-haxe)\n- [Lua](https://github.com/colyseus/colyseus-defold)\n- [C++](https://github.com/colyseus/colyseus-cocos2d-x) _(Not up-to-date)_\n\n## Why\n\nInitial thoughts/assumptions, for Colyseus:\n- little to no bottleneck for detecting state changes.\n- have a schema definition on both the server and the client\n- better experience on statically-typed languages (C#, C++)\n- mutations should be cheap.\n\nPractical Colyseus issues this should solve:\n- Avoid decoding large objects that haven't been patched\n- Allow to send different patches for each client\n- Better developer experience on statically-typed languages\n\n## Inspiration:\n\n- [Protocol Buffers](https://developers.google.com/protocol-buffers)\n- [flatbuffers](https://google.github.io/flatbuffers/flatbuffers_white_paper.html)\n- [schemapack](https://github.com/phretaddin/schemapack/)\n- [avro](https://avro.apache.org/docs/current/spec.html)\n\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcolyseus%2Fschema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcolyseus%2Fschema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcolyseus%2Fschema/lists"}