# Node.js API compatibility - Buffer

The `buffer` API in Node.js is a global class used to handle binary data. It allows developers to work with raw binary data directly, enabling efficient manipulation of data streams, file I/O, and network communications.

---

## Example: Basic buffer operations

Create and manipulate buffers with different encodings:

```javascript
/**
 * An example of using the Node.js Buffer API in an Azion Function.
 * Support:
 * - Partial support
 * @module runtime-apis/nodejs/buffer/main
 * @example
 * // Execute with Azion Bundler:
 * npx edge-functions build
 * npx edge-functions dev
 */
import { Buffer } from "node:buffer";

/**
 * Example of using the Node.js Buffer API
 * Writes `string` to `buf` at `offset` according to the character encoding in`encoding`. The `length` parameter is the number of bytes to write. If `buf` did
 * not contain enough space to fit the entire string, only part of `string` will be
 * written. However, partially encoded characters will not be written.
 * @param {*} event
 * @returns {Promise<Response>}
 */
const main = async (event) => {
  const helloBuffer = Buffer.from("Hello Edge!", "utf8");
  console.log(helloBuffer.toString("hex"));
  // 48656c6c6f204564676521
  console.log(helloBuffer.toString("base64"));
  // SGVsbG8gRWRnZSE=

  helloBuffer.write("World", 6, 5, "utf8");
  console.log(helloBuffer.toString());
  // Hello World!
  return new Response(helloBuffer.toString(), { status: 200 });
};
export default main;
```

---

## Example: Buffer encoding conversions

Convert between different encoding formats for data transmission:

```javascript
import { Buffer } from "node:buffer";

const main = async (event) => {
  // Create buffer from string
  const textBuffer = Buffer.from("Azion Runtime", "utf8");

  // Convert to different encodings
  const hexEncoded = textBuffer.toString("hex");
  const base64Encoded = textBuffer.toString("base64");
  const base64urlEncoded = textBuffer.toString("base64url");

  console.log("Hex:", hexEncoded);
  console.log("Base64:", base64Encoded);
  console.log("Base64URL:", base64urlEncoded);

  // Decode back from base64
  const decoded = Buffer.from(base64Encoded, "base64").toString("utf8");
  console.log("Decoded:", decoded);

  // Create JSON response with all encodings
  return new Response(JSON.stringify({
    original: "Azion Runtime",
    hex: hexEncoded,
    base64: base64Encoded,
    base64url: base64urlEncoded,
    decoded: decoded
  }), {
    headers: { "Content-Type": "application/json" }
  });
};

export default main;
```

---

## Example: Buffer concatenation and slicing

Combine multiple buffers and extract portions of binary data:

```javascript
import { Buffer } from "node:buffer";

const main = async (event) => {
  // Create multiple buffers
  const header = Buffer.from("HEADER:", "utf8");
  const content = Buffer.from("Hello World", "utf8");
  const footer = Buffer.from(":END", "utf8");

  // Concatenate buffers
  const combined = Buffer.concat([header, content, footer]);
  console.log("Combined:", combined.toString());
  // Combined: HEADER:Hello World:END

  // Use subarray() to extract content (preferred over deprecated slice())
  const contentOnly = combined.subarray(7, 18);
  console.log("Extracted:", contentOnly.toString());
  // Extracted: Hello World

  // Get buffer length
  console.log("Total length:", combined.length);

  // Copy portion to another buffer
  const copy = Buffer.alloc(11);
  combined.copy(copy, 0, 7, 18);
  console.log("Copied:", copy.toString());
  // Copied: Hello World

  return new Response(JSON.stringify({
    combined: combined.toString(),
    extracted: contentOnly.toString(),
    copied: copy.toString()
  }), {
    headers: { "Content-Type": "application/json" }
  });
};

export default main;
```

---

## Example: Binary data processing

Process binary data from requests or external sources:

```javascript
import { Buffer } from "node:buffer";

const main = async (event) => {
  // Get request body
  const request = event.request;
  const arrayBuffer = await request.arrayBuffer();

  // Handle empty request body
  if (!arrayBuffer.byteLength) {
    return new Response(JSON.stringify({
      error: "Empty request body",
      length: 0
    }), {
      status: 400,
      headers: { "Content-Type": "application/json" }
    });
  }

  const dataBuffer = Buffer.from(arrayBuffer);

  // Check buffer properties
  console.log("Buffer length:", dataBuffer.length);
  console.log("First byte:", dataBuffer[0]);

  // Find byte sequence
  const searchBuffer = Buffer.from("Azion", "utf8");
  const index = dataBuffer.indexOf(searchBuffer);
  console.log("Found 'Azion' at index:", index);

  // Compare buffers
  const buf1 = Buffer.from("test");
  const buf2 = Buffer.from("test");
  console.log("Buffers equal:", buf1.equals(buf2));

  // Create buffer with specific size
  const allocated = Buffer.alloc(256);
  allocated.write("Allocated buffer example", 0, "utf8");
  console.log("Allocated:", allocated.toString("utf8", 0, 24));

  return new Response(JSON.stringify({
    length: dataBuffer.length,
    firstByte: dataBuffer[0],
    foundAtIndex: index
  }), {
    headers: { "Content-Type": "application/json" }
  });
};

export default main;
```

---

## Example: JSON serialization with buffers

Handle JSON data with buffer conversion for API responses:

```javascript
import { Buffer } from "node:buffer";

const main = async (event) => {
  // Create object with data
  const data = {
    id: 12345,
    name: "Azion Function",
    timestamp: Date.now()
  };

  // Convert to JSON string and then to buffer
  const jsonString = JSON.stringify(data);
  const jsonBuffer = Buffer.from(jsonString, "utf8");

  // Calculate size for headers
  const contentLength = jsonBuffer.length;

  // Convert back to object
  const parsed = JSON.parse(jsonBuffer.toString("utf8"));

  console.log("JSON buffer size:", contentLength, "bytes");
  console.log("Parsed object:", parsed);

  // Create response buffer with metadata
  const responseData = {
    ...parsed,
    bufferSize: contentLength
  };
  const responseBuffer = Buffer.from(JSON.stringify(responseData), "utf8");

  return new Response(responseBuffer, {
    headers: {
      "Content-Type": "application/json",
      "Content-Length": responseBuffer.length.toString()
    }
  });
};

export default main;
```

---

## Supported APIs

| API | Status |
|-----|--------|
| `Buffer.alloc()` | 🟢 Supported |
| `Buffer.allocUnsafe()` | 🟢 Supported |
| `Buffer.byteLength()` | 🟢 Supported |
| `Buffer.compare()` | 🟢 Supported |
| `Buffer.concat()` | 🟢 Supported |
| `Buffer.from()` | 🟢 Supported |
| `Buffer.isBuffer()` | 🟢 Supported |
| `Buffer.isEncoding()` | 🟢 Supported |
| `buf.compare()` | 🟢 Supported |
| `buf.copy()` | 🟢 Supported |
| `buf.equals()` | 🟢 Supported |
| `buf.fill()` | 🟢 Supported |
| `buf.indexOf()` | 🟢 Supported |
| `buf.includes()` | 🟢 Supported |
| `buf.lastIndexOf()` | 🟢 Supported |
| `buf.length` | 🟢 Supported |
| `buf.readInt*()` | 🟡 Partially supported |
| `buf.subarray()` | 🟢 Supported |
| `buf.slice()` | 🟡 Supported (deprecated, use `subarray()`) |
| `buf.toString()` | 🟢 Supported |
| `buf.write()` | 🟢 Supported |
| `buf.writeInt*()` | 🟡 Partially supported |
| `Buffer.isAscii()` | 🔴 Not supported |
| `Buffer.isUtf8()` | 🔴 Not supported |
| `Buffer.resolveObjectURL()` | 🔴 Not supported |
| `Buffer.transcode()` | 🔴 Not supported |

:::note
APIs marked as 🟡 Partially supported have limited functionality compared to the full Node.js implementation. The `isAscii()`, `isUtf8()`, `resolveObjectURL()`, and `transcode()` APIs are not yet supported. Note that `buf.slice()` is deprecated in Node.js v17.5.0 and later — use `buf.subarray()` instead.
:::

---

## Related resources

- [Node.js `buffer` documentation](https://nodejs.org/api/buffer.html)