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

@codincod/codemirror-lang-java

v0.1.1

Published

Java language support for the CodeMirror code editor

Readme

@codincod/codemirror-lang-java

This package implements Java language support for the CodeMirror code editor, using the Lezer grammar Marijn Haverbeke wrote for @lezer/java, with the parse fixes below on top of it. The editor half comes from @codemirror/lang-java; the two are merged here so that one package holds the grammar and the language support that has to move with it.

Written in part for CodinCod, a competitive coding platform, where it colours the editor people solve puzzles in.

This code is released under an MIT license.

Usage

import {EditorView, basicSetup} from "codemirror"
import {java} from "@codincod/codemirror-lang-java"

const view = new EditorView({
  parent: document.body,
  doc: `sealed interface Shape permits Circle, Square {}

record Circle(double radius) implements Shape {}
record Square(double side) implements Shape {}

class Area {
  static double of(Shape s) {
    return switch (s) {
      case Circle c -> Math.PI * c.radius() * c.radius();
      case Square q -> q.side() * q.side();
    };
  }
}
`,
  extensions: [basicSetup, java()]
})

What this fixes

Upstream is a Java 11 grammar with two bugs older than that. Measured over 46 397 files of Guava, Apache Commons Lang, JUnit 5, the Spring Framework and Elasticsearch, @lezer/java 1.1.3 parses 54.61% of them with no error node, leaving 242 760 error nodes. This package parses 99.82%, leaving 1 194.

Two of the fixes are bugs rather than missing syntax, and both predate every language feature below.

  • default and synchronized were not modifiers. The list of modifiers had a missing |, so kw<"default"> kw<"synchronized"> was one sequence rather than two alternatives. No method declared synchronized, and no interface method declared default, would parse.
  • Foo.class did not parse. A class literal was written as a type before .class, which only ever matched the shapes that cannot be anything else, a primitive (int.class) and an array (String[].class). In expression position a bare Day is an identifier by the time the dot arrives, so every ordinary class literal failed.

Three more are places upstream was narrower than the language.

  • Eight module keywords were reserved everywhere. requires, exports, opens, uses, provides, to, with and transitive are keywords only inside a module declaration, and names anywhere else. Reserving them cost int to, int with and six other ordinary declarations. to and from are what anyone writes for the ends of an edge or a range.
  • A text block could not close on a line holding a quote. The content rules required the match to continue after a quote, so {"a":"b"}""" never closed, and a JSON literal inside a text block is most of what the feature is used for.
  • Type annotations were rejected on new arrays and on varargs. JLS allows new @Nullable String[0] and Object @Nullable ... args; upstream took the annotation on a dimension but not on the element type or before the dots. This is most of what remained on a null-annotated codebase.
  • An annotation type could not nest an enum. Its body took classes and interfaces only, and an enum naming the modes an annotation takes is the common case.

The rest is syntax added to Java between 14 and 21, none of which upstream has:

  • Switch expressions, arrow labels, multi-value labels (case 1, 2, 3 ->), case null, default, arrow bodies that are a block, a throw or another switch, and yield.
  • Records, with type parameters, interfaces, compact constructors, annotated and varargs components, nested in a body or local to a method.
  • Sealed types: sealed, non-sealed and permits.
  • Patterns: type patterns in instanceof and in case, record patterns, and when guards.

Every word added is contextual, so record, sealed, permits, yield, when and non are all still ordinary names, which they have to be: they were legal identifiers for the first twenty-five years of the language.

The 69 parse tests that ship with @lezer/java pass unchanged. test/fixes.txt holds a case for each fix above, and every one of them fails on upstream.

Measuring it yourself

npm run corpus -- path/to/java/files

No corpus ships with the package, because none of that code is ours to redistribute. Point it at your own; it counts files with no error node and groups them by directory, so a package that drags the total down names itself.