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) | Installation → Quick Start → CLI → Examples |
| Developer (integrate in Node.js code) | Programmatic API → Commercial license |
| Contributor (build from source) | From the repository → Development |
Table of Contents
- Features
- Why StickCode
- Requirements
- Installation
- Quick Start
- Command Line Interface
- Programmatic API
- Supported File Types
- Output Format (.scnp)
- Keys and Security
- Commercial license and device binding
- Examples
- Development
- Full Walkthrough
- License
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
.licfiles, 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.scnpStickCode 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 stickcodeCopy your .lic file into ~/Desktop/stickCode/, then encrypt:
cd ~/Desktop/stickCode
node node_modules/stickcode/stick.js enc img.pngImportant: After
npm install, the CLI is not at~/Desktop/stickCode/stick.js. It lives at~/Desktop/stickCode/node_modules/stickcode/stick.js.
Runningnode stick.jsfrom 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 update3. 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 installnpm 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.nodeTo rebuild manually:
npm run buildVerify the installation:
npm testLinux (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 stickcodeExpected 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 activationProject 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.scnpTrial → 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.licWhen 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.pngIf 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.jsCLI
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.pngDecrypt it back:
cd ~/Desktop/stickCode
node node_modules/stickcode/stick.js dec report.json.scnp
node node_modules/stickcode/stick.js dec img.png.scnpAlternative — npm bin (when the installed package includes a valid shebang):
cd ~/Desktop/stickCode
npx stick enc report.json
npx stick dec report.json.scnpJavaScript (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.dbMode 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--keyin 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) or0x00(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
*.licfile 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 passphrasesDo 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:
- Verifies the license signature with the embedded public key
- Binds the license to this machine (
hostname+platform+arch→ SHA-256 machine id) - On first run, contacts the activation server and stores a signed token in
.device_registrynext to the package - Derives the AES-256 key with HKDF-SHA256 from the server-signed activation token +
licenseId(not fromlicenseIdalone)
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
*.licin the search path → used automatically. - Several
*.licfiles → uselicense.licif present, otherwise pass--licenseexplicitly.
Server example:
sudo mkdir -p /etc/stickcode
sudo cp LIC-2026-HDKLS_FreeNbuy.lic /etc/stickcode/
sudo chmod 600 /etc/stickcode/*.licProject 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.jsonResetting 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_registryIf 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.jsonFix (both steps when moving to a new machine):
Release the seat on the server — StickCode License Dashboard → account → License → Remove on the old device ID.
Or ask your vendor to clearregisteredDevicesfor yourlicenseIdin MongoDB.
Deleting locally does not free a server slot.Clear local cache on the client (only if the file exists after a previous activation on this machine):
rm -f node_modules/stickcode/.device_registryOr in application code:
const stickcode = require('stickcode'); stickcode.resetDevices();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).
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.jsonDecrypt — 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 preprocessingOr 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.mp4Development
Build
npm run buildTest
Runs buffer and stream round-trip tests against test/fixtures/sample.json:
npm testFull 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 testStep 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.jsStep 5 — Verify tests
npm testLicense
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.
