CyberChef is a client-side web app and Node.js package for encoding, decoding, encryption, compression, parsing, and data analysis operations. Users build recipes from operations and run them against browser-local input.
Core principles for changes:
- Keep operations and features client-side, avoiding external services whenever possible. CyberChef is used on airgapped networks.
- Keep latency low. Keep large libraries in separate modules so they are downloaded only by users who invoke the relevant operations.
- Prefer Vanilla JS over jQuery or other frameworks.
- Avoid new external package dependencies unless absolutely necessary. Reuse platform APIs and existing project utilities first.
CyberChef expects Node.js >=24 <25.
- Install:
npm install - Development server:
npm start - Production build:
npm run build - Build Node package artifacts:
npm run node - Lint:
npm run lint - Spell/grammar lint for
src:npm run lint:grammar - Full non-UI test suite:
npm test - UI tests:
npm run testui - UI tests against the dev server:
npm run testuidev - Node REPL:
npm run repl
Use the existing generator for new operations:
npm run newopThis wraps node src/core/config/scripts/newOperation.mjs. Run it from the repository root. Afterwards:
- Implement the operation in
src/core/operations/<Operation>.mjs. - Add or verify its category entry in
src/core/config/Categories.json. - Implement the tests in
tests/operations/tests/<Operation>.mjs.
- Indentation: Each block should consist of 4 spaces
- Object/namespace identifiers: CamelCase
- Function/variable names: camelCase
- Constants: UNDERSCORE_UPPER_CASE
- Source code encoding: UTF-8 (without BOM)
- All source files must end with a newline
- Line endings: UNIX style (\n)
Use the existing operation recipe validation framework. Declare constraints in operation ingList entries via operation args so Ingredient and Operation.validateIngredients() can enforce them before run() executes. Do not use checks inside run() when a constraint belongs in argument metadata.
For invalid arguments and failures caused by user input, throw OperationError from src/core/errors/OperationError.mjs. Recipe execution treats OperationError as expected output, and is not appropriate for programmer bugs or unexpected internal exceptions.
Bug fixes require regression tests that must fail before the fix and pass after it. New features require tests including edge cases and invalid input. Use both NodeJS tests and UI tests when a change affects both the operation/API behaviour and browser interaction.
- Operation tests live under
tests/operations/tests/and are run bynpm testthroughtests/operations/index.mjs. - Node API tests live under
tests/node/tests/and are run bynpm testthroughtests/node/index.mjs. - UI tests live under
tests/browser/and are run withnpm run testuiornpm run testuidev.
- Avoid prototype pollution. Utilise
Object.create(null),Map, andObject.prototype.hasOwnProperty.call(...). - Avoid XSS. Escape strings before rendering and prefer text APIs over
innerHTML. - Avoid resource exhaustion. Bound input sizes, counts, recursion depth and loop iterations.
Do not open GitHub issues or pull requests on behalf of users. If a user asks to create an issue or pull request, stage a root-level file named AI_MARKER.