Three Bun concepts repeatedly surface in real use; understanding them prevents most surprises.
Native TypeScript. Bun runs .ts and .tsx files directly. There's no tsc compile step, no tsconfig.json required to start. Under the hood Bun strips type annotations at runtime — types are erased, the JS executes. That's fast but it does mean Bun does not type-check. If you have a type error, Bun won't catch it; you still need bunx tsc --noEmit in CI.
Binary lockfile (bun.lock). Earlier Bun versions used bun.lockb (purely binary); current versions use bun.lock (text-based, but still using a Structure-of-Arrays format optimized for parse speed). Either way, the file format is intentionally faster to parse than JSON-based lockfiles. Always commit it.
Drop-in npm replacement. Bun reads the same package.json, talks to the same npm registry, populates the same node_modules. To Node.js packages, Bun looks like Node.js v24.3.0 (it spoofs the version for compatibility). Most packages 'just work'. The exceptions are: native addons (compiled C++ that depends on Node's V8 internals — sometimes broken), some niche Node-specific APIs (improving every release), and packages with very tight Node version checks.