RepoPilotOpen in app โ†’

trekhleb/javascript-algorithms

๐Ÿ“ Algorithms and data structures implemented in JavaScript with explanations and links to further readings

WAIT

Single-maintainer risk โ€” review before adopting

  • โœ“Last commit 3mo ago
  • โœ“5 active contributors
  • โœ“MIT licensed
  • โœ“CI configured
  • โœ“Tests present
  • โš Small team โ€” 5 top contributors
  • โš Single-maintainer risk โ€” top contributor 86% of commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Embed this verdict

[![RepoPilot: WAIT](https://repopilot.app/api/badge/trekhleb/javascript-algorithms)](https://repopilot.app/r/trekhleb/javascript-algorithms)

Paste into your README โ€” the badge live-updates from the latest cached analysis.

Onboarding doc

Onboarding: trekhleb/javascript-algorithms

Generated by RepoPilot ยท 2026-05-04 ยท Source

Verdict

WAIT โ€” Single-maintainer risk โ€” review before adopting

  • Last commit 3mo ago
  • 5 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • โš  Small team โ€” 5 top contributors
  • โš  Single-maintainer risk โ€” top contributor 86% of commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

TL;DR

A comprehensive reference implementation of 50+ classical algorithms and data structures written in plain JavaScript (ES6+), covering everything from sorting and graph traversal to cryptography (Caesar cipher, Hill cipher, polynomial hashing) and dynamic programming. It solves the problem of having a single, well-tested, well-documented JavaScript source for CS fundamentals, with each implementation living alongside its own README and linked to further reading. Flat feature-based monolith under src/: src/algorithms/ and src/data-structures/ each contain subdirectories per topic (e.g. src/algorithms/cryptography/hill-cipher/hillCipher.js), each with its own test folder and README.md. There is no shared runtime framework โ€” each algorithm is a self-contained JS module.

Who it's for

CS students, self-taught developers preparing for technical interviews, and JavaScript engineers who want to study or reference canonical algorithm implementations in a language they already know. Contributors are typically educators or developers adding new algorithms with explanations.

Maturity & risk

The repo has 180k+ GitHub stars, uses Jest 30 for tests, has a GitHub Actions CI pipeline at .github/workflows/CI.yml running lint + coverage, and enforces pre-commit hooks via Husky. It is actively maintained (Node >=22 engine requirement shows recent updates), making it production-stable as a reference library, though not intended as a runtime dependency.

Minimal dependency risk: all dependencies are devDependencies (Jest, Babel, ESLint, Husky) โ€” there are zero runtime production dependencies. Single primary maintainer (trekhleb) is a concentration risk for long-term maintenance. The project is a reference/educational repo rather than a shipped library, so breaking changes are low-stakes.

Active areas of work

Recent activity visible includes Node engine bump to >=22.0.0, Jest upgrade to ^30.2.0, and Husky upgrade to ^9.1.7 (prepare script), suggesting a dependency refresh cycle is underway. No specific new algorithm PRs are visible from the provided data.

Get running

git clone https://github.com/trekhleb/javascript-algorithms.git && cd javascript-algorithms && nvm use && npm install && npm test

Daily commands: npm test โ€” runs the full Jest suite. npm run coverage โ€” generates coverage report. npm run lint โ€” runs ESLint across src/**. npm run ci โ€” runs both lint and coverage (used in GitHub Actions).

Map of the codebase

  • src/algorithms/graph/dijkstra/dijkstra.js โ€” Core implementation of Dijkstra's shortest-path algorithm; exemplifies the canonical pattern all graph algorithms follow in this repo.
  • src/algorithms/graph/breadth-first-search/breadthFirstSearch.js โ€” BFS is a foundational traversal primitive reused by many higher-level graph algorithms throughout the codebase.
  • src/algorithms/graph/depth-first-search/depthFirstSearch.js โ€” DFS is the other core traversal primitive; articulation-points, bridges, cycle detection, and topological sort all build on it.
  • src/algorithms/cryptography/polynomial-hash/PolynomialHash.js โ€” The production-quality rolling-hash implementation that underpins Rabin-Karp and other string algorithms; shows the numeric-precision patterns used repo-wide.
  • jest.config.js โ€” Central Jest configuration that controls Babel transforms, test discovery glob patterns, and coverage settings for all 600 files.
  • package.json โ€” Defines the single set of dev dependencies (Jest, Babel, ESLint) and npm scripts that build, lint, and test every algorithm in the repo.
  • .babelrc โ€” Babel preset configuration that enables ES-module syntax across all algorithm source files; changing it breaks the entire test suite.

How to make changes

Add a new graph algorithm

  1. Create a new directory under the graph algorithms folder following the kebab-case naming convention (src/algorithms/graph/my-new-algorithm/myNewAlgorithm.js)
  2. Implement the algorithm; import GraphVertex/GraphEdge helpers from the data-structures layer the same way dijkstra.js does (src/algorithms/graph/my-new-algorithm/myNewAlgorithm.js)
  3. Create a co-located test directory and write Jest tests mirroring the pattern in the dijkstra test file (src/algorithms/graph/my-new-algorithm/__test__/myNewAlgorithm.test.js)
  4. Add a README.md with algorithm explanation, complexity table, and references, following the dijkstra README as a template (src/algorithms/graph/my-new-algorithm/README.md)

Add a new cryptography algorithm

  1. Create a directory under the cryptography folder with the cipher or hash name in kebab-case (src/algorithms/cryptography/my-cipher/myCipher.js)
  2. Implement encode and decode (or hash) functions exported as named exports, matching the pattern in caesarCipher.js (src/algorithms/cryptography/my-cipher/myCipher.js)
  3. Add Jest tests covering both encode and decode paths, including edge cases, mirroring the caesar cipher test (src/algorithms/cryptography/my-cipher/__test__/myCipher.test.js)
  4. Write a README.md explaining the cipher with ASCII-art examples in the style of the hill-cipher README (src/algorithms/cryptography/my-cipher/README.md)

Add a cycle detection variant

  1. Add a new JS file in the existing detect-cycle directory for the new variant (e.g., directed cycle using coloring) (src/algorithms/graph/detect-cycle/detectDirectedCycleColoring.js)
  2. Implement the variant, reusing the DFS primitive from depthFirstSearch.js as the existing variants do (src/algorithms/graph/depth-first-search/depthFirstSearch.js)
  3. Add a dedicated test file in the detect-cycle test folder following the existing three-test-file pattern (src/algorithms/graph/detect-cycle/__test__/detectDirectedCycleColoring.test.js)

Add a new polynomial hash variant

  1. Create a new file in the polynomial-hash directory; study PolynomialHash.js for the BigInt precision pattern to replicate or simplify (src/algorithms/cryptography/polynomial-hash/MyHash.js)
  2. Export a class with at minimum a hash(word) method and optionally a roll(prevHash, prevChar, newChar, wordLength) method (src/algorithms/cryptography/polynomial-hash/MyHash.js)
  3. Add tests to the existing test folder, testing hash consistency and rolling-window correctness (src/algorithms/cryptography/polynomial-hash/__test__/MyHash.test.js)

Why these technologies

  • JavaScript (ES2015+) โ€” Maximises accessibility for web developers learning algorithms; no compile step needed to read source, and the language is ubiquitous in browser and Node environments.
  • Jest โ€” Zero-config test runner with built-in coverage, snapshot support, and excellent Babel integration; lets each algorithm be verified in isolation with a single command.
  • Babel โ€” Allows ES-module import/export syntax in source files while Jest (which uses CommonJS) can still consume them without native ESM complexity.
  • ESLint + Husky pre-commit โ€” Enforces consistent code style across hundreds of algorithm files contributed by many open-source authors without requiring CI to catch style regressions.

Trade-offs already made

  • Co-locate tests next to source in test directories

    • Why: Makes it trivial for contributors to find and update the test when they touch an algorithm file.
    • Consequence: The src/ tree contains both production code and tests, slightly inflating the apparent codebase size and requiring test-exclusion globs in tooling.
  • Use BigInt inside PolynomialHash for modular arithmetic

    • Why: JavaScript Number loses precision beyond 2^53; rolling hash requires exact modular arithmetic to avoid false positives in Rabin-Karp.
    • Consequence: BigInt operations are 10โ€“100ร— slower than Number; acceptable for an educational codebase but unsuitable for performance-critical production use.
  • Flat file-per-algorithm structure with no shared runtime framework

    • Why: Each algorithm is independently understandable; contributors don't need to learn a custom framework before adding an algorithm.
    • Consequence: Common graph data structures (GraphVertex, GraphEdge) are duplicated or imported ad-hoc rather than published as a versioned shared package.
  • README-first documentation inside each algorithm folder

    • Why: Keeps documentation and code in sync and allows GitHub to render explanations alongside source without an external docs site.
    • Consequence: No automated doc generation; READMEs can drift from implementation as algorithms evolve.

Non-goals (don't propose these)

  • Production-grade performance tuning or WASM optimization
  • Browser bundle / npm package publishing for direct consumption
  • A unified CLI or REPL to run algorithms interactively
  • Benchmarking infrastructure or comparative performance dashboards

Traps & gotchas

Node version must be >=22.0.0 โ€” use the .nvmrc file via 'nvm use' before installing or tests may behave unexpectedly. The Hill cipher implementation at src/algorithms/cryptography/hill-cipher/ uses a non-standard test directory name (single underscores) instead of test (double underscores) used elsewhere โ€” Jest config must account for this glob pattern. There are no runtime dependencies, so npm install only installs dev tooling.

Architecture

Concepts to learn

  • Polynomial Rolling Hash โ€” Used in src/algorithms/cryptography/polynomial-hash/ โ€” the basis of Rabin-Karp string search and many checksum schemes; understanding it unlocks multiple algorithms in this repo.
  • Hill Cipher (linear algebra cryptography) โ€” Implemented in src/algorithms/cryptography/hill-cipher/hillCipher.js โ€” a polygraphic substitution cipher using matrix multiplication over modular arithmetic, demonstrating how linear algebra applies to cryptography.
  • Caesar Cipher (ROT-N substitution) โ€” The simplest cipher in src/algorithms/cryptography/caesar-cipher/ โ€” foundational for understanding substitution ciphers and modular arithmetic in encoding.
  • Big-O Notation โ€” Every algorithm in this repo is analyzed by time/space complexity โ€” understanding Big-O is prerequisite to evaluating which algorithm to use, as shown in assets/big-o-graph.png.
  • AVL Tree (self-balancing BST) โ€” One of the advanced tree structures in src/data-structures/tree/avl-tree โ€” understanding rotations and balance factors is non-obvious and critical to grasping why BST worst-case O(n) is avoided.
  • Trie (prefix tree) โ€” Implemented under src/data-structures/trie โ€” a specialized tree for string prefix lookups that appears in autocomplete and IP routing; its structure is not intuitive from general tree knowledge.

Related repos

PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Fix inconsistent test directory naming: rename src/algorithms/cryptography/hill-cipher/_test_/ to __test__

Every other algorithm in the repo uses __test__ as the test folder convention (e.g. caesar-cipher, rail-fence-cipher, polynomial-hash, bellman-ford, articulation-points), but the hill-cipher directory uses _test_ (single underscores). This breaks naming consistency, may cause Jest to miss the tests depending on testMatch glob config, and makes the repo harder to navigate for contributors who expect uniformity.

  • [ ] Rename src/algorithms/cryptography/hill-cipher/_test_/ to src/algorithms/cryptography/hill-cipher/__test__/
  • [ ] Verify src/algorithms/cryptography/hill-cipher/__test__/hillCipher.test.js is picked up correctly by running npm test -- --testPathPattern=hillCipher
  • [ ] Check jest.config.js testMatch or testRegex to confirm the pattern covers __test__ folders and document it if not already stated
  • [ ] Open a PR with the rename and a one-line note in CONTRIBUTING.md under a 'Test File Conventions' section specifying that __test__ (double underscore) is the required directory name

Add missing README.md files for PolynomialHash.js and SimplePolynomialHash.js internals in src/algorithms/cryptography/polynomial-hash/

The polynomial-hash directory contains two separate implementation files โ€” PolynomialHash.js and SimplePolynomialHash.js โ€” each with its own test file (PolynomialHash.test.js and SimplePolynomialHash.test.js), but only a single shared README.md exists. Unlike every other algorithm in the repo where the README explains the specific implementation, there is no explanation of what differentiates SimplePolynomialHash from PolynomialHash (e.g. BigInt usage, modular arithmetic, rolling hash support). New contributors reading the code have no guided entry point.

  • [ ] Read src/algorithms/cryptography/polynomial-hash/SimplePolynomialHash.js and PolynomialHash.js to understand their differences (e.g. use of BigInt, modular inverse, Rabin-Karp suitability)
  • [ ] Update src/algorithms/cryptography/polynomial-hash/README.md to include a dedicated section for each class explaining its algorithm, complexity (time/space), and when to use one over the other
  • [ ] Add a code usage example for both classes in the README, mirroring the style used in e.g. src/algorithms/cryptography/caesar-cipher/README.md
  • [ ] Add links to further reading on polynomial rolling hashes and Rabin-Karp to match the repo's documentation standard

Add edge-case unit tests for src/algorithms/cryptography/rail-fence-cipher/railFenceCipher.js

Inspecting the existing test file src/algorithms/cryptography/rail-fence-cipher/__test__/railFenceCipher.test.js relative to known rail-fence cipher edge cases, there are likely no tests for: (1) a single rail (should return the original string), (2) number of rails equal to or greater than string length (degenerates to identity), (3) empty string input, and (4) a string with non-ASCII/Unicode characters. These are the exact boundary conditions that reveal off-by-one errors in the zigzag index calculation inside railFenceCipher.js, making this a high-value correctness contribution.

  • [ ] Open src/algorithms/cryptography/rail-fence-cipher/__test__/railFenceCipher.test.js and audit which edge cases are already covered
  • [ ] Add a test case

Good first issues

  1. Add missing README.md files for algorithms that lack them โ€” check src/algorithms/cryptography/polynomial-hash/ which has implementation files but verify the README covers all exported classes (SimplePolynomialHash vs PolynomialHash distinctions). 2. Normalize the Hill cipher test directory from src/algorithms/cryptography/hill-cipher/test/ (single underscores) to test/ to match the convention used everywhere else. 3. Add JSDoc type annotations to the public methods of src/algorithms/cryptography/polynomial-hash/PolynomialHash.js and SimplePolynomialHash.js, which currently lack parameter and return type documentation.

Top contributors

Recent commits

  • 115e428 โ€” Upgrade package dependencies (trekhleb)
  • 0248845 โ€” Upgrade node version to 22 (trekhleb)
  • 1503325 โ€” Make sure a vertex can't be added twice to a graph (Pierstoval)
  • e743df6 โ€” Make sure toString is called on edge key when calling edge.toString() (Pierstoval)
  • 0d956c2 โ€” Make sure graph vertex value is converted to string (Pierstoval)
  • 53f8c0d โ€” Allow graph edges with custom keys (Pierstoval)
  • 4ba97b9 โ€” Delete .github/FUNDING.yml (trekhleb)
  • 2834a06 โ€” Add Dijkstra algorithm illustrations and explanations (trekhleb)
  • f41e6ab โ€” Add Dijkstra algorithm illustrations and explanations (trekhleb)
  • 0627034 โ€” Add Dijkstra algorithm illustrations and explanations (trekhleb)

Security observations

Failed to generate security analysis.

LLM-derived; treat as a starting point, not a security audit.

Where to read next


Generated by RepoPilot. Verdict based on maintenance signals โ€” see the live page for receipts. Re-run on a new commit to refresh.

WAIT ยท trekhleb/javascript-algorithms โ€” RepoPilot Verdict