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

stickcode

v6.0.15

Published

Node.js compress + encrypt pipeline (Brotli + AES-256-GCM) with streaming support

Downloads

426

Readme

StickCode

StickCode is a data protection SDK for Node.js that combines compression, encryption, integrity verification, and streaming support into a single API. Protect JSON exports, SQL dumps, application logs, backups, and binary assets without stitching together separate libraries for each step.

Text-like formats (JSON, SQL, HTML, logs, CSV, and similar) benefit from strong compression before encryption. Already-compressed formats (JPEG, MP4, ZIP, PDF, SQLite, and similar) are encrypted with minimal size overhead — StickCode secures them; it does not magically shrink them further.

Under the hood, StickCode uses a native C++ pipeline built on Brotli and AES-256-GCM, exposed through a JavaScript API and a command-line tool for files on disk.

Quick navigation

| I am… | Start here | |-------|------------| | Customer (npm install, .lic file, encrypt files) | InstallationQuick StartCLIExamples | | Developer (integrate in Node.js code) | Programmatic APICommercial license | | Contributor (build from source) | From the repositoryDevelopment |


Table of Contents


Features

  • One-call encrypt and decrypt for buffers and files
  • Integrity verification via AES-256-GCM authentication tags
  • Native C++ pipeline (preprocess, Brotli, AES-256-GCM) via N-API addon
  • Streaming support for large and binary files without loading the entire file into memory
  • Automatic mode selection in the CLI: buffer for small text, stream for large or binary inputs
  • Strong compression on text-like data where it matters
  • Encryption on all data, including binary and already-compressed formats
  • Commercial licensing — RSA-signed .lic files, device binding, HKDF key derivation

Why StickCode

A typical manual workflow splits protection across several steps and libraries:

Without StickCode

// compress
const compressed = zlib.brotliCompressSync(data, brotliOptions);

// encrypt
const iv = crypto.randomBytes(12);
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
const encrypted = Buffer.concat([cipher.update(compressed), cipher.final()]);
const tag = cipher.getAuthTag();

// assemble wire format, handle streams separately for large files, …

With StickCode (licensed production build)

const stickcode = require('stickcode');

await stickcode.initFromFile(); // finds *.lic in project folder
const packed = stickcode.encrypt(data, { quality: 6 });
const restored = stickcode.decrypt(packed);

Same pipeline for files on disk:

cd ~/Desktop/stickCode
node node_modules/stickcode/stick.js enc report.json
node node_modules/stickcode/stick.js dec report.json.scnp

StickCode handles compression, encryption, authenticated integrity, output framing, and streaming — so you do not wire each layer yourself.


Requirements

Customers (npm install)

| Requirement | Version / notes | |---|---| | Node.js | 18 or newer | | npm | npm install stickcode | | Commercial license | .lic file from vendor | | Internet | Required on first run per machine (device activation) |

Prebuilt native binaries are included for common platforms (linux-x64, darwin-x64, darwin-arm64). No compiler needed on the customer machine when a prebuild matches.

Contributors (build from source)

| Requirement | Version / notes | |---|---| | Native addon | Prebuilt via prebuilds/ when available. Falls back to source compile if no match | | Build all prebuilds | npm run prebuild:all (host + Linux via Docker). CI: .github/workflows/stickcode-prebuilds.yml | | C++ toolchain | Required when no matching prebuild: build-essential + libssl-dev on Linux, Xcode CLT on macOS | | OpenSSL | Linux: sudo apt install libssl-dev (Debian/Ubuntu). macOS: Homebrew OpenSSL for source builds | | Brotli C sources | Must be present in the parent repository at ../c/ (this package is built inside the Brotli tree) |

macOS build note: The native addon links against OpenSSL at /usr/local/opt/openssl. If your OpenSSL is installed elsewhere (for example Apple Silicon Homebrew at /opt/homebrew/opt/openssl), adjust the paths in binding.gyp before building.


Installation

Install in your project folder

mkdir -p ~/Desktop/stickCode
cd ~/Desktop/stickCode
npm init -y
npm install stickcode

Copy your .lic file into ~/Desktop/stickCode/, then encrypt:

cd ~/Desktop/stickCode
node node_modules/stickcode/stick.js enc img.png

Important: After npm install, the CLI is not at ~/Desktop/stickCode/stick.js. It lives at
~/Desktop/stickCode/node_modules/stickcode/stick.js.
Running node stick.js from the project root without that file causes:
Error: Cannot find module '/home/…/stickCode/stick.js'.

Updating StickCode

StickCode follows semver. Within 6.x, patch and minor releases are backward compatible — existing .scnp files decrypt without re-encryption.

1. Declare a caret range in package.json (created automatically by npm install stickcode --save):

{
  "dependencies": {
    "stickcode": "^6.0.14"
  }
}

The ^ allows npm update to pull 6.0.15, 6.1.0, etc. without editing package.json.

2. Update:

npm update stickcode
# or: npm update

3. Verify:

npm list stickcode

| Range in package.json | npm update stickcode | |-----------------------|-------------------------| | "^6.0.14" ✅ | Upgrades within 6.x | | "6.0.14" (exact) ❌ | Does not upgrade — change version manually |

Your *.lic file and device activation stay the same. See Versioning for wire-format compatibility.


From the repository

Clone or copy the project so the layout includes both the Brotli c/ directory and the node/ package:

brotli/
  c/              # Brotli C library (required)
  node/           # StickCode package (this directory)
    package.json
    binding.gyp
    src/
    ...

Install and compile the native addon:

cd node
npm install

npm install runs lib/check-prebuild-install.js: loads a prebuilt binary from prebuilds/ when available, otherwise compiles via binding.gyp + node-gyp. For local development you can also run:

node/build/Release/stickcode_native.node

To rebuild manually:

npm run build

Verify the installation:

npm test

Linux (compile from source)

When no prebuild matches your OS/arch, install build dependencies first:

sudo apt update
sudo apt install -y build-essential python3 libssl-dev
npm install stickcode

Expected output:

All tests passed.

Quick Start

Example project layout

Typical customer install on Linux or macOS:

~/Desktop/stickCode/
├── LIC-2026-9YUIE_demo_1.lic     ← your license file
├── img.png                       ← file to encrypt
├── img.png.scnp                  ← created after encrypt
├── package.json
├── package-lock.json
└── node_modules/
    └── stickcode/
        ├── stick.js              ← CLI — run this path (encrypt / decrypt)
        └── .device_registry      ← hidden; created after first activation

Project folder: ~/Desktop/stickCode
CLI path (after npm install): ~/Desktop/stickCode/node_modules/stickcode/stick.js

One license in the project folder (typical customer): StickCode auto-finds the only *.lic file — you do not need --license:

cd ~/Desktop/stickCode
node node_modules/stickcode/stick.js enc img.png
node node_modules/stickcode/stick.js dec img.png.scnp

Trial → paid (or switching between two license files): Keep only one .lic in the folder, or pass --license explicitly when both files are present (for example during migration):

cd ~/Desktop/stickCode

# Still on trial — encrypt with trial license file:
node node_modules/stickcode/stick.js enc img.png --license ./LIC-2026-TRIAL_demo.lic

# Upgraded to paid — point at the new file (or replace the old .lic and run without --license):
node node_modules/stickcode/stick.js enc report.json --license ./LIC-2026-FreeNbuy.lic

When the licenseId inside the file changes, StickCode clears the local .device_registry and contacts the activation server again for the new license. Each license has its own device slot (maxDevices) on the server — trial and paid are separate licenses.

Recommended when upgrading: remove or rename the old trial .lic, leave only the paid file in ~/Desktop/stickCode/, then run without --license:

mv LIC-2026-TRIAL_demo.lic ~/Desktop/old/
node node_modules/stickcode/stick.js enc img.png

If activation fails with device limit exceeded, free the slot in the StickCode License Dashboard (Remove old device) or ask your vendor.

There is no stick.js in the project root unless you create a symlink yourself (not required):

ln -sf node_modules/stickcode/stick.js ~/Desktop/stickCode/stick.js

CLI

Encrypt a file (creates report.json.scnp):

cd ~/Desktop/stickCode
node node_modules/stickcode/stick.js enc report.json
node node_modules/stickcode/stick.js enc img.png

Decrypt it back:

cd ~/Desktop/stickCode
node node_modules/stickcode/stick.js dec report.json.scnp
node node_modules/stickcode/stick.js dec img.png.scnp

Alternative — npm bin (when the installed package includes a valid shebang):

cd ~/Desktop/stickCode
npx stick enc report.json
npx stick dec report.json.scnp

JavaScript (licensed)

Place one *.lic in the project folder, then:

const fs = require('fs');
const stickcode = require('stickcode');

await stickcode.initFromFile();

const data = fs.readFileSync('report.json');
const packed = stickcode.encrypt(data, { quality: 6 });
const restored = stickcode.decrypt(packed);

For files on disk, use Streaming API or the encrypt-backup.js example.


Command Line Interface

Entry point: node_modules/stickcode/stick.js (npm bin name: stick).
In a project such as ~/Desktop/stickCode, always use the full path under node_modules:

node node_modules/stickcode/stick.js enc <file> [options]

Commands

| Command | Description | |---|---| | stick enc <file> [quality] | Encrypt and compress a file | | stick dec <file.scnp> [output] | Decrypt and decompress a .scnp file | | stick help | Show usage |

Long forms encrypt and decrypt are also supported.

Options

| Option | Description | |---|---| | -o, --output <path> | Output file path | | --quality <n> | Brotli quality level (0–11, default 6) | | --license <file> | Path to .lic file (optional if exactly one *.lic is in the search path) | | --key <passphrase> | Passphrase → SHA-256 key (development builds only; disabled in published npm) | | --stream | Force streaming mode | | --buffer | Force in-memory mode (small files only) | | --no-verify | Skip round-trip verification after encrypt |

Environment variables

| Variable | Description | |---|---| | STICKCODE_LICENSE_FILE | Path to .lic file (same as --license) |

CLI examples

All examples assume you are in ~/Desktop/stickCode:

cd ~/Desktop/stickCode

# Text and code
node node_modules/stickcode/stick.js enc config.json
node node_modules/stickcode/stick.js enc schema.sql --quality 8
node node_modules/stickcode/stick.js enc index.html
node node_modules/stickcode/stick.js enc app.js
node node_modules/stickcode/stick.js enc legacy.asp
node node_modules/stickcode/stick.js enc api.php

# Data and logs
node node_modules/stickcode/stick.js enc backup.csv
node node_modules/stickcode/stick.js enc server.log

# Binary and large files (streaming is selected automatically)
node node_modules/stickcode/stick.js enc photo.jpg
node node_modules/stickcode/stick.js enc img.png
node node_modules/stickcode/stick.js enc clip.mp4
node node_modules/stickcode/stick.js enc backup.sqlite
node node_modules/stickcode/stick.js enc backup.sqlite --stream

# Custom output path
node node_modules/stickcode/stick.js enc secret.db -o secret.db.scnp
node node_modules/stickcode/stick.js dec secret.db.scnp -o secret.db

Mode selection (automatic)

| Input | Default mode | |---|---| | Text file under 8 MB | Buffer (native C++ pipeline) | | Binary file over 512 KB | Stream | | Any file 8 MB or larger | Stream |

Override with --stream or --buffer when needed.


Programmatic API

Main module: require('stickcode') — resolves to stickcode-native.js inside the package. In the repository source tree you may also use require('./stickcode-native.js').

const stickcode = require('stickcode');

Published npm builds require a commercial license — call init() or initFromFile() before encrypt/decrypt. Raw 32-byte keys and --key are disabled.


Production usage (licensed)

const fs = require('fs');
const stickcode = require('stickcode');

// 1. Load license + activate device (once per process)
await stickcode.initFromFile();
// or: await stickcode.initFromFile('/path/to/license.lic');

// 2. Buffer — small/medium payloads
const input = fs.readFileSync('report.json');
const packed = stickcode.encrypt(input, { quality: 6 });
const restored = stickcode.decrypt(packed);

// 3. Stream — large files, DB dumps, video
await stickcode.pipeEncrypt(
  fs.createReadStream('backup.sql'),
  fs.createWriteStream('backup.sql.scnp'),
  { quality: 6 }
);
await stickcode.pipeDecrypt(
  fs.createReadStream('backup.sql.scnp'),
  fs.createWriteStream('backup.sql.restored')
);

Complete API reference

| Function | Description | |----------|-------------| | Encryption | | | encrypt(input, options?) | Buffer in → compressed + encrypted Buffer out (after init) | | decrypt(input) | Reverse of encrypt() | | pipeEncrypt(source, dest, options?) | Stream encrypt file → .scnp | | pipeDecrypt(source, dest) | Stream decrypt .scnp → restored file | | createEncryptStream(options?) | Low-level { input, output } encrypt streams | | createDecryptStream() | Low-level { input, output } decrypt streams | | Compression only | | | compressOnly(input, options?) | Preprocess + Brotli, no AES (version 0x00) | | encodePipeline(input, options?) | Compress pipeline without AES wrapper | | decodePipeline(input) | Decompress pipeline output | | License & device | | | init(licenseJson) | Verify RSA license, activate device, derive AES key | | initFromFile(path?) | Load .lic from disk + init(); returns resolved path | | verifyLicense(license) | Parse and verify signature only (no activation) | | getMachineId() | SHA-256 device id (hostname + platform + arch) | | getLicenseFeatures() | Feature flags from license payload | | resetDevices() | Delete local .device_registry | | readLicenseFile(path?) | Resolve and parse .lic file | | resolveLicensePath(path?) | Resolve path without reading | | Constants | | | FLAGS | Preprocess flags: CLEAN, LOWERCASE, TRANSPOSE | | VERSION | License module version | | VERSION_NATIVE | Native addon version | | DEFAULT_LICENSE_NAME | Preferred filename when several .lic files exist (license.lic) |

Streaming helpers are exported from the same module:

const {
  encrypt,
  decrypt,
  compressOnly,
  encodePipeline,
  decodePipeline,
  pipeEncrypt,
  pipeDecrypt,
  createEncryptStream,
  createDecryptStream,
  initFromFile,
  getMachineId,
  FLAGS,
} = require('stickcode');

Buffer API

Best for small and medium text payloads held fully in memory.

encrypt(input, options?)

Runs preprocess (optional) → Brotli → AES-256-GCM. Requires init() / initFromFile() first in licensed builds.

await stickcode.initFromFile();
const packed = stickcode.encrypt(inputBuffer, {
  quality: 6,
  preprocessFlags: 0,
  tokenize: false,
});

Returns a Buffer in buffer wire format (see Output Format).

decrypt(input)

Reverses encrypt().

const restored = stickcode.decrypt(packed);

Compression without encryption

compressOnly(input, options?)

Preprocess and Brotli only (version byte 0x00, no AES).

encodePipeline(input, options?) / decodePipeline(input)

Lower-level access to the compress/decompress pipeline without the AES wrapper.


Streaming API

Best for large files and binary data (video, images, databases). Uses Node.js streams and keeps memory usage low. Compression benefit is minimal on already-compressed formats; the main value is encrypted, authenticated output without loading the entire file into memory.

pipeEncrypt(source, destination, options?)

const fs = require('fs');

await stickcode.initFromFile();
await stickcode.pipeEncrypt(
  fs.createReadStream('video.mp4'),
  fs.createWriteStream('video.mp4.scnp'),
  { quality: 6 }
);

pipeDecrypt(source, destination)

await stickcode.pipeDecrypt(
  fs.createReadStream('video.mp4.scnp'),
  fs.createWriteStream('video.mp4')
);

Low-level streams

await stickcode.initFromFile();
const { input, output } = stickcode.createEncryptStream({ quality: 6 });
const { input: decIn, output: decOut } = stickcode.createDecryptStream();

Wire input / output with stream/promises.pipeline or the provided pipeEncrypt / pipeDecrypt helpers.


License and device functions

| Function | When to use | |----------|-------------| | initFromFile() | Start here — load .lic, activate device, derive key | | init(licenseJson) | Same as above when you already have parsed license JSON | | getMachineId() | Debug / match against dashboard device list | | getLicenseFeatures() | Check enabled features from license payload | | resetDevices() | Clear local .device_registry before re-activation | | verifyLicense(license) | Validate signature without activating |

await stickcode.initFromFile();
console.log('Device ID:', stickcode.getMachineId());
console.log('Features:', stickcode.getLicenseFeatures());

See Commercial license and device binding for .lic placement, activation errors, and device limits.

Repository development only: when requireLicense: false (source tree), you may pass a 32-byte key or use --key in the CLI. Published npm disables raw keys.

Options reference

| Option | Type | Default | Description | |---|---|---|---| | quality | number | 6 | Brotli quality (0–11) | | preprocessFlags | number | 0 | Preprocessing flags (see FLAGS) | | tokenize | boolean | false | Enable tokenizer stage (off by default for speed) | | delimiter | number | 0 | CSV/TSV delimiter hint when preprocessing | | compressOnly | boolean | false | Stream only: skip AES (see createEncryptStream) |

CLI environment: set STICK_TRANSPOSE_CSV=1 to enable CSV transpose preprocessing for .csv / .tsv files.

Preprocess flags (FLAGS)

| Flag | Value | Description | |---|---|---| | FLAGS.CLEAN | 1 | Normalize whitespace | | FLAGS.LOWERCASE | 2 | Lowercase text | | FLAGS.TRANSPOSE | 4 | Transpose columnar data (CSV/TSV); can improve compression |

For binary files (images, video, databases), keep preprocessFlags: 0.


Supported File Types

StickCode works on any file at the byte level. Compression results depend on how compressible the content already is.

Strong compression (text-like)

JSON, JSONL, HTML, JS, TS, CSS, SQL, PHP, ASP, ASPX, XML, YAML, CSV, TSV, logs, Markdown, shell scripts, and similar plain-text formats.

Encryption with minimal size change (already compressed or binary)

JPEG, PNG, GIF, WebP, MP4, MOV, AVI, MKV, SQLite (.db, .sqlite), PDF, ZIP, and other binary formats. StickCode still encrypts and protects these files; output size is typically close to the original plus a small header overhead.


Output Format (.scnp)

Encrypted output files use the .scnp extension by convention. Two wire layouts exist depending on how the file was created:

Buffer format (native encrypt())

Produced by the buffer API and by the CLI when buffer mode is selected.

[version:1][iv:12][tag:16][ciphertext...]
  • version = 0x05 (encrypted) or 0x00 (compress-only)

Stream format (pipeEncrypt() / CLI stream mode)

[version:1][iv:12][ciphertext...][tag:16]

The authentication tag is appended at the end of the file in stream mode. Always decrypt using the same mode that created the file. The CLI dec command detects the format automatically.


Keys and Security

  • Algorithm: AES-256-GCM
  • Key size: 32 bytes (derived via HKDF after license activation — not stored in your code)
  • CLI (production): place a *.lic file in the project folder, or pass --license / STICKCODE_LICENSE_FILE
  • CLI (development / repository build): --key <passphrase>SHA-256(passphrase)not available in published npm

The CLI does not ship with a default encryption key. With one .lic in the folder, no flags are needed. With several .lic files, pass --license or rename the active file to license.lic.

In application code (production):

await stickcode.initFromFile();
// key is derived internally — do not hard-code passphrases

Do not ship production passphrases in source code.


Commercial license and device binding

For licensed deployments, call init() with your RSA-signed license JSON (same format as legacy StickCode). The SDK:

  1. Verifies the license signature with the embedded public key
  2. Binds the license to this machine (hostname + platform + arch → SHA-256 machine id)
  3. On first run, contacts the activation server and stores a signed token in .device_registry next to the package
  4. Derives the AES-256 key with HKDF-SHA256 from the server-signed activation token + licenseId (not from licenseId alone)

Where to put the license file (.lic)

The vendor delivers a signed license file with extension .lic (JSON inside: payload + signature).
The filename can include the customer name, e.g. LIC-2026-HDKLS_FreeNbuy.lic.

StickCode auto-discovers any *.lic in these folders (first match wins; see rules below):

| Priority | Folder | |----------|--------| | 1 | Path from --license or STICKCODE_LICENSE_FILE | | 2 | ./ (current working directory) | | 3 | ~/.config/stickcode/ | | 4 | ~/.stickcode/ | | 5 | /etc/stickcode/ |

Auto-pick rules:

  • One *.lic in the search path → used automatically.
  • Several *.lic files → use license.lic if present, otherwise pass --license explicitly.

Server example:

sudo mkdir -p /etc/stickcode
sudo cp LIC-2026-HDKLS_FreeNbuy.lic /etc/stickcode/
sudo chmod 600 /etc/stickcode/*.lic

Project example: copy your .lic to the project root; add *.lic to .gitignore.

Do not commit license files to version control.

Not the same file: after first activation, the SDK writes .device_registry inside node_modules/stickcode/. That file is machine-specific — do not copy it between servers.

There is no top-level node/ folder in a normal npm install — only node_modules/stickcode/ (the installed package).

const stickcode = require('stickcode');

// Auto-finds the only *.lic (or license.lic if several)
await stickcode.initFromFile();

// Or explicit path:
await stickcode.initFromFile('/etc/stickcode/LIC-2026-HDKLS_FreeNbuy.lic');

CLI (from ~/Desktop/stickCode):

cd ~/Desktop/stickCode

# Single *.lic in cwd — no flag needed:
node node_modules/stickcode/stick.js enc data.json
node node_modules/stickcode/stick.js enc img.png

# Explicit path (required when multiple .lic files exist):
node node_modules/stickcode/stick.js enc data.json --license ./LIC-2026-ACME_Client.lic

export STICKCODE_LICENSE_FILE=~/Desktop/stickCode/LIC-2026-9YUIE_demo_1.lic
node node_modules/stickcode/stick.js enc data.json

Resetting devices and fixing activation errors

Activation uses two separate stores:

| Store | Location | What it controls | |-------|----------|------------------| | Server (MongoDB) | Managed via StickCode License Dashboard | How many machines may activate (maxDevices) | | Local cache | node_modules/stickcode/.device_registry | Skips re-contacting the server on later runs on this machine |

Deleting only one side causes confusing errors.

Where is .device_registry?

After the first successful activation:

~/Desktop/stickCode/
├── LIC-2026-….lic
├── img.png
├── package.json
└── node_modules/
    └── stickcode/
        ├── stick.js              ← CLI
        └── .device_registry    ← hidden file (starts with a dot)

Find it:

cd ~/Desktop/stickCode
ls -la node_modules/stickcode/.device_registry

If the file is missing: this machine has never completed activation, or node_modules was removed/reinstalled (npm install deletes it). That is normal — you do not need the file to exist before the first run.

Error: Device limit exceeded (or similar)

This comes from the activation server, not from a missing local file. It means the license already has maxDevices machines registered on the server for that licenseId.

Typical project layout (no node/ directory):

~/Desktop/stickCode/
├── LIC-2026-9YUIE_demo_1.lic
├── img.png
├── node_modules/stickcode/stick.js
├── package.json
└── package-lock.json

Fix (both steps when moving to a new machine):

  1. Release the seat on the server — StickCode License Dashboard → account → LicenseRemove on the old device ID.
    Or ask your vendor to clear registeredDevices for your licenseId in MongoDB.
    Deleting locally does not free a server slot.

  2. Clear local cache on the client (only if the file exists after a previous activation on this machine):

    rm -f node_modules/stickcode/.device_registry

    Or in application code:

    const stickcode = require('stickcode');
    stickcode.resetDevices();
  3. Run again with internet — first successful run re-registers this machine:

    cd ~/Desktop/stickCode
    node node_modules/stickcode/stick.js enc data.json
    node node_modules/stickcode/stick.js enc img.png

Check which license is blocking you — the .lic filename can differ from the licenseId inside:

node -e "
const fs=require('fs');
const lic=JSON.parse(fs.readFileSync('LIC-2026-9YUIE_demo_1.lic','utf8'));
console.log(JSON.parse(Buffer.from(lic.payload,'base64')));
"

Remove the device for that licenseId in the dashboard, not a different one.

Summary

| Situation | Action | |-----------|--------| | New machine, no .device_registry | Remove old device in dashboard, then activate with internet | | Device limit exceeded | Server still full — dashboard Remove, not local file delete | | Replacing hardware on same project | Dashboard Remove old ID + rm node_modules/stickcode/.device_registry + re-run | | After npm install / fresh clone | Local registry gone; server slots unchanged — clear server if needed |

Published npm builds: runtime JS is obfuscated and signed with a trailing //<sha256> hash. Tampering causes process.exit(1).

See examples/license-init.js.


Examples

CLI only (no script)

One-off encrypt/decrypt from the terminal — see Quick Start.

Your own script (company pipeline)

Customers can create a .js file in their project (or copy one from the package) to automate backups, exports, or uploads. StickCode ships with ready-made examples under node_modules/stickcode/examples/ after npm install.

Typical flow: export from DB → encrypt to .scnp → upload .scnp to your server / S3 / blob storage (upload step is yours — StickCode only produces the encrypted file).

From ~/Desktop/stickCode:

cd ~/Desktop/stickCode

# Encrypt a SQL dump or JSON export (uses your .lic automatically):
node node_modules/stickcode/examples/encrypt-file-licensed.js backup.sql
node node_modules/stickcode/examples/encrypt-file-licensed.js export.json -o secure/export.json.scnp

# Then upload the .scnp with your tools, e.g.:
# scp backup.sql.scnp user@company-server:/backups/
# aws s3 cp export.json.scnp s3://my-bucket/secure/

Example file — save as encrypt-backup.js in your project (e.g. ~/Desktop/stickCode/):

'use strict';

const fs = require('fs');
const path = require('path');
const stickcode = require('stickcode');

async function main() {
  const inputPath = path.resolve(process.argv[2]);
  if (!inputPath || !fs.existsSync(inputPath)) {
    console.error('Usage: node encrypt-backup.js <file>');
    process.exit(1);
  }

  // Auto-finds *.lic in project folder
  const licensePath = await stickcode.initFromFile();
  const outputPath = inputPath + '.scnp';

  await stickcode.pipeEncrypt(
    fs.createReadStream(inputPath),
    fs.createWriteStream(outputPath),
    { quality: 6 }
  );

  console.log('License:   ', licensePath);
  console.log('Encrypted: ', outputPath);
  console.log('Next: upload', outputPath, 'to your server / S3 / database');
}

main().catch((err) => {
  console.error(err.message || err);
  process.exit(1);
});

Run:

cd ~/Desktop/stickCode
node encrypt-backup.js backup.sql
node encrypt-backup.js export.json

Decrypt — save as decrypt-backup.js:

'use strict';

const fs = require('fs');
const path = require('path');
const stickcode = require('stickcode');

async function main() {
  const inputPath = path.resolve(process.argv[2]);
  if (!inputPath || !fs.existsSync(inputPath)) {
    console.error('Usage: node decrypt-backup.js <file.scnp>');
    process.exit(1);
  }

  await stickcode.initFromFile();
  const outputPath = inputPath.replace(/\.scnp$/i, '') + '.restored';

  await stickcode.pipeDecrypt(
    fs.createReadStream(inputPath),
    fs.createWriteStream(outputPath)
  );

  console.log('Restored:', outputPath);
}

main().catch((err) => {
  console.error(err.message || err);
  process.exit(1);
});
node decrypt-backup.js backup.sql.scnp

| File | When to use | |---|---| | examples/encrypt-file-licensed.js | Licensed file → .scnp for upload / archive (SQL, JSON, DB dumps) | | examples/buffer-text.js | JSON, SQL, HTML, JS — data already in a Buffer | | examples/stream-file.js | Large or binary files on disk (MP4, JPG, SQLite) — stream encrypt/decrypt | | examples/compress-only.js | Brotli compression without encryption | | examples/custom-key.js | Passphrase or STICK_KEY environment variable (development only) | | examples/license-init.js | RSA license + init() + device activation (in-memory demo) | | examples/csv-transpose.js | CSV/TSV with optional transpose preprocessing |

Index: examples/README.md

Run an example:

npm run example:buffer    # small text: encrypt/decrypt in memory
npm run example:stream    # files: stream encrypt/decrypt
npm run example:compress  # Brotli only, no AES
npm run example:key       # passphrase / STICK_KEY
npm run example:csv       # CSV transpose preprocessing

Or directly (customer project):

cd ~/Desktop/stickCode
node node_modules/stickcode/examples/encrypt-file-licensed.js backup.sql
node node_modules/stickcode/examples/buffer-text.js
node node_modules/stickcode/examples/stream-file.js ./my-video.mp4

Development

Build

npm run build

Test

Runs buffer and stream round-trip tests against test/fixtures/sample.json:

npm test

Full Walkthrough

This section walks through a complete workflow: install, encrypt several file types, decrypt them, and use the API directly.

Step 1 — Install

cd node
npm install
npm test

Step 2 — Encrypt files with the CLI

From the node/ package directory (repository development):

# JSON configuration
node stick.js enc ./test/fixtures/sample.json

# SQL dump (example path)
node stick.js enc ./schema.sql --quality 8

# Image (stream mode, encryption-focused)
node stick.js enc ./photo.jpg

# Video — stream mode (encryption + integrity; file size stays roughly the same)
node stick.js enc ./clip.mp4 --key "demo-production-key"

Each command writes a sibling file with a .scnp extension, for example sample.json.scnp.

Step 3 — Decrypt files

node stick.js dec ./test/fixtures/sample.json.scnp
node stick.js dec ./clip.mp4.scnp ./clip-restored.mp4 --key "demo-production-key"

If no output path is given, the CLI derives the original name by removing .scnp from the input filename.

Step 4 — Run the code examples

Pick the example that matches your use case:

# Text / JSON / SQL in memory
node examples/buffer-text.js

# File on disk (same pattern for video, images, .db)
node examples/stream-file.js ./test/fixtures/sample.json

# Compression without encryption
node examples/compress-only.js

# Production-style key from environment
STICK_KEY="demo-production-key" node examples/custom-key.js

Step 5 — Verify tests

npm test

License

StickCode is proprietary software (npm: UNLICENSED). Use in production requires a valid commercial license issued by the copyright holder (RSA-signed license file + device activation where applicable). See the full LICENSE agreement and SPECIFICATION.md for sales and technical evaluation.

| What | License | |------|---------| | StickCode package (this npm module) | Proprietary — LICENSE | | Brotli C library (bundled c/) | MIT — see THIRD_PARTY_NOTICES.md | | OpenSSL (linked at build time) | See THIRD_PARTY_NOTICES.md |

Copyright (c) 2026 Ygal Brami. All rights reserved.

For pricing and license purchases, contact the vendor listed in LICENSE.