blob: 817a3b332501b3f6aabd5f6e08028cce10350d66 [file] [log] [blame] [edit]
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="canonical" href="https://flatbuffers.dev/schema/">
<link rel="prev" href="../flatc/">
<link rel="next" href="../evolution/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.16">
<title>Overview - FlatBuffers Docs</title>
<link rel="stylesheet" href="../assets/stylesheets/main.7e37652d.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#schema" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="FlatBuffers Docs" class="md-header__button md-logo" aria-label="FlatBuffers Docs" data-md-component="logo">
<img src="../assets/flatbuffers_logo.svg" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
FlatBuffers Docs
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Overview
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<div class="md-header__source">
<a href="https://github.com/google/flatbuffers" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path fill="currentColor" d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</div>
<div class="md-source__repository">
google/FlatBuffers
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="FlatBuffers Docs" class="md-nav__button md-logo" aria-label="FlatBuffers Docs" data-md-component="logo">
<img src="../assets/flatbuffers_logo.svg" alt="logo">
</a>
FlatBuffers Docs
</label>
<div class="md-nav__source">
<a href="https://github.com/google/flatbuffers" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path fill="currentColor" d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</div>
<div class="md-source__repository">
google/FlatBuffers
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../quick_start/" class="md-nav__link">
<span class="md-ellipsis">
Quick Start
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tutorial/" class="md-nav__link">
<span class="md-ellipsis">
Tutorial
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
Compiler (flatc)
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Compiler (flatc)
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../building/" class="md-nav__link">
<span class="md-ellipsis">
Building
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../flatc/" class="md-nav__link">
<span class="md-ellipsis">
Using
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" checked>
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
Schema (.fbs)
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Schema (.fbs)
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Overview
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Overview
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#tables" class="md-nav__link">
<span class="md-ellipsis">
Tables
</span>
</a>
<nav class="md-nav" aria-label="Tables">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#fields" class="md-nav__link">
<span class="md-ellipsis">
Fields
</span>
</a>
<nav class="md-nav" aria-label="Fields">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-default" class="md-nav__link">
<span class="md-ellipsis">
1. Default
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-optional" class="md-nav__link">
<span class="md-ellipsis">
2. Optional
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-required" class="md-nav__link">
<span class="md-ellipsis">
3. Required
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#structs" class="md-nav__link">
<span class="md-ellipsis">
Structs
</span>
</a>
<nav class="md-nav" aria-label="Structs">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#arrays" class="md-nav__link">
<span class="md-ellipsis">
Arrays
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#types" class="md-nav__link">
<span class="md-ellipsis">
Types
</span>
</a>
<nav class="md-nav" aria-label="Types">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#scalars" class="md-nav__link">
<span class="md-ellipsis">
Scalars
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#non-scalars" class="md-nav__link">
<span class="md-ellipsis">
Non-scalars
</span>
</a>
<nav class="md-nav" aria-label="Non-scalars">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#vectors" class="md-nav__link">
<span class="md-ellipsis">
Vectors
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#strings" class="md-nav__link">
<span class="md-ellipsis">
Strings
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#enums" class="md-nav__link">
<span class="md-ellipsis">
Enums
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#unions" class="md-nav__link">
<span class="md-ellipsis">
Unions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#namespaces" class="md-nav__link">
<span class="md-ellipsis">
Namespaces
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#includes" class="md-nav__link">
<span class="md-ellipsis">
Includes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#root-type" class="md-nav__link">
<span class="md-ellipsis">
Root type
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#file-identification-and-extension" class="md-nav__link">
<span class="md-ellipsis">
File identification and extension
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rpc-interface-declarations" class="md-nav__link">
<span class="md-ellipsis">
RPC interface declarations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#comments-documentation" class="md-nav__link">
<span class="md-ellipsis">
Comments &amp; documentation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#attributes" class="md-nav__link">
<span class="md-ellipsis">
Attributes
</span>
</a>
<nav class="md-nav" aria-label="Attributes">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#required" class="md-nav__link">
<span class="md-ellipsis">
required
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#json-parsing" class="md-nav__link">
<span class="md-ellipsis">
JSON Parsing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#guidelines" class="md-nav__link">
<span class="md-ellipsis">
Guidelines
</span>
</a>
<nav class="md-nav" aria-label="Guidelines">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#efficiency" class="md-nav__link">
<span class="md-ellipsis">
Efficiency
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#style-guide" class="md-nav__link">
<span class="md-ellipsis">
Style guide
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#gotchas" class="md-nav__link">
<span class="md-ellipsis">
Gotchas
</span>
</a>
<nav class="md-nav" aria-label="Gotchas">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#testing-whether-a-field-is-present-in-a-table" class="md-nav__link">
<span class="md-ellipsis">
Testing whether a field is present in a table
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../evolution/" class="md-nav__link">
<span class="md-ellipsis">
Evolution
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../grammar/" class="md-nav__link">
<span class="md-ellipsis">
Grammar
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
Language Guides
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Language Guides
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../languages/c/" class="md-nav__link">
<span class="md-ellipsis">
C
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/cpp/" class="md-nav__link">
<span class="md-ellipsis">
C++
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/c_sharp/" class="md-nav__link">
<span class="md-ellipsis">
C#
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/dart/" class="md-nav__link">
<span class="md-ellipsis">
Dart
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/go/" class="md-nav__link">
<span class="md-ellipsis">
Go
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/java/" class="md-nav__link">
<span class="md-ellipsis">
Java
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/javascript/" class="md-nav__link">
<span class="md-ellipsis">
JavaScript
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/kotlin/" class="md-nav__link">
<span class="md-ellipsis">
Kotlin
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/lobster/" class="md-nav__link">
<span class="md-ellipsis">
Lobster
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/lua/" class="md-nav__link">
<span class="md-ellipsis">
Lua
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/php/" class="md-nav__link">
<span class="md-ellipsis">
PHP
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/python/" class="md-nav__link">
<span class="md-ellipsis">
Python
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/rust/" class="md-nav__link">
<span class="md-ellipsis">
Rust
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/swift/" class="md-nav__link">
<span class="md-ellipsis">
Swift
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../languages/typescript/" class="md-nav__link">
<span class="md-ellipsis">
TypeScript
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../support/" class="md-nav__link">
<span class="md-ellipsis">
Supported Configurations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../white_paper/" class="md-nav__link">
<span class="md-ellipsis">
White Paper
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_9" >
<label class="md-nav__link" for="__nav_9" id="__nav_9_label" tabindex="0">
<span class="md-ellipsis">
Advanced
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_9">
<span class="md-nav__icon md-icon"></span>
Advanced
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../internals/" class="md-nav__link">
<span class="md-ellipsis">
FlatBuffers Internals
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../intermediate_representation/" class="md-nav__link">
<span class="md-ellipsis">
Intermediate Representation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../annotation/" class="md-nav__link">
<span class="md-ellipsis">
Annotating Buffers (.afb)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../benchmarks/" class="md-nav__link">
<span class="md-ellipsis">
Benchmarks
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../flexbuffers/" class="md-nav__link">
<span class="md-ellipsis">
FlexBuffers (Schema-less version)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../contributing/" class="md-nav__link">
<span class="md-ellipsis">
Contributing
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#tables" class="md-nav__link">
<span class="md-ellipsis">
Tables
</span>
</a>
<nav class="md-nav" aria-label="Tables">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#fields" class="md-nav__link">
<span class="md-ellipsis">
Fields
</span>
</a>
<nav class="md-nav" aria-label="Fields">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-default" class="md-nav__link">
<span class="md-ellipsis">
1. Default
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-optional" class="md-nav__link">
<span class="md-ellipsis">
2. Optional
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-required" class="md-nav__link">
<span class="md-ellipsis">
3. Required
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#structs" class="md-nav__link">
<span class="md-ellipsis">
Structs
</span>
</a>
<nav class="md-nav" aria-label="Structs">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#arrays" class="md-nav__link">
<span class="md-ellipsis">
Arrays
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#types" class="md-nav__link">
<span class="md-ellipsis">
Types
</span>
</a>
<nav class="md-nav" aria-label="Types">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#scalars" class="md-nav__link">
<span class="md-ellipsis">
Scalars
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#non-scalars" class="md-nav__link">
<span class="md-ellipsis">
Non-scalars
</span>
</a>
<nav class="md-nav" aria-label="Non-scalars">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#vectors" class="md-nav__link">
<span class="md-ellipsis">
Vectors
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#strings" class="md-nav__link">
<span class="md-ellipsis">
Strings
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#enums" class="md-nav__link">
<span class="md-ellipsis">
Enums
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#unions" class="md-nav__link">
<span class="md-ellipsis">
Unions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#namespaces" class="md-nav__link">
<span class="md-ellipsis">
Namespaces
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#includes" class="md-nav__link">
<span class="md-ellipsis">
Includes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#root-type" class="md-nav__link">
<span class="md-ellipsis">
Root type
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#file-identification-and-extension" class="md-nav__link">
<span class="md-ellipsis">
File identification and extension
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#rpc-interface-declarations" class="md-nav__link">
<span class="md-ellipsis">
RPC interface declarations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#comments-documentation" class="md-nav__link">
<span class="md-ellipsis">
Comments &amp; documentation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#attributes" class="md-nav__link">
<span class="md-ellipsis">
Attributes
</span>
</a>
<nav class="md-nav" aria-label="Attributes">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#required" class="md-nav__link">
<span class="md-ellipsis">
required
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#json-parsing" class="md-nav__link">
<span class="md-ellipsis">
JSON Parsing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#guidelines" class="md-nav__link">
<span class="md-ellipsis">
Guidelines
</span>
</a>
<nav class="md-nav" aria-label="Guidelines">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#efficiency" class="md-nav__link">
<span class="md-ellipsis">
Efficiency
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#style-guide" class="md-nav__link">
<span class="md-ellipsis">
Style guide
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#gotchas" class="md-nav__link">
<span class="md-ellipsis">
Gotchas
</span>
</a>
<nav class="md-nav" aria-label="Gotchas">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#testing-whether-a-field-is-present-in-a-table" class="md-nav__link">
<span class="md-ellipsis">
Testing whether a field is present in a table
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/google/flatbuffers/edit/master/docs/source/schema.md" title="Edit this page" class="md-content__button md-icon" rel="edit">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg>
</a>
<h1 id="schema">Schema</h1>
<p>The syntax of the schema language (aka IDL,
<a href="https://en.wikipedia.org/wiki/Interface_description_language">Interface Definition Language</a>)
should look quite familiar to users of any of the C family of languages, and
also to users of other IDLs. Let's look at an example first:</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">monster.fbs</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"> 1</span>
<span class="normal"> 2</span>
<span class="normal"> 3</span>
<span class="normal"> 4</span>
<span class="normal"> 5</span>
<span class="normal"> 6</span>
<span class="normal"> 7</span>
<span class="normal"> 8</span>
<span class="normal"> 9</span>
<span class="normal">10</span>
<span class="normal">11</span>
<span class="normal">12</span>
<span class="normal">13</span>
<span class="normal">14</span>
<span class="normal">15</span>
<span class="normal">16</span>
<span class="normal">17</span>
<span class="normal">18</span>
<span class="normal">19</span>
<span class="normal">20</span>
<span class="normal">21</span>
<span class="normal">22</span>
<span class="normal">23</span>
<span class="normal">24</span>
<span class="normal">25</span>
<span class="normal">26</span>
<span class="normal">27</span>
<span class="normal">28</span>
<span class="normal">29</span>
<span class="normal">30</span>
<span class="normal">31</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="c1">// example IDL file</span>
<span class="n">namespace</span><span class="w"> </span><span class="n">MyGame</span><span class="p">;</span>
<span class="n">attribute</span><span class="w"> </span><span class="s">&quot;priority&quot;</span><span class="p">;</span>
<span class="k">enum</span><span class="w"> </span><span class="n">Color</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">byte</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">Red</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">Green</span><span class="p">,</span><span class="w"> </span><span class="n">Blue</span><span class="w"> </span><span class="p">}</span>
<span class="k">union</span><span class="w"> </span><span class="nc">Any</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">Monster</span><span class="p">,</span><span class="w"> </span><span class="n">Weapon</span><span class="p">,</span><span class="w"> </span><span class="n">Pickup</span><span class="w"> </span><span class="p">}</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">Vec3</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nl">x</span><span class="p">:</span><span class="kt">float</span><span class="p">;</span>
<span class="w"> </span><span class="nl">y</span><span class="p">:</span><span class="kt">float</span><span class="p">;</span>
<span class="w"> </span><span class="nl">z</span><span class="p">:</span><span class="kt">float</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">table</span><span class="w"> </span><span class="n">Monster</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nl">pos</span><span class="p">:</span><span class="n">Vec3</span><span class="p">;</span>
<span class="w"> </span><span class="nl">mana</span><span class="p">:</span><span class="kt">short</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">150</span><span class="p">;</span>
<span class="w"> </span><span class="nl">hp</span><span class="p">:</span><span class="kt">short</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">100</span><span class="p">;</span>
<span class="w"> </span><span class="nl">name</span><span class="p">:</span><span class="n">string</span><span class="p">;</span>
<span class="w"> </span><span class="nl">friendly</span><span class="p">:</span><span class="kt">bool</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">false</span><span class="w"> </span><span class="p">(</span><span class="n">deprecated</span><span class="p">,</span><span class="w"> </span><span class="n">priority</span><span class="o">:</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
<span class="w"> </span><span class="nl">inventory</span><span class="p">:[</span><span class="n">ubyte</span><span class="p">];</span>
<span class="w"> </span><span class="nl">color</span><span class="p">:</span><span class="n">Color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Blue</span><span class="p">;</span>
<span class="w"> </span><span class="nl">test</span><span class="p">:</span><span class="n">Any</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">table</span><span class="w"> </span><span class="n">Weapon</span><span class="w"> </span><span class="p">{}</span>
<span class="n">table</span><span class="w"> </span><span class="n">Pickup</span><span class="w"> </span><span class="p">{}</span>
<span class="n">root_type</span><span class="w"> </span><span class="n">Monster</span><span class="p">;</span>
</code></pre></div></td></tr></table></div>
<h2 id="tables">Tables</h2>
<p>Tables are the main way of defining objects in FlatBuffers.</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">monster.fbs - Example Table</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">17</span>
<span class="normal">18</span>
<span class="normal">19</span>
<span class="normal">20</span>
<span class="normal">21</span>
<span class="normal">22</span>
<span class="normal">23</span>
<span class="normal">24</span>
<span class="normal">25</span>
<span class="normal">26</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="n">table</span><span class="w"> </span><span class="n">Monster</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nl">pos</span><span class="p">:</span><span class="n">Vec3</span><span class="p">;</span>
<span class="w"> </span><span class="nl">mana</span><span class="p">:</span><span class="kt">short</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">150</span><span class="p">;</span>
<span class="w"> </span><span class="nl">hp</span><span class="p">:</span><span class="kt">short</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">100</span><span class="p">;</span>
<span class="w"> </span><span class="nl">name</span><span class="p">:</span><span class="n">string</span><span class="p">;</span>
<span class="w"> </span><span class="nl">friendly</span><span class="p">:</span><span class="kt">bool</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">false</span><span class="w"> </span><span class="p">(</span><span class="n">deprecated</span><span class="p">,</span><span class="w"> </span><span class="n">priority</span><span class="o">:</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
<span class="w"> </span><span class="nl">inventory</span><span class="p">:[</span><span class="n">ubyte</span><span class="p">];</span>
<span class="w"> </span><span class="nl">color</span><span class="p">:</span><span class="n">Color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Blue</span><span class="p">;</span>
<span class="w"> </span><span class="nl">test</span><span class="p">:</span><span class="n">Any</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></td></tr></table></div>
<p>They consist of a name (here <code>Monster</code>) and a list of <a href="#fields">fields</a>. This
field list can be appended to (and deprecated from) while still maintaining
compatibility.</p>
<h3 id="fields">Fields</h3>
<p>Table fields have a name identifier, a <a href="#types">type</a>, optional default value,
optional <a href="#attributes">attributes</a> and ends with a <code>;</code>. See the
<a href="../grammar/">grammar</a> for full details.</p>
<div class="highlight"><pre><span></span><code><span class="k">field_decl </span><span class="o">=</span> <span class="k">ident </span><span class="err">`:`</span> <span class="k">type </span><span class="p">[</span> <span class="err">`=`</span> <span class="k">scalar </span><span class="p">]</span> <span class="k">metadata </span><span class="err">`</span><span class="p">;</span><span class="err">`</span>
</code></pre></div>
<p>Fields do not have to appear in the wire representation, and you can choose to
omit fields when constructing an object. You have the flexibility to add fields
without fear of bloating your data. This design is also FlatBuffer's mechanism
for forward and backwards compatibility.</p>
<p>There are three, mutually exclusive, reactions to the non-presence of a table's
field in the binary data.</p>
<h4 id="1-default">1. Default</h4>
<p>Default value fields with return the default value as defined in the schema. If
the default value is not specified in the schema, it will be <code>0</code> for scalar
types, or <code>null</code> for other types.</p>
<div class="highlight"><pre><span></span><code><span class="nl">mana</span><span class="p">:</span><span class="kt">short</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">150</span><span class="p">;</span>
<span class="nl">hp</span><span class="p">:</span><span class="kt">short</span><span class="p">;</span>
<span class="nl">inventory</span><span class="p">:[</span><span class="n">ubyte</span><span class="p">];</span>
</code></pre></div>
<p>Here <code>mana</code> would default to the value <code>150</code>, <code>hp</code> to value <code>0</code>, and <code>inventory</code>
to <code>null</code>, if those fields are not set.</p>
<p>Only scalar values can have explicit defaults, non-scalar fields (strings,
vectors, tables) are <code>null</code> when not present.</p>
<p>This is the normal mode that fields will take.</p>
<details class="danger">
<summary>Don't change Default values</summary>
<p>You generally do not want to change default values after they're initially
defined. Fields that have the default value are not actually stored in the
serialized data (see also Gotchas below). Values explicitly written by code
generated by the old schema old version, if they happen to be the default, will
be read as a different value by code generated with the new schema. This is
slightly less bad when converting an optional scalar into a default valued
scalar since non-presence would not be overloaded with a previous default value.
There are situations, however, where this may be desirable, especially if you
can ensure a simultaneous rebuild of all code.</p>
</details>
<h4 id="2-optional">2. Optional</h4>
<p>Optional value fields will return some form of <code>null</code> in the language generated.</p>
<div class="tabbed-set tabbed-alternate" data-tabs="1:1"><input checked="checked" id="c" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="c">C++</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><pre><span></span><code><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">field</span><span class="p">;</span>
</code></pre></div>
</div>
</div>
</div>
<p>For optional scalars, just set the field default value to <code>null</code>. If the
producer of the buffer does not explicitly set that field, it will be marked
<code>null</code>.</p>
<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="nl">hp</span><span class="p">:</span><span class="kt">short</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">null</span><span class="p">;</span>
</code></pre></div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Not every languages support scalar defaults yet</p>
</div>
<h4 id="3-required">3. Required</h4>
<p>Required valued fields will cause an error if they are not set. The FlatBuffers
verifier would consider the whole buffer invalid.</p>
<p>This is enabled by the <a href="#required"><code>required</code> attribute</a> on the field.</p>
<div class="highlight"><pre><span></span><code> hp:short (required)
</code></pre></div>
<p>You cannot have <code>required</code> set with an explicit default value, it will result in
a compiler error.</p>
<h2 id="structs">Structs</h2>
<p>Similar to a table, <code>structs</code> consist of fields are required (so no defaults
either), and fields may not be added or be deprecated.</p>
<div class="highlight"><table class="highlighttable"><tr><th colspan="2" class="filename"><span class="filename">monster.fbs - Example Struct</span></th></tr><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">11</span>
<span class="normal">12</span>
<span class="normal">13</span>
<span class="normal">14</span>
<span class="normal">15</span></pre></div></td><td class="code"><div><pre><span></span><code><span class="k">struct</span><span class="w"> </span><span class="nc">Vec3</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nl">x</span><span class="p">:</span><span class="kt">float</span><span class="p">;</span>
<span class="w"> </span><span class="nl">y</span><span class="p">:</span><span class="kt">float</span><span class="p">;</span>
<span class="w"> </span><span class="nl">z</span><span class="p">:</span><span class="kt">float</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></td></tr></table></div>
<p>Structs may only contain scalars or other structs. Use this for simple objects
where you are very sure no changes will ever be made (as quite clear in the
example <code>Vec3</code>). Structs use less memory than tables and are even faster to
access (they are always stored in-line in their parent object, and use no
virtual table).</p>
<h3 id="arrays">Arrays</h3>
<p>Arrays are a convenience short-hand for a fixed-length collection of elements.
Arrays allow the following syntax, while maintaining binary equivalency.</p>
<div class="grid cards">
<ul>
<li><strong>Normal Syntax</strong></li>
</ul>
<p>===</p>
<div class="highlight"><pre><span></span><code><span class="k">struct</span><span class="w"> </span><span class="nc">Vec3</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nl">x</span><span class="p">:</span><span class="kt">float</span><span class="p">;</span>
<span class="w"> </span><span class="nl">y</span><span class="p">:</span><span class="kt">float</span><span class="p">;</span>
<span class="w"> </span><span class="nl">z</span><span class="p">:</span><span class="kt">float</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>
<ul>
<li><strong>Array Syntax</strong></li>
</ul>
<p>===</p>
<div class="highlight"><pre><span></span><code><span class="k">struct</span><span class="w"> </span><span class="nc">Vec3</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="nl">v</span><span class="p">:[</span><span class="kt">float</span><span class="o">:</span><span class="mi">3</span><span class="p">];</span>
<span class="p">}</span>
</code></pre></div>
</div>
<p>Arrays are currently only supported in a <code>struct</code>.</p>
<h2 id="types">Types</h2>
<p>The following are the built-in types that can be used in FlatBuffers.</p>
<h3 id="scalars">Scalars</h3>
<p>The standard assortment of fixed sized scalars are available. There are no
variable sized integers (e.g., <code>varints</code>).</p>
<table>
<thead>
<tr>
<th>Size</th>
<th>Signed</th>
<th>Unsigned</th>
<th>Floating Point</th>
</tr>
</thead>
<tbody>
<tr>
<td>8-bit</td>
<td><code>byte</code>, <code>bool</code></td>
<td><code>ubyte</code> (<code>uint8</code>)</td>
<td></td>
</tr>
<tr>
<td>16-bit</td>
<td><code>short</code> (<code>int16</code>)</td>
<td><code>ushort</code> (<code>uint16</code>)</td>
<td></td>
</tr>
<tr>
<td>32-bit</td>
<td><code>int</code> (<code>int32</code>)</td>
<td><code>uint</code> (<code>uint32</code>)</td>
<td><code>float</code> (<code>float32</code>)</td>
</tr>
<tr>
<td>64-bit</td>
<td><code>long</code> (<code>int64</code>)</td>
<td><code>ulong</code> (<code>uint64</code>)</td>
<td><code>double</code> (<code>float64</code>)</td>
</tr>
</tbody>
</table>
<p>The type names in parentheses are alias names such that for example <code>uint8</code> can
be used in place of <code>ubyte</code>, and <code>int32</code> can be used in place of <code>int</code> without
affecting code generation.</p>
<h3 id="non-scalars">Non-scalars</h3>
<h4 id="vectors">Vectors</h4>
<p>Vector of any other type (denoted with <code>[type]</code>).</p>
<div class="highlight"><pre><span></span><code><span class="nl">inventory</span><span class="p">:[</span><span class="n">ubyte</span><span class="p">];</span>
</code></pre></div>
<div class="admonition note">
<p class="admonition-title">Nesting vectors</p>
<p>Nesting vectors is not supported, instead you can wrap the inner vector with
a table.</p>
<div class="highlight"><pre><span></span><code>table nest{
a:[ubyte]
}
table monster {
a:[nest]
}
</code></pre></div>
</div>
<h4 id="strings">Strings</h4>
<p>Strings (indicated by <code>string</code>) are zero-terminated strings, prefixed by their
length. Strings may only hold UTF-8 or 7-bit ASCII. For other text encodings or
general binary data use vectors (<code>[byte]</code> or <code>[ubyte]</code>) instead.</p>
<div class="highlight"><pre><span></span><code><span class="nl">name</span><span class="p">:</span><span class="n">string</span><span class="p">;</span>
</code></pre></div>
<h2 id="enums">Enums</h2>
<p>Define a sequence of named constants, each with a given value, or increasing by
one from the previous one. The default first value is <code>0</code>. As you can see in the
enum declaration, you specify the underlying integral type of the enum with <code>:</code>
(in this case <code>byte</code>), which then determines the type of any fields declared
with this enum type.</p>
<p>Only integer types are allowed, i.e. <code>byte</code>, <code>ubyte</code>, <code>short</code> <code>ushort</code>, <code>int</code>,
<code>uint</code>, <code>long</code> and <code>ulong</code>.</p>
<p>Typically, enum values should only ever be added, never removed (there is no
deprecation for enums). This requires code to handle forwards compatibility
itself, by handling unknown enum values.</p>
<h2 id="unions">Unions</h2>
<p>Unions share a lot of properties with enums, but instead of new names for
constants, you use names of tables. You can then declare a union field, which
can hold a reference to any of those types, and additionally a field with the
suffix <code>_type</code> is generated that holds the corresponding enum value, allowing
you to know which type to cast to at runtime.</p>
<p>It's possible to give an alias name to a type union. This way a type can even be
used to mean different things depending on the name used:</p>
<div class="highlight"><pre><span></span><code>table PointPosition { x:uint; y:uint; }
table MarkerPosition {}
union Position {
Start:MarkerPosition,
Point:PointPosition,
Finish:MarkerPosition
}
</code></pre></div>
<p>Unions contain a special <code>NONE</code> marker to denote that no value is stored so that
name cannot be used as an alias.</p>
<p>Unions are a good way to be able to send multiple message types as a FlatBuffer.
Note that because a union field is really two fields, it must always be part of
a table, it cannot be the root of a FlatBuffer by itself.</p>
<p>If you have a need to distinguish between different FlatBuffers in a more
open-ended way, for example for use as files, see the file identification
feature below.</p>
<p>There is an experimental support only in C++ for a vector of unions (and types).
In the example IDL file above, use [Any] to add a vector of Any to Monster
table. There is also experimental support for other types besides tables in
unions, in particular structs and strings. There's no direct support for scalars
in unions, but they can be wrapped in a struct at no space cost.</p>
<h2 id="namespaces">Namespaces</h2>
<p>These will generate the corresponding namespace in C++ for all helper code, and
packages in Java. You can use <code>.</code> to specify nested namespaces / packages.</p>
<h2 id="includes">Includes</h2>
<p>You can include other schemas files in your current one, e.g.:</p>
<div class="highlight"><pre><span></span><code>include &quot;mydefinitions.fbs&quot;;
</code></pre></div>
<p>This makes it easier to refer to types defined elsewhere. <code>include</code>
automatically ensures each file is parsed just once, even when referred to more
than once.</p>
<p>When using the <code>flatc</code> compiler to generate code for schema definitions, only
definitions in the current file will be generated, not those from the included
files (those you still generate separately).</p>
<h2 id="root-type">Root type</h2>
<p>This declares what you consider to be the root table of the serialized data.
This is particularly important for parsing JSON data, which doesn't include
object type information.</p>
<h2 id="file-identification-and-extension">File identification and extension</h2>
<p>Typically, a FlatBuffer binary buffer is not self-describing, i.e. it needs you
to know its schema to parse it correctly. But if you want to use a FlatBuffer as
a file format, it would be convenient to be able to have a "magic number" in
there, like most file formats have, to be able to do a sanity check to see if
you're reading the kind of file you're expecting.</p>
<p>Now, you can always prefix a FlatBuffer with your own file header, but
FlatBuffers has a built-in way to add an identifier to a FlatBuffer that takes
up minimal space, and keeps the buffer compatible with buffers that don't have
such an identifier.</p>
<p>You can specify in a schema, similar to <code>root_type</code>, that you intend for this
type of FlatBuffer to be used as a file format:</p>
<div class="highlight"><pre><span></span><code>file_identifier &quot;MYFI&quot;;
</code></pre></div>
<p>Identifiers must always be exactly 4 characters long. These 4 characters will
end up as bytes at offsets 4-7 (inclusive) in the buffer.</p>
<p>For any schema that has such an identifier, <code>flatc</code> will automatically add the
identifier to any binaries it generates (with <code>-b</code>), and generated calls like
<code>FinishMonsterBuffer</code> also add the identifier. If you have specified an
identifier and wish to generate a buffer without one, you can always still do so
by calling <code>FlatBufferBuilder::Finish</code> explicitly.</p>
<p>After loading a buffer, you can use a call like <code>MonsterBufferHasIdentifier</code> to
check if the identifier is present.</p>
<p>Note that this is best for open-ended uses such as files. If you simply wanted
to send one of a set of possible messages over a network for example, you'd be
better off with a union.</p>
<p>Additionally, by default <code>flatc</code> will output binary files as <code>.bin</code>. This
declaration in the schema will change that to whatever you want:</p>
<div class="highlight"><pre><span></span><code>file_extension &quot;ext&quot;;
</code></pre></div>
<h2 id="rpc-interface-declarations">RPC interface declarations</h2>
<p>You can declare RPC calls in a schema, that define a set of functions that take
a FlatBuffer as an argument (the request) and return a FlatBuffer as the
response (both of which must be table types):</p>
<div class="highlight"><pre><span></span><code>rpc_service MonsterStorage {
Store(Monster):StoreResponse;
Retrieve(MonsterId):Monster;
}
</code></pre></div>
<p>What code this produces and how it is used depends on language and RPC system
used, there is preliminary support for GRPC through the <code>--grpc</code> code generator,
see <code>grpc/tests</code> for an example.</p>
<h2 id="comments-documentation">Comments &amp; documentation</h2>
<p>May be written as in most C-based languages. Additionally, a triple comment
(<code>///</code>) on a line by itself signals that a comment is documentation for whatever
is declared on the line after it (table/struct/field/enum/union/element), and
the comment is output in the corresponding C++ code. Multiple such lines per
item are allowed.</p>
<h2 id="attributes">Attributes</h2>
<p>Attributes may be attached to a declaration, behind a field/enum value, or after
the name of a table/struct/enum/union. These may either have a value or not.
Some attributes like <code>deprecated</code> are understood by the compiler; user defined
ones need to be declared with the attribute declaration (like <code>priority</code> in the
example above), and are available to query if you parse the schema at runtime.
This is useful if you write your own code generators/editors etc., and you wish
to add additional information specific to your tool (such as a help text).</p>
<p>Current understood attributes:</p>
<ul>
<li><code>id: n</code> (on a table field): manually set the field identifier to <code>n</code>. If you
use this attribute, you must use it on ALL fields of this table, and the
numbers must be a contiguous range from 0 onwards. Additionally, since a union
type effectively adds two fields, its id must be that of the second field (the
first field is the type field and not explicitly declared in the schema). For
example, if the last field before the union field had id 6, the union field
should have id 8, and the unions type field will implicitly be 7. IDs allow
the fields to be placed in any order in the schema. When a new field is added
to the schema it must use the next available ID.</li>
<li><code>deprecated</code> (on a field): do not generate accessors for this field anymore,
code should stop using this data. Old data may still contain this field, but
it won't be accessible anymore by newer code. Note that if you deprecate a
field that was previous required, old code may fail to validate new data (when
using the optional verifier).</li>
</ul>
<h3 id="required"><code>required</code></h3>
<ul>
<li><code>required</code> (on a non-scalar table field): this field must always be set. By
default, fields do not need to be present in the binary. This is desirable, as
it helps with forwards/backwards compatibility, and flexibility of data
structures. By specifying this attribute, you make non- presence in an error
for both reader and writer. The reading code may access the field directly,
without checking for null. If the constructing code does not initialize this
field, they will get an assert, and also the verifier will fail on buffers
that have missing required fields. Both adding and removing this attribute may
be forwards/backwards incompatible as readers will be unable read old or new
data, respectively, unless the data happens to always have the field set.</li>
<li><code>force_align: size</code> (on a struct): force the alignment of this struct to be
something higher than what it is naturally aligned to. Causes these structs to
be aligned to that amount inside a buffer, IF that buffer is allocated with
that alignment (which is not necessarily the case for buffers accessed
directly inside a <code>FlatBufferBuilder</code>). Note: currently not guaranteed to have
an effect when used with <code>--object-api</code>, since that may allocate objects at
alignments less than what you specify with <code>force_align</code>.</li>
<li><code>force_align: size</code> (on a vector): force the alignment of this vector to be
something different than what the element size would normally dictate. Note:
Now only work for generated C++ code.</li>
<li><code>bit_flags</code> (on an unsigned enum): the values of this field indicate bits,
meaning that any unsigned value N specified in the schema will end up
representing 1&lt;&lt;N, or if you don't specify values at all, you'll get the
sequence 1, 2, 4, 8, ...</li>
<li><code>nested_flatbuffer: "table_name"</code> (on a field): this indicates that the field
(which must be a vector of ubyte) contains flatbuffer data, for which the root
type is given by <code>table_name</code>. The generated code will then produce a
convenient accessor for the nested FlatBuffer.</li>
<li><code>flexbuffer</code> (on a field): this indicates that the field (which must be a
vector of ubyte) contains flexbuffer data. The generated code will then
produce a convenient accessor for the FlexBuffer root.</li>
<li><code>key</code> (on a field): this field is meant to be used as a key when sorting a
vector of the type of table it sits in. Can be used for in-place binary
search.</li>
<li><code>hash</code> (on a field). This is an (un)signed 32/64 bit integer field, whose
value during JSON parsing is allowed to be a string, which will then be stored
as its hash. The value of attribute is the hashing algorithm to use, one of
<code>fnv1_32</code> <code>fnv1_64</code> <code>fnv1a_32</code> <code>fnv1a_64</code>.</li>
<li><code>original_order</code> (on a table): since elements in a table do not need to be
stored in any particular order, they are often optimized for space by sorting
them to size. This attribute stops that from happening. There should generally
not be any reason to use this flag.</li>
<li>'native<em>*'. Several attributes have been added to support the C++ object
Based API. All such attributes are prefixed with the term "native</em>".</li>
</ul>
<h2 id="json-parsing">JSON Parsing</h2>
<p>The same parser that parses the schema declarations above is also able to parse
JSON objects that conform to this schema. So, unlike other JSON parsers, this
parser is strongly typed, and parses directly into a FlatBuffer (see the
compiler documentation on how to do this from the command line, or the C++
documentation on how to do this at runtime).</p>
<p>Besides needing a schema, there are a few other changes to how it parses JSON:</p>
<ul>
<li>It accepts field names with and without quotes, like many JSON parsers already
do. It outputs them without quotes as well, though can be made to output them
using the <code>strict_json</code> flag.</li>
<li>If a field has an enum type, the parser will recognize symbolic enum values
(with or without quotes) instead of numbers, e.g. <code>field: EnumVal</code>. If a field
is of integral type, you can still use symbolic names, but values need to be
prefixed with their type and need to be quoted, e.g. <code>field: "Enum.EnumVal"</code>.
For enums representing flags, you may place multiple inside a string separated
by spaces to OR them, e.g. <code>field: "EnumVal1 EnumVal2"</code> or
<code>field: "Enum.EnumVal1 Enum.EnumVal2"</code>.</li>
<li>Similarly, for unions, these need to specified with two fields much like you
do when serializing from code. E.g. for a field <code>foo</code>, you must add a field
<code>foo_type: FooOne</code> right before the <code>foo</code> field, where <code>FooOne</code> would be the
table out of the union you want to use.</li>
<li>A field that has the value <code>null</code> (e.g. <code>field: null</code>) is intended to have the
default value for that field (thus has the same effect as if that field wasn't
specified at all).</li>
<li>It has some built in conversion functions, so you can write for example
<code>rad(180)</code> where ever you'd normally write <code>3.14159</code>. Currently supports the
following functions: <code>rad</code>, <code>deg</code>, <code>cos</code>, <code>sin</code>, <code>tan</code>, <code>acos</code>, <code>asin</code>,
<code>atan</code>.</li>
</ul>
<p>When parsing JSON, it recognizes the following escape codes in strings:</p>
<ul>
<li><code>\n</code> - linefeed.</li>
<li><code>\t</code> - tab.</li>
<li><code>\r</code> - carriage return.</li>
<li><code>\b</code> - backspace.</li>
<li><code>\f</code> - form feed.</li>
<li><code>\"</code> - double quote.</li>
<li><code>\\</code> - backslash.</li>
<li><code>\/</code> - forward slash.</li>
<li><code>\uXXXX</code> - 16-bit unicode code point, converted to the equivalent UTF-8
representation.</li>
<li><code>\xXX</code> - 8-bit binary hexadecimal number XX. This is the only one that is not
in the JSON spec (see http://json.org/), but is needed to be able to encode
arbitrary binary in strings to text and back without losing information (e.g.
the byte 0xFF can't be represented in standard JSON).</li>
</ul>
<p>It also generates these escape codes back again when generating JSON from a
binary representation.</p>
<p>When parsing numbers, the parser is more flexible than JSON. A format of numeric
literals is more close to the C/C++. According to the
<a href="../grammar/">grammar</a>, it accepts the following numerical literals:</p>
<ul>
<li>An integer literal can have any number of leading zero <code>0</code> digits. Unlike
C/C++, the parser ignores a leading zero, not interpreting it as the beginning
of the octal number. The numbers <code>[081, -00094]</code> are equal to <code>[81, -94]</code>
decimal integers.</li>
<li>The parser accepts unsigned and signed hexadecimal integer numbers. For
example: <code>[0x123, +0x45, -0x67]</code> are equal to <code>[291, 69, -103]</code> decimals.</li>
<li>The format of float-point numbers is fully compatible with C/C++ format. If a
modern C++ compiler is used the parser accepts hexadecimal and special
floating-point literals as well:
<code>[-1.0, 2., .3e0, 3.e4, 0x21.34p-5, -inf, nan]</code>.</li>
</ul>
<p>The following conventions for floating-point numbers are used:</p>
<ul>
<li>The exponent suffix of hexadecimal floating-point number is mandatory.</li>
<li>Parsed <code>NaN</code> converted to unsigned IEEE-754 <code>quiet-NaN</code> value.</li>
</ul>
<p>Extended floating-point support was tested with:</p>
<ul>
<li>x64 Windows: <code>MSVC2015</code> and higher.</li>
<li>
<p>x64 Linux: <code>LLVM 6.0</code>, <code>GCC 4.9</code> and higher.</p>
</li>
<li>
<p>For compatibility with a JSON lint tool all numeric literals of scalar fields
can be wrapped to quoted string:
<code>"1", "2.0", "0x48A", "0x0C.0Ep-1", "-inf", "true"</code>.</p>
</li>
</ul>
<h2 id="guidelines">Guidelines</h2>
<h3 id="efficiency">Efficiency</h3>
<p>FlatBuffers is all about efficiency, but to realize that efficiency you require
an efficient schema. There are usually multiple choices on how to represent data
that have vastly different size characteristics.</p>
<p>It is very common nowadays to represent any kind of data as dictionaries (as in
e.g. JSON), because of its flexibility and extensibility. While it is possible
to emulate this in FlatBuffers (as a vector of tables with key and value(s)),
this is a bad match for a strongly typed system like FlatBuffers, leading to
relatively large binaries. FlatBuffer tables are more flexible than
classes/structs in most systems, since having a large number of fields only few
of which are actually used is still efficient. You should thus try to organize
your data as much as possible such that you can use tables where you might be
tempted to use a dictionary.</p>
<p>Similarly, strings as values should only be used when they are truly open-ended.
If you can, always use an enum instead.</p>
<p>FlatBuffers doesn't have inheritance, so the way to represent a set of related
data structures is a union. Unions do have a cost however, so an alternative to
a union is to have a single table that has all the fields of all the data
structures you are trying to represent, if they are relatively similar / share
many fields. Again, this is efficient because non-present fields are cheap.</p>
<p>FlatBuffers supports the full range of integer sizes, so try to pick the
smallest size needed, rather than defaulting to int/long.</p>
<p>Remember that you can share data (refer to the same string/table within a
buffer), so factoring out repeating data into its own data structure may be
worth it.</p>
<h3 id="style-guide">Style guide</h3>
<p>Identifiers in a schema are meant to translate to many different programming
languages, so using the style of your "main" language is generally a bad idea.</p>
<p>For this reason, below is a suggested style guide to adhere to, to keep schemas
consistent for interoperation regardless of the target language.</p>
<p>Where possible, the code generators for specific languages will generate
identifiers that adhere to the language style, based on the schema identifiers.</p>
<ul>
<li>Table, struct, enum and rpc names (types): UpperCamelCase.</li>
<li>Table and struct field names: snake_case. This is translated to lowerCamelCase
automatically for some languages, e.g. Java.</li>
<li>Enum values: UpperCamelCase.</li>
<li>namespaces: UpperCamelCase.</li>
</ul>
<p>Formatting (this is less important, but still worth adhering to):</p>
<ul>
<li>Opening brace: on the same line as the start of the declaration.</li>
<li>Spacing: Indent by 2 spaces. None around <code>:</code> for types, on both sides for <code>=</code>.</li>
</ul>
<p>For an example, see the schema at the top of this file.</p>
<h2 id="gotchas">Gotchas</h2>
<h3 id="testing-whether-a-field-is-present-in-a-table">Testing whether a field is present in a table</h3>
<p>Most serialization formats (e.g. JSON or Protocol Buffers) make it very explicit
in the format whether a field is present in an object or not, allowing you to
use this as "extra" information.</p>
<p>FlatBuffers will not write fields that are equal to their default value,
sometimes resulting in significant space savings. However, this also means we
cannot disambiguate the meaning of non-presence as "written default value" or
"not written at all". This only applies to scalar fields since only they support
default values. Unless otherwise specified, their default is 0.</p>
<p>If you care about the presence of scalars, most languages support "optional
scalars." You can set <code>null</code> as the default value in the schema. <code>null</code> is a
value that's outside of all types, so we will always write if <code>add_field</code> is
called. The generated field accessor should use the local language's canonical
optional type.</p>
<p>Some <code>FlatBufferBuilder</code> implementations have an option called <code>force_defaults</code>
that circumvents this "not writing defaults" behavior you can then use
<code>IsFieldPresent</code> to query presence. / Another option that works in all languages
is to wrap a scalar field in a struct. This way it will return null if it is not
present. This will be slightly less ergonomic but structs don't take up any more
space than the scalar they represent.</p>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href="../flatc/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Using">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Previous
</span>
<div class="md-ellipsis">
Using
</div>
</div>
</a>
<a href="../evolution/" class="md-footer__link md-footer__link--next" aria-label="Next: Evolution">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Evolution
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2025 Google
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
<div class="md-social">
<a href="https://github.com/google/flatbuffers" target="_blank" rel="noopener" title="github.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path fill="currentColor" d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</a>
<a href="https:///discord.gg/6qgKs3R" target="_blank" rel="noopener" title="" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path fill="currentColor" d="M492.5 69.8c-.2-.3-.4-.6-.8-.7-38.1-17.5-78.4-30-119.7-37.1-.4-.1-.8 0-1.1.1s-.6.4-.8.8c-5.5 9.9-10.5 20.2-14.9 30.6-44.6-6.8-89.9-6.8-134.4 0-4.5-10.5-9.5-20.7-15.1-30.6-.2-.3-.5-.6-.8-.8s-.7-.2-1.1-.2C162.5 39 122.2 51.5 84.1 69c-.3.1-.6.4-.8.7C7.1 183.5-13.8 294.6-3.6 404.2c0 .3.1.5.2.8s.3.4.5.6c44.4 32.9 94 58 146.8 74.2.4.1.8.1 1.1 0s.7-.4.9-.7c11.3-15.4 21.4-31.8 30-48.8.1-.2.2-.5.2-.8s0-.5-.1-.8-.2-.5-.4-.6-.4-.3-.7-.4c-15.8-6.1-31.2-13.4-45.9-21.9-.3-.2-.5-.4-.7-.6s-.3-.6-.3-.9 0-.6.2-.9.3-.5.6-.7c3.1-2.3 6.2-4.7 9.1-7.1.3-.2.6-.4.9-.4s.7 0 1 .1c96.2 43.9 200.4 43.9 295.5 0 .3-.1.7-.2 1-.2s.7.2.9.4c2.9 2.4 6 4.9 9.1 7.2.2.2.4.4.6.7s.2.6.2.9-.1.6-.3.9-.4.5-.6.6c-14.7 8.6-30 15.9-45.9 21.8-.2.1-.5.2-.7.4s-.3.4-.4.7-.1.5-.1.8.1.5.2.8c8.8 17 18.8 33.3 30 48.8.2.3.6.6.9.7s.8.1 1.1 0c52.9-16.2 102.6-41.3 147.1-74.2.2-.2.4-.4.5-.6s.2-.5.2-.8c12.3-126.8-20.5-236.9-86.9-334.5zm-302 267.7c-29 0-52.8-26.6-52.8-59.2s23.4-59.2 52.8-59.2c29.7 0 53.3 26.8 52.8 59.2 0 32.7-23.4 59.2-52.8 59.2m195.4 0c-29 0-52.8-26.6-52.8-59.2s23.4-59.2 52.8-59.2c29.7 0 53.3 26.8 52.8 59.2 0 32.7-23.2 59.2-52.8 59.2"/></svg>
</a>
<a href="https://twitter.com/dbaileychess" target="_blank" rel="noopener" title="twitter.com" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path fill="currentColor" d="M357.2 48h70.6L273.6 224.2 455 464H313L201.7 318.6 74.5 464H3.8l164.9-188.5L-5.2 48h145.6l100.5 132.9zm-24.8 373.8h39.1L119.1 88h-42z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "..", "features": ["content.code.annotate", "content.tabs.link", "navigation.expand", "navigation.footer", "header.autohide", "content.action.edit"], "search": "../assets/javascripts/workers/search.d50fe291.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.50899def.min.js"></script>
</body>
</html>