ByteScope

WebAssembly file format

A compiled WebAssembly binary module.

MIME type
application/wasm
Extensions
.wasm
Category
Executables & bytecode

Magic-number signature

0x000000000061736D·asm0x00 'asm'

About the WebAssembly format

A WebAssembly module is the most regular binary format in this catalogue: an eight-byte preamble, then a sequence of sections, each one a single-byte id followed by a LEB128 length and that many bytes of payload. Nothing is at a fixed offset beyond byte eight, but nothing needs to be — a reader walks the sections and can skip any it does not care about, which is what lets a browser start compiling while the rest of the module is still downloading. The known sections must appear in a fixed order, so a validator can reject a malformed module without a second pass.

Header layout, byte by byte

OffsetLengthFieldMeaning
04magic00 61 73 6D — a NUL byte followed by the ASCII letters asm. The leading NUL is deliberate: it guarantees the file is not valid text, so a module that arrives through anything that touches text encodings fails at the first byte instead of somewhere unpredictable.
44versionA 32-bit little-endian version, currently 01 00 00 00 — version 1 — and unchanged since the format shipped, because every extension since has been made backwards compatible rather than by bumping this number.
81First section idOne byte naming the section: 0 custom, 1 type, 2 import, 3 function, 4 table, 5 memory, 6 global, 7 export, 8 start, 9 element, 10 code, 11 data, 12 data count. Known sections must appear in ascending order and at most once each, so the first byte after the preamble is usually 1 (types) or 0 (a custom section a toolchain put in front).
9variableSection size (LEB128)Unsigned LEB128 byte count of the section body — one to five bytes, each carrying seven bits of value with the high bit as a continuation flag. This is the only length field in the format, and every section boundary is found by adding it, which is why nothing after offset 8 has a fixed address.
variablevariableSection bodyVectors of entries, themselves LEB128-prefixed with a count. The next section id begins immediately after the last byte the size field claimed, so summing ids and sizes must land exactly on the end of the file — the format's built-in truncation check.
variablevariableCustom sections (id 0)A named blob that carries no semantics: the 'name' section holding function names for stack traces, DWARF debug info, producer metadata, and the target-features record. They may appear anywhere between other sections, and stripping them is exactly what a release build does to shrink a module.

Telling it apart from its neighbours

Easily confused withHow to tell
WAT textThe text form of the same module is source, not a variant of the binary: it begins with an open parenthesis and the word module, and is UTF-8 throughout. Anything starting 00 61 73 6D is the binary form, which is the only form a browser instantiates.
GZIPPractically the most common confusion, because .wasm files are almost always served compressed. A file that begins 1F 8B is a gzip stream, and the wasm magic only appears after decompression. A build artefact saved straight out of a network tab is often gzip with a .wasm name.
ELF executableBoth are compiled output for a virtual or real machine, and an emscripten or wasi-sdk build directory contains both — the .o files are ELF while only the final module is wasm. 7F 45 4C 46 versus 00 61 73 6D at offset 0 separates them without ambiguity.
asm.jsThe ancestor, still found in old bundles: asm.js is JavaScript, a plain text file with a 'use asm' directive, delivered as .js. If a tool loads it with WebAssembly.instantiate it will fail on the magic, because there is no binary module in it at all.

How these files break

  • Truncation. Section sizes are declared before their contents, so a partial download parses correctly right up to the point where a section claims more bytes than remain — the decoder reports 'unexpected end of section or function', which is the clearest truncation message any format in this catalogue produces.
  • Served or saved gzip-compressed. A .wasm downloaded with Content-Encoding gzip and written to disk unchanged starts 1F 8B, and WebAssembly.instantiate rejects it on the magic. The bytes are fine; only the layer is wrong.
  • A stray byte inside a section body. The section walk still lands on the right boundaries as long as the length fields are intact, so the module often loads and then traps or misbehaves at runtime, which is much harder to diagnose than a header failure.
  • Text-mode transfer or an editor that appends a newline. One extra byte at the end leaves a module whose section walk ends one byte short of the file, and strict decoders report trailing bytes rather than accepting it.

Where the format stands today

WebAssembly is how existing native code reaches the browser: video and image codecs, PDF and CAD engines, SQLite, Python and Ruby runtimes, emulators, and the compression libraries behind in-browser archive tools all ship as .wasm modules. It is not a replacement for JavaScript and is not used for UI — it has no DOM access of its own — but it is the default answer for compute-heavy work that must run on the user's machine, which is also what makes browser-only, no-upload tools possible at all. Outside the browser it has grown a second life as a portable sandbox: WASI runtimes, edge compute platforms and plug-in systems all use the same binary format, which is why a module built for a website often runs unchanged on a server.

Open WebAssembly files on this site

Every one of these runs in your browser — the file never leaves your machine.

Related formats

Formats that are easy to confuse with WebAssembly — compare their leading bytes.

FormatFirst bytesExtension
ELF executable7F 45 4C 46.elf
Java class fileCA FE BA BE.class

Frequently asked questions

What is a magic number in a file?

The first few bytes of a file, which identify its format regardless of what the name says. A PNG always starts with 89 50 4E 47; a ZIP with 50 4B 03 04. Operating systems, browsers and the file command all read these bytes rather than trusting the extension, which is why renaming a file does not change what it actually is.

How do I check a file's magic number myself?

On macOS or Linux, xxd -l 16 yourfile prints the first 16 bytes; on Windows, Format-Hex -Path yourfile -Count 16 in PowerShell. Or drop the file into the File Type Identifier on this site, which reads the bytes locally and names the format for you — nothing is uploaded.

Why do two formats share the same magic number?

Because one is built on the other. Every docx, xlsx, pptx, apk, jar and epub begins with the ZIP signature, since all of them are ZIP archives underneath; telling them apart means looking at the entries inside. Java class files and macOS universal binaries both start with CA FE BA BE and are distinguished by the field that follows.

Can a file have no magic number at all?

Yes. Text-based formats — XML, HTML, JSON, SVG, CSV — have no fixed byte signature, so they are recognized structurally instead: a leading <?xml declaration, a <svg element, or a { followed by a quoted key. That detection is a good guess rather than a certainty, which is why this reference marks those formats as probe-detected.

Does a matching magic number mean the file is safe?

No. It tells you what the format is, not whether the contents are harmless — a genuine PDF or docx can still carry a malicious payload. Identifying the true type is a useful first check, especially when the extension disagrees with the bytes, but it is not a malware scan.

Have a file that might be in the WebAssembly format? Identify it with the File Type Identifier — it reads the magic number locally, nothing is uploaded. Or browse all formats.