magic.cr
magic.cr
Crystal bindings for libmagic, the library used by the Unix file command to identify file types from their contents.
The shard provides a small Crystal-friendly wrapper for common use and exposes the raw C API through LibMagic when you need direct access.
Requirements
- Crystal
>= 1.16.0 libmagic- The libmagic development headers
Install libmagic before building applications that depend on this shard:
# Debian/Ubuntu
sudo apt install libmagic-dev
# Fedora
sudo dnf install file-devel
# Arch
sudo pacman -S file
# macOS
brew install libmagic
Installation
Add the shard to your shard.yml:
dependencies:
magic:
github: trans/magic.cr
version: ~> 0.1.1
Then install dependencies:
shards install
Usage
require "magic"
puts Magic.file("README.md")
# => ASCII text
puts Magic.file("README.md", Magic::Flag::MimeType)
# => text/plain
puts Magic.buffer("hello\n")
# => ASCII text
For repeated lookups, keep a database handle open:
Magic.open do |magic|
puts magic.file("README.md")
puts magic.buffer("hello\n")
end
You can pass libmagic flags when opening a handle:
Magic.open(Magic::Flag::MimeType | Magic::Flag::Symlink) do |magic|
puts magic.file("README.md")
end
Or use a one-shot helper:
mime_type = Magic.file("README.md", Magic::Flag::MimeType)
API
One-shot helpers
Magic.file(path, flags = Magic::Flag::None, database = nil)
Magic.buffer(bytes, flags = Magic::Flag::None, database = nil)
Magic.buffer(string, flags = Magic::Flag::None, database = nil)
Magic.version
These helpers open libmagic, load the database, run one lookup, and close the handle.
Reusable database handle
magic = Magic::Database.open(Magic::Flag::MimeType)
magic.file("README.md")
magic.buffer("hello\n")
magic.descriptor(fd)
magic.close
Prefer the block form so the handle is always closed:
Magic::Database.open(Magic::Flag::MimeType) do |magic|
puts magic.file("README.md")
end
A custom magic database path can be passed as the second argument:
Magic.open(Magic::Flag::None, "/path/to/magic.mgc") do |magic|
puts magic.file("sample.bin")
end
Flags
Magic::Flag maps the libmagic flags into a Crystal flags enum. Common values include:
Magic::Flag::MimeTypeMagic::Flag::MimeEncodingMagic::Flag::MimeMagic::Flag::SymlinkMagic::Flag::CompressMagic::Flag::ErrorMagic::Flag::Extension
Flags can be combined with |:
flags = Magic::Flag::MimeType | Magic::Flag::Error
puts Magic.file("README.md", flags)
Errors
libmagic failures raise Magic::Error:
begin
Magic.file("missing.file", Magic::Flag::Error)
rescue error : Magic::Error
puts error.message
puts error.errno
end
Raw LibMagic API
The low-level binding is available as LibMagic:
handle = LibMagic.magic_open(LibMagic::MAGIC_MIME_TYPE)
LibMagic.magic_load(handle, Pointer(LibC::Char).null)
puts String.new(LibMagic.magic_file(handle, "README.md"))
LibMagic.magic_close(handle)
Use this layer when you need a libmagic function that the wrapper does not abstract.
Development
Run the specs:
CRYSTAL_CACHE_DIR=/tmp/crystal-cache crystal spec
Format source and specs:
crystal tool format src spec
License
MIT. See LICENSE.
Contributors
- Thomas Sawyer - creator and maintainer
magic.cr
- 0
- 0
- 0
- 1
- 0
- about 2 hours ago
- June 21, 2026
MIT License
Sun, 21 Jun 2026 03:58:18 GMT