# How bat's Assets System Manages Syntax and Theme Data: A Technical Deep Dive

> Discover how bat's assets system efficiently manages syntax and theme data using pre-compiled binaries and lazy loading for rapid, customizable output. Learn the technical details.

- Repository: [David Peter/bat](https://github.com/sharkdp/bat)
- Tags: deep-dive
- Published: 2026-03-06

---

**bat stores syntax definitions and color themes as pre-compiled binary assets that are lazily loaded at runtime, enabling fast startup while supporting user customization through a cache mechanism.**

The `bat` command-line tool enhances the traditional `cat` utility with syntax highlighting and Git integration. Central to this functionality is **bat's assets system**, which efficiently manages hundreds of syntax definitions and color themes. Rather than parsing raw TextMate or Sublime Text files at startup, bat employs a three-stage pipeline that compiles, embeds, and lazily loads these resources.

## The Three-Stage Asset Pipeline

### Stage 1: Generating Pre-Compiled Binaries

The asset generation process begins with the shell script [`assets/create.sh`](https://github.com/sharkdp/bat/blob/main/assets/create.sh). This script invokes `bat cache --build`, which parses every `.sublime-syntax` file in `assets/syntaxes/` and every theme file in `assets/themes/`. Using the `syntect` library, bat serializes the resulting data structures with **bincode**, a compact binary serialization format. The output consists of three binary files: `assets/syntaxes.bin`, `assets/themes.bin`, and `assets/acknowledgements.bin`.

### Stage 2: Embedding Assets at Compile Time

Once generated, these binary blobs are baked directly into the bat executable using Rust's `include_bytes!` macro. The [`src/assets.rs`](https://github.com/sharkdp/bat/blob/main/src/assets.rs) file contains helper functions that expose these embedded resources:

```rust
pub(crate) fn get_serialized_integrated_syntaxset() -> &'static [u8] {
    include_bytes!("../assets/syntaxes.bin")
}

pub(crate) fn get_integrated_themeset() -> LazyThemeSet {
    from_binary(include_bytes!("../assets/themes.bin"), COMPRESS_THEMES)
}

```

This compile-time embedding ensures that bat ships as a single, self-contained binary with no external resource dependencies.

### Stage 3: Lazy Runtime Loading

At runtime, bat avoids the performance penalty of deserializing all syntax and theme data upfront. The `HighlightingAssets` struct in [`src/assets.rs`](https://github.com/sharkdp/bat/blob/main/src/assets.rs) manages this through lazy initialization:

```rust
pub fn from_binary() -> Self {
    HighlightingAssets::new(
        SerializedSyntaxSet::FromBinary(get_serialized_integrated_syntaxset()),
        get_integrated_themeset(),
    )
}

```

The actual deserialization occurs only on first use, utilizing `OnceCell` (or similar lazy initialization patterns) to cache the `SyntaxSet` and `ThemeSet` after their initial load. This approach provides fast startup times while maintaining access to hundreds of syntax definitions.

## Custom Assets and Cache Management

While bat ships with comprehensive default assets, users can extend or override them. The `bat cache --build --source <dir>` command generates custom binary caches from user-provided `.sublime-syntax` or `.tmTheme` files. When a custom cache directory exists, `HighlightingAssets::from_cache(cache_path)` loads `syntaxes.bin` and `themes.bin` from that location instead of the embedded defaults.

Users can also disable custom assets entirely using the `--no-custom-assets` CLI flag, forcing bat to use only the integrated binaries. This flexibility allows bat to function as a portable tool while supporting specialized syntax requirements.

## Theme and Syntax Lookup Mechanisms

Once loaded, assets are accessed through specific lookup methods. The `get_theme()` method in [`src/assets.rs`](https://github.com/sharkdp/bat/blob/main/src/assets.rs) queries the `LazyThemeSet`, falling back to the default theme if the requested name is unknown (handling deprecated aliases like `"ansi"` transparently).

For syntax detection, `get_syntax()` analyzes file paths and content against the loaded `SyntaxSet`, utilizing the syntax mapping rules defined in [`src/syntax_mapping.rs`](https://github.com/sharkdp/bat/blob/main/src/syntax_mapping.rs). This integration ensures accurate language detection across hundreds of file types without manual configuration.

## Summary

- **bat's assets system** compiles syntax and theme files into binary blobs using `bincode` serialization via [`assets/create.sh`](https://github.com/sharkdp/bat/blob/main/assets/create.sh) and `bat cache --build`.
- The `include_bytes!` macro embeds these assets directly into the executable at compile time, eliminating external dependencies.
- `HighlightingAssets` manages lazy deserialization at runtime using `from_binary()`, ensuring fast startup by loading data only on first use.
- Users can override default assets with custom caches via `from_cache()` or disable them with `--no-custom-assets`.
- Theme and syntax lookups are handled by `get_theme()` and `get_syntax()` methods in [`src/assets.rs`](https://github.com/sharkdp/bat/blob/main/src/assets.rs).

## Frequently Asked Questions

### How does bat achieve fast startup times despite supporting hundreds of syntaxes?

bat uses **lazy loading** via the `HighlightingAssets` struct. Rather than parsing all syntax definitions at startup, it embeds pre-compiled binary data and deserializes specific syntaxes only when first requested, minimizing initial load time.

### Can I add my own syntax highlighting definitions to bat?

Yes. Run `bat cache --build --source <directory>` where your directory contains `.sublime-syntax` files. This generates a custom cache that bat loads via `HighlightingAssets::from_cache()`, overriding or extending the built-in assets.

### What format does bat use to store its syntax and theme data?

bat uses **bincode**, a compact binary serialization format, to store pre-parsed `syntect` data structures. These are created during the build process by [`assets/create.sh`](https://github.com/sharkdp/bat/blob/main/assets/create.sh) and stored in `syntaxes.bin` and `themes.bin`.

### How can I force bat to ignore custom user assets?

Use the `--no-custom-assets` command-line flag. This forces bat to use only the embedded default assets loaded via `HighlightingAssets::from_binary()`, ignoring any custom cache directories.