Open source · MIT license · Java 17+

Your Java models, as FlatBuffers schemas.

Aurkitu (Basque for “to find”) reads your annotated Java and Kotlin classes at build time and writes the FlatBuffers schema (.fbs) for them. Your server-side models stay the single source of truth, and every client language flatc supports gets the same types.

Latest release 1.4.0 on Maven Central and the Gradle Plugin Portal

  1. Java / Kotlin models@FlatBufferTable
  2. AurkituMaven · Gradle plugin
  3. Schemauser.fbs
  4. flatcFlatBuffers compiler
  5. Client codeC# · Swift · TS · Go · Rust …
Aurkitu writes and validates the schema. flatc, the FlatBuffers compiler, turns it into code for each client.

What it does

Maven or Gradle

A Maven plugin and a Gradle plugin with the same options, built on the same generator, so both write the same schema byte for byte.

The whole schema language

Tables, structs, enums (including bit_flags), unions, maps, inheritance, field ids and attributes, optional scalars, RPC services, namespaces, includes and documentation comments.

Schemas that compile

Validation of the rules flatc enforces, tested against flatc itself, with an optional check by flatc in your build.

Your models as they are

Classes of any visibility, in your project or in a dependency, scanned from the compile classpath. Kotlin JVM classes work too.

Any client language

flatc turns the schema into code for C#, Swift, TypeScript, Go, Rust, C++, Python and more, so every client shares your Java models.

Verifiable releases

Reproducible builds, signed artifacts, SLSA provenance on every GitHub release, and the OpenSSF Scorecard and Best Practices badges.

Quick start

1 Add the annotations and the plugin

pom.xml

<dependencies>
    <dependency>
        <groupId>io.github.mhradek</groupId>
        <artifactId>aurkitu-annotations</artifactId>
        <version>1.4.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>io.github.mhradek</groupId>
            <artifactId>aurkitu-maven-plugin</artifactId>
            <version>1.4.0</version>
            <configuration>
                <schemaName>user</schemaName>
                <schemaNamespace>com.example.flatbuffers</schemaNamespace>
                <specifiedPackages>
                    <specifiedPackage>com.example.models</specifiedPackage>
                </specifiedPackages>
            </configuration>
            <executions>
                <execution>
                    <goals><goal>build-schema</goal></goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

build.gradle.kts

plugins {
    java
    id("io.github.mhradek.aurkitu") version "1.4.0"
}

dependencies {
    implementation("io.github.mhradek:aurkitu-annotations:1.4.0")
}

aurkitu {
    schemaName = "user"
    schemaNamespace = "com.example.flatbuffers"
    specifiedPackages = listOf("com.example.models")
}

specifiedPackages is optional but recommended: it limits scanning to your model packages.

2 Annotate your models

import io.github.mhradek.aurkitu.annotations.FlatBufferTable;

@FlatBufferTable(rootType = true)
public class User {
    private long id;
    private String name;
}

3 Build

mvn package writes target/aurkitu/schemas/user.fbs, and gradle build writes build/aurkitu/schemas/user.fbs:

// Aurkitu 1.4.0 automatically generated FlatBuffer schema
namespace com.example.flatbuffers;

table User {
  id:long;
  name:string;
}

root_type User;

Then compile it with flatc for the languages you need: see using the schema from other languages.

A fuller example

Part of the sample game model, built with schemaNamespace = com.example.game.fb. Comments, defaults, required fields, enums and maps carry over; a field marked @FlatBufferIgnore stays on the server.

Player.java, Status.java

@FlatBufferComment(comment = "A player and what a client shows about them.")
@FlatBufferTable(rootType = true)
public class Player {
    private long id;
    @FlatBufferFieldOptions(fieldType = FieldType.STRING, required = true)
    private String displayName;
    @FlatBufferComment(comment = "Starts at 1.")
    @FlatBufferFieldOptions(fieldType = FieldType.INT, defaultValue = "1")
    private int level;
    private Status status;
    @FlatBufferComment(comment = "Free-form counters, e.g. \"wins\".")
    private Map<String, Integer> stats;
    @FlatBufferIgnore
    private String sessionToken;
}

@FlatBufferEnum
public enum Status {
    OFFLINE,
    ONLINE,
    @FlatBufferComment(comment = "Playing a match right now.")
    IN_MATCH
}

game.fbs

namespace com.example.game.fb;

enum Status : byte {
  OFFLINE,
  ONLINE,
  /// Playing a match right now.
  IN_MATCH,
}

/// A player and what a client shows about them.
table Player {
  id:long;
  display_name:string (required);
  /// Starts at 1.
  level:int = 1;
  status:Status;
  /// Free-form counters, e.g. "wins".
  stats:[MapValueSet_Player_stats];
}

table MapValueSet_Player_stats {
  key:string;
  value:int;
}

root_type Player;

Documentation and downloads