Bakelite

Next-generation BakedFS, virtual filesystem, and binary container engine for Crystal.

Bakelite provides zero-copy compile-time asset embedding alongside streaming-capable, chunked-compressed storage and post-compilation binary overlay containers.

CI Pages License: MIT


Features


Installation

Add bakelite to your shard.yml:

dependencies:
  bakelite:
    github: sol-vin/bakelite
    version: ~> 0.1.0

Run shards install.


Quick Start

1. Macro DSL Embedding

require "bakelite"

module Assets
  include Bakelite::FS

  # Direct inlined bake (zero-copy string/bytes)
  bake "config/app.yml", as_path: "app.yml"

  # Streamed chunked store (64KB chunks, Deflate compressed)
  store "media/soundtrack.ogg", chunk_size: 65536, compress: :deflate

  # Embed entire directories
  bake_folder "public/icons", prefix: "icons"
  store_folder "assets/models", prefix: "models"
end

# Read baked content directly
puts Assets["app.yml"].content

# Stream large files through standard Crystal IO
Assets.open("media/soundtrack.ogg") do |io|
  io.seek(1024)
  buffer = Bytes.new(512)
  io.read_fully(buffer)
end

2. Custom Volumes & Union Mounts

module Game
  include Bakelite::FS

  # Define a dedicated volume mounted at /mods with high priority
  volume :mods, mount: "mods", priority: 100 do
    bake "mods/pack1/rules.json", as_path: "rules.json"
  end
end

# Access files via mount prefix or direct volume reference
item = Game["mods/rules.json"]
mod_item = Game.volume(:mods)["rules.json"]

3. Declarative Multi-Volume Manifest (bake_manifest)

Declare multi-volume configurations cleanly in YAML with custom mount points, auto thresholds, and glob patterns with negative exclusions (!pattern). The manifest is processed in a single fast compile-time pass (<200ms):

# manifest.yml
volumes:
  engine:
    mount: ""
    default_chunk_size: 65536
    default_compression: deflate
    auto_threshold: 16384 # Files < 16KB use bake; >= 16KB use store
    files:
      - src/libgodot.cr
      - src/lapis.cr
      - src/libgodot/**/*.cr
      - src/bridge/**/*
      - shard.yml
      - godot-version.yml
    exclude:
      - src/main.cr
      - src/libgodot/docs/**
      - "**/*.uid"
  template:
    mount: "template"
    files:
      - template/**/*
  addon:
    mount: "addons/crystal_integration"
    files:
      - addons/crystal_integration/**/*

Bake into your application with a single call:

module EngineFS
  include Bakelite::FS

  bake_manifest "manifest.yml", base_dir: "."
end

4. Volume Extraction API

Extract isolated volumes or specific subfolders directly to disk with full overwrite protection:

# Extract the lean :engine volume into lib/lapis
EngineFS.extract_volume(:engine, "lib/lapis")

# Extract only the "scenes" folder from the template volume
EngineFS.extract_volume_folder(:template, "scenes", "my_project/scenes")

5. Programmatic Packaging API (Bakelite.pack)

Pack containers or append assets directly from your toolchain or scripts without spawning child processes:

# Pack a directory into a container or append to an executable
Bakelite.pack(
  target: "bin/game.exe",
  source_dir: "assets/",
  volume: :root,
  mount_point: "assets",
  append: true
)

# Pack an array of preconfigured volumes
vol = Bakelite::Volume.new(:levels)
# ... populate volume ...
Bakelite.pack("game_assets.bkl", volumes: [vol])

6. Appending Containers Post-Compilation

Compile your application normally:

crystal build src/main.cr -o bin/game.exe

Append assets into the binary using the bakelite CLI:

bakelite pack bin/game.exe assets/ --mount assets --append

Inside src/main.cr, mount the appended container on startup:

require "bakelite"

Bakelite.mount_self!

# All assets are now available transparently!
if item = Bakelite.get?("assets/textures/player.png")
  puts "Found asset: #{item.size} bytes"
end

CLI Reference

Bakelite ships with a complete CLI tool for managing containers and documentation:

# Pack a directory into a .bkl archive or append to an executable
bakelite pack <target> <dir> [--mount PATH] [--append] [--chunk-size 64KB] [--compress deflate]

# List files and volumes in a container with rich Opal tables
bakelite list <target>

# Inspect container trailer, start offset, index metadata, and mounted volumes
bakelite inspect <target>

# Verify CRC32 checksums for every chunk in a container
bakelite verify <target>

# Extract all files or a specific volume to disk
bakelite extract <target> <destination> [--volume NAME]

# Compile structured guide documentation with Jasper
bakelite docs [--src docs_src] [--out src/bakelite/docs]

# Display version information
bakelite version

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                       Bakelite::FS                          │
│                      (Union Router)                         │
└──────────────┬───────────────────────────────┬──────────────┘
               │                               │
       Priority 100                    Priority 0
┌──────────────▼──────────────┐ ┌──────────────▼──────────────┐
│       Volume (:dlc)         │ │       Volume (:root)        │
│   Mount: "content/dlc"      │ │       Mount: ""             │
└──────────────┬──────────────┘ └──────────────┬──────────────┘
               │                               │
       ┌───────┴───────┐               ┌───────┴───────┐
       │               │               │               │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│  BakedItem  │ │ StoredItem  │ │  BakedItem  │ │ StoredItem  │
│ (Inlined)   │ │  (Chunked)  │ │ (Inlined)   │ │  (Chunked)  │
└─────────────┘ └──────┬──────┘ └─────────────┘ └──────┬──────┘
                       │                               │
              ┌────────▼────────┐             ┌────────▼────────┐
              │ Bakelite::FileIO│             │ Bakelite::FileIO│
              │ O(chunk) Memory │             │ O(chunk) Memory │
              └─────────────────┘             └─────────────────┘

Running Specs

# Run full test suite
crystal spec

# Or compile and run dedicated runner
crystal build spec/all_specs.cr -o bin/all_specs.exe
./bin/all_specs.exe

License

MIT License. Copyright (c) 2026 sol-vin.