darklua
DocumentationTry itGitHub

Content Loaders


darklua picks a loader for each file based on its extension: Lua and Luau files are parsed, recognized data files are converted to Lua modules, and everything else is left alone.

The loaders field lets you override these defaults or assign a loader to any extension darklua does not recognize. It maps glob patterns to loader names. Patterns are matched in order, and the first one that matches a file will be selected.

Files that match no pattern fall back to the extension-based defaults (see Reference), and files with no recognized loader are skipped.

{
  loaders: {
    "**/*.model.json": "copy",
    "**/*.md": "string",
    "**/*.png": "buffer/base64",
  },
}

Copying files

The copy loader writes files to the output directory unchanged. This is useful for assets that need to end up alongside your processed code, such as Rojo model files:

{
  loaders: {
    "**/*.model.json": "copy",
  },
}

Previously, the usual workaround was to copy these files manually (for example with cp) and then run darklua in-place. The copy loader removes that extra step.

Processing data files

darklua can convert structured data into a Lua module that returns the data as a table. JSON, JSON Lines, TOML, and YAML are supported:

{
  loaders: {
    "**/*.json": "json",
    "**/*.jsonl": "json_lines",
    "**/*.toml": "toml",
    "**/*.yaml": "yaml",
  },
}

A file like config.json becomes config.lua (or config.luau) that returns the converted table. This already worked when bundling; loaders make it available in the regular process flow too.

The json loader parses files with a JSON5 parser, not strict JSON. That means files may include comments, trailing commas, and unquoted keys. The json_lines loader does the same per line: each line is parsed with the JSON5 parser and the module returns a Lua array of the parsed values. The yaml loader also accepts yml as an alias, so "**/*.yml": "yaml" and "**/*.yml": "yml" are equivalent.

Embedding file content

These loaders read a file and create a Lua module that returns its content. They work with any file, including binary files.

  • string: returns the content as a string.
  • buffer: returns the content as a buffer (buffer.fromstring(...)).
  • bytes: returns the content as an array of byte values.
{
  loaders: {
    "**/*.md": "string",
    "**/*.bin": "buffer",
  },
}

Each of these also has encoding variants that compress or encode the content before embedding it:

  • /base64: string/base64, buffer/base64, and bytes/base64
  • /zstd: string/zstd, buffer/zstd, and bytes/zstd
  • /gzip: string/gzip, buffer/gzip, and bytes/gzip
  • /zlib: string/zlib, buffer/zlib, and bytes/zlib

These variants keep binary data safe inside the generated Lua source and can reduce the size of large embedded files. Note that encoded or compressed content is not decoded at runtime, so your code receives the encoded value and must decode or decompress it yourself.

Unlike the data loaders (json, json_lines, toml, yaml) and luau, which require valid UTF-8 input, the embedding loaders accept any file content and work correctly with binary files.

Skipping files

The skip loader ignores matching files. Use it to exclude files that would otherwise be picked up by a default loader:

{
  loaders: {
    "**/*.test.json": "skip",
  },
}

Choosing the Lua extension

Loaders that produce a Lua module write a file with the same name but a Lua extension. By default this is .lua. Set lua_extension to control which extension is used:

{
  loaders: {
    "**/*.json": "json",
  },
  lua_extension: "luau", // or "lua"
}

Files that already end in .lua or .luau keep their extension.

Requiring loaded files

Loaders that produce a Lua module work with require during bundling. You can require a JSON config, an embedded Markdown template, or any other file whose loader outputs Lua, and darklua will inline the generated module. The path in the require call is rewritten to use the .lua (or .luau) extension automatically, so require("./data.json") becomes a valid require after processing.

Files matched by skip or copy cannot be required. Requiring a skipped file (or a file with no recognized loader) produces the error “configure content loaders to load this file”. Requiring a copied file produces “configure content loaders to copy this file”. In both cases the error message points to the relevant loader to use instead.

Reference

Loaders available for use in the loaders field:

LoaderWhat it does
luauParses and processes the file as Lua/Luau code.
copyCopies the file to the output unchanged.
skipIgnores the file.
stringReturns the content as a string.
string/base64Returns the content as a base64-encoded string.
string/zstdReturns the content as a zstd-compressed string.
string/gzipReturns the content as a gzip-compressed string.
string/zlibReturns the content as a zlib-compressed string.
bufferReturns the content as a buffer.
buffer/base64Returns the content as a base64-encoded buffer.
buffer/zstdReturns the content as a zstd-compressed buffer.
buffer/gzipReturns the content as a gzip-compressed buffer.
buffer/zlibReturns the content as a zlib-compressed buffer.
bytesReturns the content as an array of bytes.
bytes/base64Returns the content, base64-encoded, as an array of bytes.
bytes/zstdReturns the content, zstd-compressed, as an array of bytes.
bytes/gzipReturns the content, gzip-compressed, as an array of bytes.
bytes/zlibReturns the content, zlib-compressed, as an array of bytes.
jsonParses JSON data with a JSON5 parser and converts it to a Lua module.
json_linesParses each line with a JSON5 parser and converts the result to a Lua module.
tomlConverts TOML data to a Lua module.
yamlConverts YAML data to a Lua module.

Default loaders assigned by file extension when no pattern matches. Anything not listed here is skipped unless you assign a loader to it.

ExtensionLoader
.lua, .luauluau
.json, .json5json
.jsonl, .ndjsonjson_lines
.tomltoml
.yaml, .ymlyaml
.txtstring