diff --git a/src/bfbs_gen_lua.cpp b/src/bfbs_gen_lua.cpp
new file mode 100644
index 0000000..868bb14
--- /dev/null
+++ b/src/bfbs_gen_lua.cpp
@@ -0,0 +1,628 @@
+/*
+ * Copyright 2021 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bfbs_gen_lua.h"
+
+#include <cstdint>
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_set>
+#include <vector>
+
+// Ensure no includes to flatc internals. bfbs_gen.h and generator.h are OK.
+#include "bfbs_gen.h"
+#include "flatbuffers/bfbs_generator.h"
+
+// The intermediate representation schema.
+#include "flatbuffers/reflection_generated.h"
+
+namespace flatbuffers {
+namespace {
+
+// To reduce typing
+namespace r = ::reflection;
+
+class LuaBfbsGenerator : public BaseBfbsGenerator {
+ public:
+  explicit LuaBfbsGenerator(const std::string &flatc_version)
+      : BaseBfbsGenerator(),
+        keywords_(),
+        requires_(),
+        current_obj_(nullptr),
+        current_enum_(nullptr),
+        flatc_version_(flatc_version) {
+    static const char *const keywords[] = {
+      "and",      "break",  "do",   "else", "elseif", "end",  "false", "for",
+      "function", "goto",   "if",   "in",   "local",  "nil",  "not",   "or",
+      "repeat",   "return", "then", "true", "until",  "while"
+    };
+    keywords_.insert(std::begin(keywords), std::end(keywords));
+  }
+
+  GeneratorStatus GenerateFromSchema(const r::Schema *schema)
+      FLATBUFFERS_OVERRIDE {
+    if (!GenerateEnums(schema->enums())) { return FAILED; }
+    if (!GenerateObjects(schema->objects(), schema->root_table())) {
+      return FAILED;
+    }
+    return OK;
+  }
+
+  uint64_t SupportedAdvancedFeatures() const FLATBUFFERS_OVERRIDE {
+    return 0xF;
+  }
+
+ protected:
+  bool GenerateEnums(
+      const flatbuffers::Vector<flatbuffers::Offset<r::Enum>> *enums) {
+    ForAllEnums(enums, [&](const r::Enum *enum_def) {
+      std::string code;
+
+      StartCodeBlock(enum_def);
+
+      std::string ns;
+      const std::string enum_name =
+          NormalizeName(Denamespace(enum_def->name(), ns));
+
+      GenerateDocumentation(enum_def->documentation(), "", code);
+      code += "local " + enum_name + " = {\n";
+
+      ForAllEnumValues(enum_def, [&](const reflection::EnumVal *enum_val) {
+        GenerateDocumentation(enum_val->documentation(), "  ", code);
+        code += "  " + NormalizeName(enum_val->name()) + " = " +
+                NumToString(enum_val->value()) + ",\n";
+      });
+      code += "}\n";
+      code += "\n";
+
+      EmitCodeBlock(code, enum_name, ns, enum_def->declaration_file()->str());
+    });
+    return true;
+  }
+
+  bool GenerateObjects(
+      const flatbuffers::Vector<flatbuffers::Offset<r::Object>> *objects,
+      const r::Object *root_object) {
+    ForAllObjects(objects, [&](const r::Object *object) {
+      std::string code;
+
+      StartCodeBlock(object);
+
+      // Register the main flatbuffers module.
+      RegisterRequires("flatbuffers", "flatbuffers");
+
+      std::string ns;
+      const std::string object_name =
+          NormalizeName(Denamespace(object->name(), ns));
+
+      GenerateDocumentation(object->documentation(), "", code);
+
+      code += "local " + object_name + " = {}\n";
+      code += "local mt = {}\n";
+      code += "\n";
+      code += "function " + object_name + ".New()\n";
+      code += "  local o = {}\n";
+      code += "  setmetatable(o, {__index = mt})\n";
+      code += "  return o\n";
+      code += "end\n";
+      code += "\n";
+
+      if (object == root_object) {
+        code += "function " + object_name + ".GetRootAs" + object_name +
+                "(buf, offset)\n";
+        code += "  if type(buf) == \"string\" then\n";
+        code += "    buf = flatbuffers.binaryArray.New(buf)\n";
+        code += "  end\n";
+        code += "\n";
+        code += "  local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)\n";
+        code += "  local o = " + object_name + ".New()\n";
+        code += "  o:Init(buf, n + offset)\n";
+        code += "  return o\n";
+        code += "end\n";
+        code += "\n";
+      }
+
+      // Generates a init method that receives a pre-existing accessor object,
+      // so that objects can be reused.
+
+      code += "function mt:Init(buf, pos)\n";
+      code += "  self.view = flatbuffers.view.New(buf, pos)\n";
+      code += "end\n";
+      code += "\n";
+
+      // Create all the field accessors.
+      ForAllFields(object, /*reverse=*/false, [&](const r::Field *field) {
+        // Skip writing deprecated fields altogether.
+        if (field->deprecated()) { return; }
+
+        const std::string field_name = NormalizeName(field->name());
+        const std::string field_name_camel_case =
+            ConvertCase(field_name, Case::kUpperCamel);
+        const r::BaseType base_type = field->type()->base_type();
+
+        // Generate some fixed strings so we don't repeat outselves later.
+        const std::string getter_signature =
+            "function mt:" + field_name_camel_case + "()\n";
+        const std::string offset_prefix = "local o = self.view:Offset(" +
+                                          NumToString(field->offset()) + ")\n";
+        const std::string offset_prefix_2 = "if o ~= 0 then\n";
+
+        GenerateDocumentation(field->documentation(), "", code);
+
+        if (IsScalar(base_type)) {
+          code += getter_signature;
+
+          if (object->is_struct()) {
+            // TODO(derekbailey): it would be nice to modify the view:Get to
+            // just pass in the offset and not have to add it its own
+            // self.view.pos.
+            code += "  return " + GenerateGetter(field->type()) +
+                    "self.view.pos + " + NumToString(field->offset()) + ")\n";
+          } else {
+            // Table accessors
+            code += "  " + offset_prefix;
+            code += "  " + offset_prefix_2;
+
+            std::string getter =
+                GenerateGetter(field->type()) + "self.view.pos + o)";
+            if (IsBool(base_type)) { getter = "(" + getter + " ~=0)"; }
+            code += "    return " + getter + "\n";
+            code += "  end\n";
+            code += "  return " + DefaultValue(field) + "\n";
+          }
+          code += "end\n";
+          code += "\n";
+        } else {
+          switch (base_type) {
+            case r::String: {
+              code += getter_signature;
+              code += "  " + offset_prefix;
+              code += "  " + offset_prefix_2;
+              code += "    return " + GenerateGetter(field->type()) +
+                      "self.view.pos + o)\n";
+              code += "  end\n";
+              code += "end\n";
+              code += "\n";
+              break;
+            }
+            case r::Obj: {
+              if (object->is_struct()) {
+                code += "function mt:" + field_name_camel_case + "(obj)\n";
+                code += "  obj:Init(self.view.bytes, self.view.pos + " +
+                        NumToString(field->offset()) + ")\n";
+                code += "  return obj\n";
+                code += "end\n";
+                code += "\n";
+              } else {
+                code += getter_signature;
+                code += "  " + offset_prefix;
+                code += "  " + offset_prefix_2;
+
+                const r::Object *field_object = GetObject(field->type());
+                if (!field_object) {
+                  // TODO(derekbailey): this is an error condition. we
+                  // should report it better.
+                  return;
+                }
+                code += "    local x = " +
+                        std::string(
+                            field_object->is_struct()
+                                ? "self.view.pos + o\n"
+                                : "self.view:Indirect(self.view.pos + o)\n");
+                const std::string require_name = RegisterRequires(field);
+                code += "    local obj = " + require_name + ".New()\n";
+                code += "    obj:Init(self.view.bytes, x)\n";
+                code += "    return obj\n";
+                code += "  end\n";
+                code += "end\n";
+                code += "\n";
+              }
+              break;
+            }
+            case r::Union: {
+              code += getter_signature;
+              code += "  " + offset_prefix;
+              code += "  " + offset_prefix_2;
+              code +=
+                  "   local obj = "
+                  "flatbuffers.view.New(flatbuffers.binaryArray.New("
+                  "0), 0)\n";
+              code += "    " + GenerateGetter(field->type()) + "obj, o)\n";
+              code += "    return obj\n";
+              code += "  end\n";
+              code += "end\n";
+              code += "\n";
+              break;
+            }
+            case r::Array:
+            case r::Vector: {
+              const r::BaseType vector_base_type = field->type()->element();
+              int32_t element_size = field->type()->element_size();
+              code += "function mt:" + field_name_camel_case + "(j)\n";
+              code += "  " + offset_prefix;
+              code += "  " + offset_prefix_2;
+
+              if (IsStructOrTable(vector_base_type)) {
+                code += "    local x = self.view:Vector(o)\n";
+                code +=
+                    "    x = x + ((j-1) * " + NumToString(element_size) + ")\n";
+                if (IsTable(field->type(), /*use_element=*/true)) {
+                  code += "    x = self.view:Indirect(x)\n";
+                } else {
+                  // Vector of structs are inline, so we need to query the
+                  // size of the struct.
+                  const reflection::Object *obj =
+                      GetObjectByIndex(field->type()->index());
+                  element_size = obj->bytesize();
+                }
+
+                // Include the referenced type, thus we need to make sure
+                // we set `use_element` to true.
+                const std::string require_name =
+                    RegisterRequires(field, /*use_element=*/true);
+                code += "    local obj = " + require_name + ".New()\n";
+                code += "    obj:Init(self.view.bytes, x)\n";
+                code += "    return obj\n";
+              } else {
+                code += "    local a = self.view:Vector(o)\n";
+                code += "    return " + GenerateGetter(field->type()) +
+                        "a + ((j-1) * " + NumToString(element_size) + "))\n";
+              }
+              code += "  end\n";
+              // Only generate a default value for those types that are
+              // supported.
+              if (!IsStructOrTable(vector_base_type)) {
+                code +=
+                    "  return " +
+                    std::string(vector_base_type == r::String ? "''\n" : "0\n");
+              }
+              code += "end\n";
+              code += "\n";
+
+              // If the vector is composed of single byte values, we
+              // generate a helper function to get it as a byte string in
+              // Lua.
+              if (IsSingleByte(vector_base_type)) {
+                code += "function mt:" + field_name_camel_case +
+                        "AsString(start, stop)\n";
+                code += "  return self.view:VectorAsString(" +
+                        NumToString(field->offset()) + ", start, stop)\n";
+                code += "end\n";
+                code += "\n";
+              }
+
+              // We also make a new accessor to query just the length of the
+              // vector.
+              code += "function mt:" + field_name_camel_case + "Length()\n";
+              code += "  " + offset_prefix;
+              code += "  " + offset_prefix_2;
+              code += "    return self.view:VectorLen(o)\n";
+              code += "  end\n";
+              code += "  return 0\n";
+              code += "end\n";
+              code += "\n";
+              break;
+            }
+            default: {
+              return;
+            }
+          }
+        }
+        return;
+      });
+
+      // Create all the builders
+      if (object->is_struct()) {
+        code += "function " + object_name + ".Create" + object_name +
+                "(builder" + GenerateStructBuilderArgs(object) + ")\n";
+        code += AppendStructBuilderBody(object);
+        code += "  return builder:Offset()\n";
+        code += "end\n";
+        code += "\n";
+      } else {
+        // Table builders
+        code += "function " + object_name + ".Start(builder)\n";
+        code += "  builder:StartObject(" +
+                NumToString(object->fields()->size()) + ")\n";
+        code += "end\n";
+        code += "\n";
+
+        ForAllFields(object, /*reverse=*/false, [&](const r::Field *field) {
+          if (field->deprecated()) { return; }
+
+          const std::string field_name = NormalizeName(field->name());
+
+          code += "function " + object_name + ".Add" +
+                  ConvertCase(field_name, Case::kUpperCamel) + "(builder, " +
+                  ConvertCase(field_name, Case::kLowerCamel) + ")\n";
+          code += "  builder:Prepend" + GenerateMethod(field) + "Slot(" +
+                  NumToString(field->id()) + ", " +
+                  ConvertCase(field_name, Case::kLowerCamel) + ", " +
+                  DefaultValue(field) + ")\n";
+          code += "end\n";
+          code += "\n";
+
+          if (IsVector(field->type()->base_type())) {
+            code += "function " + object_name + ".Start" +
+                    ConvertCase(field_name, Case::kUpperCamel) +
+                    "Vector(builder, numElems)\n";
+
+            const int32_t element_size = field->type()->element_size();
+            int32_t alignment = 0;
+            if (IsStruct(field->type(), /*use_element=*/true)) {
+              alignment = GetObjectByIndex(field->type()->index())->minalign();
+            } else {
+              alignment = element_size;
+            }
+
+            code += "  return builder:StartVector(" +
+                    NumToString(element_size) + ", numElems, " +
+                    NumToString(alignment) + ")\n";
+            code += "end\n";
+            code += "\n";
+          }
+        });
+
+        code += "function " + object_name + ".End(builder)\n";
+        code += "  return builder:EndObject()\n";
+        code += "end\n";
+        code += "\n";
+      }
+
+      EmitCodeBlock(code, object_name, ns, object->declaration_file()->str());
+    });
+    return true;
+  }
+
+ private:
+  void GenerateDocumentation(
+      const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>
+          *documentation,
+      std::string indent, std::string &code) const {
+    flatbuffers::ForAllDocumentation(
+        documentation, [&](const flatbuffers::String *str) {
+          code += indent + "--" + str->str() + "\n";
+        });
+  }
+
+  std::string GenerateStructBuilderArgs(const r::Object *object,
+                                        std::string prefix = "") const {
+    std::string signature;
+    ForAllFields(object, /*reverse=*/false, [&](const r::Field *field) {
+      if (IsStructOrTable(field->type()->base_type())) {
+        const r::Object *field_object = GetObject(field->type());
+        signature += GenerateStructBuilderArgs(
+            field_object, prefix + NormalizeName(field->name()) + "_");
+      } else {
+        signature +=
+            ", " + prefix +
+            ConvertCase(NormalizeName(field->name()), Case::kLowerCamel);
+      }
+    });
+    return signature;
+  }
+
+  std::string AppendStructBuilderBody(const r::Object *object,
+                                      std::string prefix = "") const {
+    std::string code;
+    code += "  builder:Prep(" + NumToString(object->minalign()) + ", " +
+            NumToString(object->bytesize()) + ")\n";
+
+    // We need to reverse the order we iterate over, since we build the
+    // buffer backwards.
+    ForAllFields(object, /*reverse=*/true, [&](const r::Field *field) {
+      const int32_t num_padding_bytes = field->padding();
+      if (num_padding_bytes) {
+        code += "  builder:Pad(" + NumToString(num_padding_bytes) + ")\n";
+      }
+      if (IsStructOrTable(field->type()->base_type())) {
+        const r::Object *field_object = GetObject(field->type());
+        code += AppendStructBuilderBody(
+            field_object, prefix + NormalizeName(field->name()) + "_");
+      } else {
+        code += "  builder:Prepend" + GenerateMethod(field) + "(" + prefix +
+                ConvertCase(NormalizeName(field->name()), Case::kLowerCamel) +
+                ")\n";
+      }
+    });
+
+    return code;
+  }
+
+  std::string GenerateMethod(const r::Field *field) const {
+    const r::BaseType base_type = field->type()->base_type();
+    if (IsScalar(base_type)) {
+      return ConvertCase(GenerateType(base_type), Case::kUpperCamel);
+    }
+    if (IsStructOrTable(base_type)) { return "Struct"; }
+    return "UOffsetTRelative";
+  }
+
+  std::string GenerateGetter(const r::Type *type,
+                             bool element_type = false) const {
+    switch (element_type ? type->element() : type->base_type()) {
+      case r::String: return "self.view:String(";
+      case r::Union: return "self.view:Union(";
+      case r::Vector: return GenerateGetter(type, true);
+      default:
+        return "self.view:Get(flatbuffers.N." +
+               ConvertCase(GenerateType(type, element_type),
+                           Case::kUpperCamel) +
+               ", ";
+    }
+  }
+
+  std::string GenerateType(const r::Type *type,
+                           bool element_type = false) const {
+    const r::BaseType base_type =
+        element_type ? type->element() : type->base_type();
+    if (IsScalar(base_type)) { return GenerateType(base_type); }
+    switch (base_type) {
+      case r::String: return "string";
+      case r::Vector: return GenerateGetter(type, true);
+      case r::Obj: {
+        const r::Object *obj = GetObject(type);
+        return NormalizeName(Denamespace(obj->name()));
+      };
+      default: return "*flatbuffers.Table";
+    }
+  }
+
+  std::string GenerateType(const r::BaseType base_type) const {
+    // Need to override the default naming to match the Lua runtime libraries.
+    // TODO(derekbailey): make overloads in the runtime libraries to avoid this.
+    switch (base_type) {
+      case r::None: return "uint8";
+      case r::UType: return "uint8";
+      case r::Byte: return "int8";
+      case r::UByte: return "uint8";
+      case r::Short: return "int16";
+      case r::UShort: return "uint16";
+      case r::Int: return "int32";
+      case r::UInt: return "uint32";
+      case r::Long: return "int64";
+      case r::ULong: return "uint64";
+      case r::Float: return "Float32";
+      case r::Double: return "Float64";
+      default: return r::EnumNameBaseType(base_type);
+    }
+  }
+
+  std::string DefaultValue(const r::Field *field) const {
+    const r::BaseType base_type = field->type()->base_type();
+    if (IsFloatingPoint(base_type)) {
+      return NumToString(field->default_real());
+    }
+    if (IsBool(base_type)) {
+      return field->default_integer() ? "true" : "false";
+    }
+    if (IsScalar(base_type)) { return NumToString((field->default_integer())); }
+    // represents offsets
+    return "0";
+  }
+
+  std::string NormalizeName(const std::string name) const {
+    return keywords_.find(name) == keywords_.end() ? name : "_" + name;
+  }
+
+  std::string NormalizeName(const flatbuffers::String *name) const {
+    return NormalizeName(name->str());
+  }
+
+  void StartCodeBlock(const reflection::Enum *enum_def) {
+    current_enum_ = enum_def;
+    current_obj_ = nullptr;
+    requires_.clear();
+  }
+
+  void StartCodeBlock(const reflection::Object *object) {
+    current_obj_ = object;
+    current_enum_ = nullptr;
+    requires_.clear();
+  }
+
+  std::string RegisterRequires(const r::Field *field,
+                               bool use_element = false) {
+    std::string type_name;
+
+    const r::BaseType type =
+        use_element ? field->type()->element() : field->type()->base_type();
+
+    if (IsStructOrTable(type)) {
+      const r::Object *object = GetObjectByIndex(field->type()->index());
+      if (object == current_obj_) { return Denamespace(object->name()); }
+      type_name = object->name()->str();
+    } else {
+      const r::Enum *enum_def = GetEnumByIndex(field->type()->index());
+      if (enum_def == current_enum_) { return Denamespace(enum_def->name()); }
+      type_name = enum_def->name()->str();
+    }
+
+    // Prefix with double __ to avoid name clashing, since these are defined
+    // at the top of the file and have lexical scoping. Replace '.' with '_'
+    // so it can be a legal identifier.
+    std::string name = "__" + type_name;
+    std::replace(name.begin(), name.end(), '.', '_');
+
+    return RegisterRequires(name, type_name);
+  }
+
+  std::string RegisterRequires(const std::string &local_name,
+                               const std::string &requires_name) {
+    requires_[local_name] = requires_name;
+    return local_name;
+  }
+
+  void EmitCodeBlock(const std::string &code_block, const std::string &name,
+                     const std::string &ns,
+                     const std::string &declaring_file) const {
+    const std::string root_type = schema_->root_table()->name()->str();
+    const std::string root_file =
+        schema_->root_table()->declaration_file()->str();
+    const std::string full_qualified_name = ns.empty() ? name : ns + "." + name;
+
+    std::string code = "--[[ " + full_qualified_name + "\n\n";
+    code +=
+        "  Automatically generated by the FlatBuffers compiler, do not "
+        "modify.\n";
+    code += "  Or modify. I'm a message, not a cop.\n";
+    code += "\n";
+    code += "  flatc version: " + flatc_version_ + "\n";
+    code += "\n";
+    code += "  Declared by  : " + declaring_file + "\n";
+    code += "  Rooting type : " + root_type + " (" + root_file + ")\n";
+    code += "\n--]]\n\n";
+
+    if (!requires_.empty()) {
+      for (auto it = requires_.cbegin(); it != requires_.cend(); ++it) {
+        code += "local " + it->first + " = require('" + it->second + "')\n";
+      }
+      code += "\n";
+    }
+
+    code += code_block;
+    code += "return " + name;
+
+    // Namespaces are '.' deliminted, so replace it with the path separator.
+    std::string path = ns;
+
+    if (path.empty()) {
+      path = ".";
+    } else {
+      std::replace(path.begin(), path.end(), '.', '/');
+    }
+
+    // TODO(derekbailey): figure out a save file without depending on util.h
+    EnsureDirExists(path);
+    const std::string file_name = path + "/" + name + ".lua";
+    SaveFile(file_name.c_str(), code, false);
+  }
+
+  std::unordered_set<std::string> keywords_;
+  std::map<std::string, std::string> requires_;
+  const r::Object *current_obj_;
+  const r::Enum *current_enum_;
+  const std::string flatc_version_;
+};
+}  // namespace
+
+std::unique_ptr<BfbsGenerator> NewLuaBfbsGenerator(
+    const std::string &flatc_version) {
+  return std::unique_ptr<LuaBfbsGenerator>(new LuaBfbsGenerator(flatc_version));
+}
+
+}  // namespace flatbuffers
\ No newline at end of file
