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

jj-language-server

v0.2.0

Published

Java Language Server implemented in TypeScript/JavaScript (no JVM required)

Readme

jj-language-server

[!WARNING] Experimental project — Developed by Julien Dubois. This software is provided "as is", without warranty of any kind, express or implied. See the Apache-2.0 License for details.

A Java Language Server implemented in TypeScript/JavaScript — no JVM required.

Installable via npm, works with any editor that supports the Language Server Protocol.

Installing

npm install -g jj-language-server

Running

jj-language-server --stdio

See the LSP Configuration Guide for detailed setup instructions for VS Code, Neovim, Sublime Text, Emacs, Helix, and GitHub Copilot CLI (Windows/macOS/Linux).

CLI Options

Usage: jj-language-server [options]

Options:
  -V, --version                output the version number
  --stdio                      use stdio (required)
  --log-level <logLevel>       Log level: 4=log, 3=info, 2=warn, 1=error (default: 3)
  -h, --help                   display help for command

How It Works

Unlike the Eclipse JDT Language Server which requires a JVM, jj-language-server parses Java source code using java-parser (a Chevrotain-based parser written in pure JavaScript) and implements the LSP protocol using vscode-languageserver.

Performance Benchmarks

Benchmarked against Eclipse JDTLS 1.56 on Spring PetClinic (30 Java files), measured via JSON-RPC over stdio. JDTLS is configured with Maven import (Gradle disabled due to Java toolchain requirements). Both Node.js and Bun runtimes are tested for jj-language-server:

| Metric | jj (Node.js) | jj (Bun) | Eclipse JDTLS | |---|---|---|---| | Startup time | ~295 ms | ~2,200 ms | ~2,350 ms (8×) | | Memory after init (RSS) | 220 MB | 202 MB | 2,427 MB | | Memory final (RSS) | 345 MB | 254 MB | 2,516 MB | | Bulk open (30 files) | ~1,500 ms | ~1,500 ms | ~5,000 ms |

Operation Latency (avg of 3 runs, largest file)

| Operation | jj (Node.js) | jj (Bun) | Eclipse JDTLS | |---|---|---|---| | hover | 3.2 ms | 2.2 ms | 1.9 ms | | completion | 1.2 ms | 3.9 ms | 36.1 ms | | documentSymbol | 0.6 ms | 1.3 ms | 1.1 ms | | definition | 1.5 ms (∅) | 2.1 ms (∅) | 1.5 ms (∅) | | references | 11 ms | 5.2 ms | 42.1 ms | | formatting | 7.5 ms | 24.3 ms | 7 ms | | codeAction | 1.3 ms | 1.3 ms | 31.6 ms (∅) | | foldingRange | 1.2 ms | 2.0 ms | 1.1 ms | | semanticTokens | 2.9 ms | 3.3 ms | 1.5 ms |

(∅) = response was null or empty (not yet supported for cross-file definition)

Key takeaway: jj-language-server is 30× faster at completion and 8× faster at references than JDTLS, while using 7× less memory (~345 MB vs ~2.5 GB). Bun offers the lowest memory footprint (254 MB final). JDTLS excels at semantic tokens and folding ranges thanks to full type resolution. For cold-start scenarios (opening a project for the first time, CI environments, quick edits), jj-language-server is dramatically faster.

Run benchmarks locally:

# Download JDTLS, then:
npm run benchmark        # all three (Node.js + Bun + JDTLS)
npm run benchmark:jj     # jj-language-server only (Node.js)
node benchmarks/lsp-benchmark.mjs --bun-only   # jj (Bun) only
node benchmarks/lsp-benchmark.mjs --no-jdtls   # Node.js + Bun, skip JDTLS

Development

Build

npm install
npm run build

Test

npm test

There are 503 tests across 35 test files. Integration tests use the Spring PetClinic project as a realistic fixture. The pinned commit is tracked in test-fixtures/spring-petclinic-sha.txt.

CI / CD

| Workflow | Trigger | Description | |----------|---------|-------------| | CI (.github/workflows/ci.yml) | PR / push to main | Lint, build, test (Node 22 & 24) with Spring PetClinic integration | | Update Spring PetClinic (.github/workflows/update-spring-petclinic.yml) | Weekly (Monday) / manual | Checks for new PetClinic commits, runs tests, opens a PR | | Dependabot (.github/dependabot.yml) | Weekly (Monday) | Updates npm dependencies and GitHub Action versions |

Features

✅ Fully Implemented

All features are wired into the LSP server and fully functional:

  • Document symbols — hierarchical: classes, methods, fields, constructors, enums, records, interfaces, annotations
  • Workspace symbols — search across all indexed Java files
  • Code folding — blocks, methods, imports, comments, annotations
  • Code formatting — via Prettier Java, with on-type formatting (auto-indent, auto-close braces)
  • Selection range — smart expand/shrink via CST hierarchy
  • Code lens — reference counts above declarations
  • Source generation — generate constructors, getters/setters, toString, equals/hashCode (real TextEdit insertions)
  • Diagnostics — parse errors, duplicate declarations, unused imports, missing return statements, unreachable code, unresolved type references, deprecated API warnings (@Deprecated), unresolved method detection, access control violations, missing @Override hints
  • Maven/Gradle parsing — extracts project metadata, dependencies, source directories, Java version
  • Javadoc — parses /** */ comments, renders in hover & completion
  • Type hierarchy — real supertypes/subtypes using symbol table
  • File watcherworkspace/didChangeWatchedFiles to re-index on external changes
  • Workspace configuration — settings for formatter, Java version, classpath hints
  • Import resolution — resolves import statements, maps unqualified names throughout the file
  • Type inference — local variable types, expression types (method calls, field access, literals, operators), type resolver for symbols, members, method return types, field types
  • JDK API model — 238 built-in JDK types covering core packages (java.lang, java.util, java.io, java.nio, java.net, java.time, java.sql, java.math, java.text, java.util.concurrent, java.util.stream, java.util.function, java.util.regex, java.security)
  • Hover — symbol signatures + JDK type info + Javadoc from source comments + dependency JAR type info via source JARs
  • Code completion — scope-aware symbols, JDK types with auto-import, keywords, snippets, overload-aware (each overload shown separately with argument-count ranking)
  • Signature help — parameter hints for methods in scope, shows all overloads with best-match selection based on argument count
  • Go-to-definition — local + cross-file via workspace index, import-resolved, source JAR navigation for dependency types
  • Go-to-implementation — finds subclasses/implementors across workspace
  • Go-to-type-definition — navigates to type declaration of a variable
  • Find references / Document highlight — finds matching identifiers, cross-file search
  • Rename — cross-file rename via workspace index
  • Semantic tokens — classifies identifiers via symbol table (20 token types, 10 modifiers), generic type parameter classification
  • Code actions — organize imports, extract variable, extract method, extract constant, inline variable, surround with try-catch, add import for JDK types, move class to package, change method signature
  • Inlay hints — parameter name hints on method calls, var type inference hints (shows inferred type for var declarations)
  • Call hierarchy — incoming/outgoing calls, cross-file via workspace index
  • Classpath resolution — automatically runs mvn dependency:build-classpath or Gradle to resolve all transitive dependencies (including downloads); falls back to scanning ~/.m2/repository and ~/.gradle/caches if Maven/Gradle CLI is unavailable; detects JDK path and version
  • Java class file reader — parses .class files from JARs to extract type metadata (classes, methods, fields, access flags) without a JVM
  • JAR type index — builds a searchable type index from resolved dependency JARs (ZIP parsing, class extraction, type search)
  • Annotation processing — Lombok support (@Data, @Getter, @Setter, @Builder, @Value, @Slf4j, @NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor) and Spring annotations (@Component, @Service, @RestController, @GetMapping, etc.); integrated into symbol table
  • Document cache — version-aware caching with debounced reparsing for performance
  • Multi-root workspace — supports multiple workspace folders, each with its own index; handles workspace/didChangeWorkspaceFolders
  • Linked editing ranges — synchronized editing of all occurrences of an identifier
  • Generics support — type parameters extracted from classes, interfaces, methods; classified in semantic tokens; bounded type parameter tracking
  • Source JAR navigation — go-to-definition into dependency source JARs with virtual URI scheme, Javadoc from source JARs in hover

Roadmap

| Phase | Focus | Status | |-------|-------|--------| | 1. Semantic Diagnostics | Parse-level semantic checks | ✅ Done | | 2. Source Generation | Constructor, getters/setters, toString, equals/hashCode | ✅ Done | | 3. Enhanced Features | Real code action edits, semantic tokens, cross-file rename | ✅ Done | | 4. Navigation | Go-to-implementation, type definition, improved cross-file def | ✅ Done | | 5. Quick Wins | Javadoc extraction, type hierarchy wiring, file watcher, workspace config | ✅ Done | | 6. Type Resolution | Import resolution, local type inference, expression types, type resolver | ✅ Done | | 7. Advanced Diagnostics | Deprecated warnings, unresolved methods, access control, missing @Override | ✅ Done | | 8. Advanced Refactoring | Extract method, extract constant, inline variable | ✅ Done | | 9. Classpath Resolution | Classpath resolver, class file reader, JDK model, annotation processing | ✅ Done | | 10. Performance & Polish | Document cache, multi-root workspace, linked editing, document links | ✅ Done | | 11. Quick Wins | var inlay hints, cross-file call hierarchy | ✅ Done | | 12. Generics Foundation | Type parameters in symbol table, semantic token classification | ✅ Done | | 13. Overload Resolution | Overload-aware completion, best-match signature help | ✅ Done | | 14. Advanced Refactoring | Move class to package, change method signature | ✅ Done | | 15. Source JAR Navigation | Source JAR extraction/caching, go-to-definition into JARs | ✅ Done |

License

Apache-2.0