npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

hide-my-json

v0.1.1

Published

Obfuscate JSON payloads via gzip + XOR + Base62 encoding

Readme

hide-my-json

Obfuscate JSON payloads via Base62 encoding with optional gzip compression and XOR encryption.

Why?

When your web app exchanges JSON with your server, the data is easily readable in browser DevTools — anyone can inspect network requests and see exactly what you're sending and receiving. hide-my-json makes that data unreadable to casual observers by encoding it into a compact Base62 string, with optional compression and encryption.

This is not a substitute for proper encryption (use HTTPS + TLS for that). It's an obfuscation layer designed to discourage casual inspection and make reverse-engineering your API payloads significantly harder.

🔗 Try it live →

Use it when you want to:

  • Hide JSON structure from browser DevTools / network inspectors
  • Make API payloads opaque to curious users
  • Add a lightweight obfuscation layer on top of HTTPS
  • Transfer compact, encoded data between client and server

Installation

npm install hide-my-json

Quick Start

import { HideMyJson } from "hide-my-json";

// Encode — gzip + Base62 (default)
const { payload } = await HideMyJson.encode({ user: "john", role: "admin" });
// → "G1ZwXNZN6ZjIZibSGwPA0fOJUw5BWadzgsp1Y53ktDlSMfbVM8cJO3N49xkWRoYg8Iq"

// Decode
const { data } = await HideMyJson.decode(payload);
// → { user: "john", role: "admin" }

Usage

Basic Obfuscation (gzip + Base62)

By default, data is gzip-compressed and then Base62-encoded:

const { payload } = await HideMyJson.encode({
  user: "john",
  role: "admin",
  permissions: ["read", "write"],
});
console.log(payload);
// → "3LVZjVORY66shXSyroEZjmJoOLTSYLNurmyelLR95UfXGNVVXxTwgOxmSRBRPvheTDKn3wrGTKfBJgy8cDaNnBWYv7mKFwMRC3xDQHzge"

With XOR Encryption

Pass an xorKey to add XOR encryption on top of gzip:

const opts = { xorKey: "my-secret-key" };

const { payload } = await HideMyJson.encode({ token: "abc123" }, opts);
// → "Z8bmC2yph49yuCWTbNGDzguj9o4gdAJGiakBhoJquWGYHw4coVB"

const { data } = await HideMyJson.decode(payload, opts);
// → { token: "abc123" }

Both sides must use the same options. If you encode with xorKey, you must decode with the same xorKey.

Without Gzip (Base62 only)

Disable gzip for small payloads where compression overhead isn't worth it:

const opts = { useGzip: false };

const { payload } = await HideMyJson.encode({ id: 1 }, opts);
// → "AZRNdCjY0Wz"

const { data } = await HideMyJson.decode(payload, opts);
// → { id: 1 }

Gzip in Action

Gzip really shines on repetitive data. Here's a 930-byte JSON compressed down to a 195-character payload — 84% smaller:

const logs = {
  logs: [
    {
      timestamp: "2024-01-01T00:00:00Z",
      level: "info",
      message: "User logged in successfully",
    },
    {
      timestamp: "2024-01-01T00:00:01Z",
      level: "info",
      message: "User logged in successfully",
    },
    {
      timestamp: "2024-01-01T00:00:02Z",
      level: "info",
      message: "User logged in successfully",
    },
    {
      timestamp: "2024-01-01T00:00:03Z",
      level: "info",
      message: "User logged in successfully",
    },
    {
      timestamp: "2024-01-01T00:00:04Z",
      level: "info",
      message: "User logged in successfully",
    },
    {
      timestamp: "2024-01-01T00:00:05Z",
      level: "info",
      message: "User logged in successfully",
    },
    {
      timestamp: "2024-01-01T00:00:06Z",
      level: "info",
      message: "User logged in successfully",
    },
    {
      timestamp: "2024-01-01T00:00:07Z",
      level: "info",
      message: "User logged in successfully",
    },
    {
      timestamp: "2024-01-01T00:00:08Z",
      level: "info",
      message: "User logged in successfully",
    },
    {
      timestamp: "2024-01-01T00:00:09Z",
      level: "info",
      message: "User logged in successfully",
    },
  ],
};

// With gzip (default) — 195 chars
const withGzip = await HideMyJson.encode(logs);
// → "3ds5WnDJjriKiymY1XNkFDeDIptcHrsMqkvI5tyPC6qLVvmKj0A5daZlEkx97fhvkVoAO56jxG2bLhASkStsdDwanA39knKUK2gkFHkTUgJnqncDBa9bZgCFowDicGkFqNhVrRxtsQOhKHLXqR3d66nfShjLGfAAxMSvneVwMwno2e17Jbmzt8HBbz525p7O3QO"

// Without gzip — 1250 chars
const withoutGzip = await HideMyJson.encode(logs, { useGzip: false });
// → "4Rj3f1gVDwE2qrEYheA7YwpvuY03umVpPext..."  (1250 characters)

| Mode | Payload size | | ----------------------- | ------------ | | With gzip (default) | 195 chars | | Without gzip | 1,250 chars | | Original JSON | 930 bytes |

All Options Combined

const opts = {
  xorKey: "my-secret-key",
  useGzip: false,
  debug: true,
};

const result = await HideMyJson.encode({ hello: "world" }, opts);
console.log(result.payload);
// → "2oBeeu9YmiH3WIT7ibzPNWA"

console.log(result.steps);
// → {
//     originalJson: '{"hello":"world"}',
//     originalBytes: 17,
//     compressedHex: "7b 22 68 65 ...",
//     compressedBytes: 17,
//     xoredHex: "16 57 1c 0b ...",
//     xoredBytes: 17,
//     encoded: "9Bx3mKz7Wp",
//     encodedBytes: 10
//   }

Debug Mode

Pass debug: true to inspect every stage of the pipeline:

const result = await HideMyJson.encode(
  { hello: "world" },
  { xorKey: "secret", debug: true },
);
console.log(result.steps);
// → {
//     originalJson: '{"hello":"world"}',
//     originalBytes: 17,
//     compressedHex: "1f 8b 08 00 00 ...",    ← gzip output
//     compressedBytes: 37,
//     xoredHex: "6c ee 6b 72 65 ...",         ← after XOR
//     xoredBytes: 37,
//     encoded: "841SU0Las2ERP...",        ← final Base62
//     encodedBytes: 50
//   }

const decoded = await HideMyJson.decode(result.payload, {
  xorKey: "secret",
  debug: true,
});
console.log(decoded.steps);
// → {
//     encoded: "841SU0Las2ER...",
//     encodedBytes: 50,
//     xoredHex: "6c ee 6b 72 65 ...",
//     xoredBytes: 37,
//     compressedHex: "1f 8b 08 00 ...",
//     compressedBytes: 37,
//     recoveredJson: '{"hello":"world"}',
//     recoveredBytes: 17
//   }

API

HideMyJson.encode<T>(value: T, options?): Promise<EncodeResult>

| Option | Type | Default | Description | | --------- | ---------------- | ----------- | -------------------------------------------------- | | xorKey | string \| null | undefined | XOR key for encryption. Skipped if not provided. | | useGzip | boolean | true | Gzip-compress the data before encoding. | | debug | boolean | false | Include intermediate pipeline steps in the result. |

Returns { payload, steps? }

HideMyJson.decode<T>(payload: string, options?): Promise<DecodeResult<T>>

Uses the same options as encode. Returns { data, steps? }

Browser Usage (Script Tag)

<script src="https://cdn.jsdelivr.net/npm/hide-my-json/dist/browser.global.js"></script>
<script>
  const { payload } = await HideMyJson.encode({ hello: "world" });
</script>

Requirements

  • Node.js ≥ 18 or any modern browser (requires CompressionStream / DecompressionStream API when useGzip: true)

License

MIT