diff --git a/std/node/buffer.ts b/std/node/buffer.ts
index fa911ee6f7..b9b33be993 100644
--- a/std/node/buffer.ts
+++ b/std/node/buffer.ts
@@ -1,3 +1,38 @@
+import * as hex from "../encoding/hex.ts";
+import * as base64 from "../encoding/base64.ts";
+import { notImplemented } from "./_utils.ts";
+
+const validEncodings = ["utf8", "hex", "base64"];
+const notImplementedEncodings = [
+  "utf16le",
+  "latin1",
+  "ascii",
+  "binary",
+  "ucs2",
+];
+
+function checkEncoding(encoding = "utf8", strict = true): string {
+  if (typeof encoding !== "string" || (strict && encoding === "")) {
+    if (!strict) return "utf8";
+    throw new TypeError(`Unkown encoding: ${encoding}`);
+  }
+
+  encoding = encoding.toLowerCase();
+  if (encoding === "utf-8" || encoding === "") {
+    return "utf8";
+  }
+
+  if (notImplementedEncodings.includes(encoding)) {
+    notImplemented(`"${encoding}" encoding`);
+  }
+
+  if (!validEncodings.includes(encoding)) {
+    throw new TypeError(`Unkown encoding: ${encoding}`);
+  }
+
+  return encoding;
+}
+
 /**
  * See also https://nodejs.org/api/buffer.html
  */
@@ -66,11 +101,24 @@ export default class Buffer extends Uint8Array {
   /**
    * Creates a new Buffer containing string.
    */
-  static from(string: string): Buffer;
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  static from(value: any, offset?: number, length?: number): Buffer {
-    if (typeof value == "string")
+  static from(string: string, encoding?: string): Buffer;
+  static from(
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    value: any,
+    offsetOrEncoding?: number | string,
+    length?: number
+  ): Buffer {
+    const offset =
+      typeof offsetOrEncoding === "string" ? undefined : offsetOrEncoding;
+    let encoding =
+      typeof offsetOrEncoding === "string" ? offsetOrEncoding : undefined;
+
+    if (typeof value == "string") {
+      encoding = checkEncoding(encoding, false);
+      if (encoding === "hex") return new Buffer(hex.decodeString(value).buffer);
+      if (encoding === "base64") return new Buffer(base64.decode(value));
       return new Buffer(new TextEncoder().encode(value).buffer);
+    }
 
     // workaround for https://github.com/microsoft/TypeScript/issues/38446
     return new Buffer(value, offset!, length);
@@ -246,7 +294,13 @@ export default class Buffer extends Uint8Array {
    * encoding. start and end may be passed to decode only a subset of buf.
    */
   toString(encoding = "utf8", start = 0, end = this.length): string {
-    return new TextDecoder(encoding).decode(this.subarray(start, end));
+    encoding = checkEncoding(encoding);
+
+    const b = this.subarray(start, end);
+    if (encoding === "hex") return hex.encodeToString(b);
+    if (encoding === "base64") return base64.encode(b.buffer);
+
+    return new TextDecoder(encoding).decode(b);
   }
 
   /**
diff --git a/std/node/buffer_test.ts b/std/node/buffer_test.ts
index d2b41fa1b2..adbc797515 100644
--- a/std/node/buffer_test.ts
+++ b/std/node/buffer_test.ts
@@ -116,6 +116,150 @@ Deno.test({
   },
 });
 
+Deno.test({
+  name: "Buffer from string hex",
+  fn() {
+    for (const encoding of ["hex", "HEX"]) {
+      const buffer: Buffer = Buffer.from(
+        "7468697320697320612074c3a97374",
+        encoding
+      );
+      assertEquals(buffer.length, 15, "Buffer length should be 15");
+      assertEquals(
+        buffer.toString(),
+        "this is a tést",
+        "Buffer to string should recover the string"
+      );
+    }
+  },
+});
+
+Deno.test({
+  name: "Buffer from string base64",
+  fn() {
+    for (const encoding of ["base64", "BASE64"]) {
+      const buffer: Buffer = Buffer.from("dGhpcyBpcyBhIHTDqXN0", encoding);
+      assertEquals(buffer.length, 15, "Buffer length should be 15");
+      assertEquals(
+        buffer.toString(),
+        "this is a tést",
+        "Buffer to string should recover the string"
+      );
+    }
+  },
+});
+
+Deno.test({
+  name: "Buffer to string base64",
+  fn() {
+    for (const encoding of ["base64", "BASE64"]) {
+      const buffer: Buffer = Buffer.from("deno land");
+      assertEquals(
+        buffer.toString(encoding),
+        "ZGVubyBsYW5k",
+        "Buffer to string should recover the string in base64"
+      );
+    }
+    const b64 = "dGhpcyBpcyBhIHTDqXN0";
+    assertEquals(Buffer.from(b64, "base64").toString("base64"), b64);
+  },
+});
+
+Deno.test({
+  name: "Buffer to string hex",
+  fn() {
+    for (const encoding of ["hex", "HEX"]) {
+      const buffer: Buffer = Buffer.from("deno land");
+      assertEquals(
+        buffer.toString(encoding),
+        "64656e6f206c616e64",
+        "Buffer to string should recover the string"
+      );
+    }
+    const hex = "64656e6f206c616e64";
+    assertEquals(Buffer.from(hex, "hex").toString("hex"), hex);
+  },
+});
+
+Deno.test({
+  name: "Buffer to string invalid encoding",
+  fn() {
+    const buffer: Buffer = Buffer.from("deno land");
+    const invalidEncodings = [null, 5, {}, true, false, "foo", ""];
+
+    for (const encoding of invalidEncodings) {
+      assertThrows(
+        () => {
+          // deno-lint-ignore ban-ts-comment
+          // @ts-ignore
+          buffer.toString(encoding);
+        },
+        TypeError,
+        `Unkown encoding: ${encoding}`,
+        "Should throw on invalid encoding"
+      );
+    }
+  },
+});
+
+Deno.test({
+  name: "Buffer from string invalid encoding",
+  fn() {
+    const defaultToUtf8Encodings = [null, 5, {}, true, false, ""];
+    const invalidEncodings = ["deno", "base645"];
+
+    for (const encoding of defaultToUtf8Encodings) {
+      // deno-lint-ignore ban-ts-comment
+      // @ts-ignore
+      assertEquals(Buffer.from("yes", encoding).toString(), "yes");
+    }
+
+    for (const encoding of invalidEncodings) {
+      assertThrows(
+        () => {
+          // deno-lint-ignore ban-ts-comment
+          // @ts-ignore
+          Buffer.from("yes", encoding);
+        },
+        TypeError,
+        `Unkown encoding: ${encoding}`
+      );
+    }
+  },
+});
+
+Deno.test({
+  name: "Buffer to/from string not implemented encodings",
+  fn() {
+    const buffer: Buffer = Buffer.from("deno land");
+    const notImplemented = ["ascii", "binary"];
+
+    for (const encoding of notImplemented) {
+      assertThrows(
+        () => {
+          // deno-lint-ignore ban-ts-comment
+          // @ts-ignore
+          buffer.toString(encoding);
+        },
+        Error,
+        `"${encoding}" encoding`,
+        "Should throw on invalid encoding"
+      );
+
+      assertThrows(
+        () => {
+          // deno-lint-ignore ban-ts-comment
+          // @ts-ignore
+          Buffer.from("", encoding);
+        },
+        Error,
+        `"${encoding}" encoding`,
+        "Should throw on invalid encoding"
+      );
+    }
+  },
+});
+
 Deno.test({
   name: "Buffer from another buffer creates a Buffer",
   fn() {