BLEND File Documentation
Summary
A BLEND file is the native project file of Blender, the free open-source 3D creation suite from the Blender Foundation. One .blend holds an entire scene: meshes, materials, textures, lighting, rigging, animation, physics and render settings, stored as a dump of Blender’s in-memory data with a self-describing schema. Its MIME type is application/x-blender. Only Blender opens it fully; to use the 3D content elsewhere, open it and export to a neutral format such as FBX, OBJ or glTF.
Technical details
| Feature | Value |
|---|---|
| Full name | Blender 3D Data File |
| File extension | .blend (backups .blend1, .blend2) |
| MIME type | application/x-blender |
| Format type | Binary 3D scene/project database (memory-image dump with schema) |
| Developer | The Blender Foundation |
| Introduced | 1994 (Blender); SDNA structure stabilised late 1990s |
| Magic number | 42 4C 45 4E 44 45 52 (“BLENDER”) at offset 0 |
| Header length | 12 bytes: 7-byte magic + pointer-size flag + endianness flag + 3-digit version |
| Pointer-size flag | _ (0x5F) = 32-bit, - (0x2D) = 64-bit |
| Endianness flag | v (0x76) = little-endian, V (0x56) = big-endian |
| Compression | Optional; gzip on save, so file may begin 1F 8B instead |
| Self-describing schema | DNA1 block (SDNA): C struct definitions embedded in the file |
| Terminator | ENDB file block |
| Open standard | No (proprietary; mirrors Blender internals) |
| Specification | Blender Manual — the .blend file format |
| Stores | Meshes, materials/nodes, UV maps, textures, armatures, animation, physics, scenes, render settings |
| Opens with | Blender (Windows, macOS, Linux) — the only full reader |
| Export targets | .fbx, .obj, .glb/.gltf, .stl, .dae, .ply |
| Related extensions | .blend1, .fbx, .obj, .gltf, .abc, .dae |
| Specification URL | docs.blender.org/manual/en/latest/files/blend/index.html |
What is a BLEND file?
A BLEND file is the native document format of Blender, the free and open-source 3D creation suite first released in 1994 and maintained since 2002 by the Blender Foundation. A single .blend is not one 3D model; it is closer to a small database that can hold an entire production: meshes and curves, materials and shader node trees, UV maps, textures (optionally embedded), armatures and rigging, keyframe and physics animation, particle systems, multiple cameras and lights, several scenes, compositing node trees, and the render settings, all in one file.
What makes the format unusual is how it is written. A .blend is essentially a snapshot of Blender’s data structures as they sat in memory at save time. Blender walks its internal linked data and dumps each object as a block of raw C-struct bytes, then appends a machine-readable description of those structs so the file can be read back on a different build. That design makes the format fast to save and load and remarkably version-tolerant, at the cost of being tied to Blender itself: there is no practical third-party reader.
The 12-byte file header
Every uncompressed .blend begins with a fixed 12-byte header that tells a reader how to interpret the rest of the file: which pointer width the machine used, which byte order, and which Blender version wrote it.
offset 0 "BLENDER" 7 bytes magic identifier
offset 7 pointer 1 byte '_' (0x5F) = 4-byte pointers, '-' (0x2D) = 8-byte
offset 8 endianness 1 byte 'v' (0x76) = little-endian, 'V' (0x56) = big-endian
offset 9 version 3 bytes ASCII, e.g. "404" for Blender 4.4
The seven magic bytes are 42 4C 45 4E 44 45 52. Byte 7 records the pointer size of the system that saved the file, because the file stores raw memory addresses and a reader must know whether each pointer occupies 4 or 8 bytes. Byte 8 records endianness for the same reason: the multi-byte integers inside the struct blocks are stored in the writing machine’s byte order, and a reader on the other endianness must byte-swap. Bytes 9–11 are the three-digit version, so a 64-bit little-endian file from Blender 4.4 reads literally as BLENDER-v404. Almost every file you meet today is 64-bit little-endian; the alternatives exist because the format predates their dominance.
One catch trips up anyone inspecting a saved file by hand: Blender gzip-compresses on save by default. A compressed .blend starts with the gzip signature 1F 8B, and the BLENDER header only appears after you inflate it.
File blocks: the body of the file
After the header the file is a flat sequence of file blocks, each a small header followed by raw struct data. The block header layout depends on the pointer-size flag, because one of its fields is a native pointer.
file-block header
code 4 bytes block identifier, e.g. 'OB', 'ME', 'MA', 'DNA1', 'ENDB'
size 4 bytes length of the data that follows this header
old_addr 4 or 8 B memory address the block had when saved (the pointer size)
sdna_index 4 bytes index of the struct definition (in DNA1) describing the data
count 4 bytes how many of that struct are packed in this block
... size bytes of raw struct data ...
The four-byte code names the datablock type: OB for an object, ME for a mesh, MA for a material, SC for a scene, and so on. size gives the byte length of the data that follows. old_addr is the original memory address of this block when it lived in Blender’s heap. That address is the key to the whole scheme: pointers inside one block refer to other blocks by their old addresses, and on load Blender builds a table from old address to new address and rewrites every pointer, reconstructing the object graph exactly. sdna_index points at the struct definition that describes the bytes, and count says how many copies of that struct the block contains.
SDNA: the DNA1 block that makes the file self-describing
The reason a .blend from one Blender version can still load in another is a single special block near the end, coded DNA1, holding the SDNA (Structure DNA). SDNA is a complete, machine-readable description of every C struct the file uses.
DNA1 block
'SDNA'
'NAME' count + names of every struct field (e.g. "*next", "loc[3]")
'TYPE' count + names of every type ("float", "Object", "Mesh", ...)
'TLEN' the byte length of each type
'STRC' each struct: its type + a list of (field-type, field-name) pairs
Because sdna_index on every block points into this table, a reader never has to hard-code the layout of an Object or a Mesh. It looks up the struct definition that the file itself carries, learns each field’s name, type and offset, and reads the bytes accordingly. When Blender adds a field in a new version, older files simply lack it and newer readers see the shorter old struct through the old file’s own SDNA; when an old Blender reads a new file, it maps the fields it recognises and ignores the rest. That is forward- and backward-compatibility built into the data, not the code. The block sequence ends with an empty block coded ENDB, which marks the end of the file.
.blend1 backups and packed data
Every time you save, Blender first renames the previous file to .blend1 (and optionally an older one to .blend2). These are not a different format; a .blend1 is a complete, valid .blend from the prior save. If a save goes wrong you can recover by renaming .blend1 back to .blend. They are safe to delete to reclaim space.
By default a .blend stores only references (paths) to external textures, fonts and sounds, exactly the way the FBX and OBJ export chains keep images as sidecar files. Blender can instead pack those assets, copying their bytes into datablocks inside the .blend so the file is self-contained and portable. Packing makes the file larger but means a scene can move to another machine without losing its textures.
Exporting a scene, not converting the file
Because the format mirrors Blender’s internals, there is no standalone .blend-to-anything converter: reading the file means running Blender. To use 3D content elsewhere you open the .blend and export to a neutral interchange format. OBJ carries static geometry and materials but no animation. FBX is the usual route into game engines because it keeps meshes, rigging and animation, which is why Unity and Unreal ingest it. glTF/GLB is the modern web and AR choice, bundling geometry, PBR materials and animation in one file. STL exports mesh-only geometry for 3D printing. Each is a lossy projection of the full .blend: the export keeps what the target format understands and drops Blender-specific data such as node graphs, drivers and physics setups.
Auto-run Python and why a BLEND is not fully passive
A .blend is mostly data, but not entirely. Blender files can embed Python: drivers can contain Python expressions, and a file can carry text-block scripts marked to register or auto-run on load. If “Auto Run Python Scripts” is enabled, opening a .blend from an untrusted source can execute arbitrary code with your user privileges, the same class of risk as a spreadsheet macro. Blender disables auto-run by default and shows a warning when a file wants to run scripts. Keep auto-run off for files from strangers, and enable it only for projects whose scripts you have reviewed or whose author you trust. The geometry and material data on their own are inert.
FAQ
Why does a BLEND file store raw memory addresses?
Because the file is a direct dump of Blender’s in-memory data, and the links between datablocks are pointers. Storing each block’s original address (old_addr) lets Blender, on load, build an old-to-new address map and patch every pointer so the object graph is rebuilt exactly. It is what makes saving and loading fast: little translation happens beyond pointer fixups.
How can an old Blender open a file from a newer one?
The DNA1 (SDNA) block carries the full struct schema inside the file. A reader consults that schema rather than a hard-coded layout, so it can map whichever fields it recognises and skip the rest. New fields added in later versions are simply ignored by an older reader, and missing fields default, which is why compatibility is broad even though the format is proprietary.
References
- Blender Manual — The .blend file format
- Blender Manual — Security (auto-run Python scripts)
- Blender — official site and downloads
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.