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

codemirror-lang-ruby

v0.4.4

Published

Ruby language support for CodeMirror 6, built on a Lezer grammar

Readme

codemirror-lang-ruby

Ruby language support for CodeMirror 6, built on a Lezer grammar.

Targets Ruby 3.0+ syntax (including endless methods and basic pattern matching).

Live Demo

Install

npm install codemirror-lang-ruby

Usage

import {EditorView, basicSetup} from "codemirror"
import {ruby} from "codemirror-lang-ruby"

new EditorView({
  doc: 'puts "hello"',
  extensions: [basicSetup, ruby()],
  parent: document.getElementById("editor")!,
})

Real-world parse accuracy

Tested against popular open source Ruby projects (large, representative files):

| Project | File | Lines | Accuracy | |---------|------|-------|----------| | Faker | internet.rb | 579 | 98.4% | | Devise | devise.rb | 534 | 98.3% | | Jekyll | site.rb | 577 | 97.6% | | Fastlane | runner.rb | 379 | 96.3% | | Rails | query_methods.rb | 2291 | 96.0% | | Grape | api.rb | 166 | 95.8% | | Sidekiq | config.rb | 321 | 95.6% |

What's supported

  • Definitions: methods (with params, endless def f(x) = expr), classes (with inheritance), modules
  • Control flow: if/elsif/else, unless, while, until, for/in, case/when, case/in (pattern matching with pin operators, hash patterns, find patterns)
  • Error handling: begin/rescue/ensure/raise, rescue with scoped constants (rescue Foo::Bar => e)
  • Strings: single-quoted, double-quoted with #{interpolation}, heredocs (<<~DELIM), %-literals with any delimiter
  • Literals: integers, floats, symbols, character literals (?a), arrays, hashes, regex (/pattern/flags), nil, true, false
  • Expressions: assignment (including ||=, &&=), multiple assignment (a, b = 1, 2), method calls (with receiver and keyword args like User.where(active: true), splat *args/**kwargs/&block), chained calls, binary/unary/ternary operators, lambdas, ranges, conditional modifiers
  • Blocks: brace blocks and do/end blocks attached to method calls (items.each { |x| x })
  • Operators: proper precedence (** > *// > +/- > comparison > logic), safe navigation (&.), scope resolution (:: including leading ::TopLevel)
  • Bare method calls: puts "hello", require "json", attr_reader :name, include Comparable, validates_presence_of :name, rescue_from, helper_method (49 common Ruby/Rails methods)
  • Variables: local, @instance, @@class, $global, Constants
  • Comments: line # and block =begin/=end
  • Editor features: smart indentation, code folding, bracket closing, keyword autocompletion (31 keywords)

Known limitations

  • Heredoc body highlighting with trailing codefoo(<<~SQL) and <<~HEREDOC.strip parse correctly (no error nodes), but the heredoc body is not highlighted as a string in these cases. Simple heredocs (x = <<~SQL) highlight the full body as a string. This is a Lezer architectural limitation: inline tokenizers always run before external tokenizers, preventing the body tokenizer from claiming the content.
  • Guard clauses in pattern matchingin x if x > 0 is not supported. The if/unless keyword conflicts with IfStatement/ConditionalModifier in the LR parser and cannot be resolved without an external tokenizer.
  • Heredoc and %-literal bodies are opaque tokens (no interpolation highlighting inside).
  • Inline rescue as a standalone expressionvalue = foo rescue nil works (rescue in assignments), but foo rescue bar as a standalone expression outside of assignment context is not supported.
  • Newline as statement separator — Ruby uses newlines to separate statements, but the grammar is whitespace-insensitive. An expression followed by if on the next line may be parsed as a conditional modifier (e.g., x = 1\nif cond parses as x = (1 if cond)).
  • Setter assignment with conditional modifierself.x = 1 if condition is not fully supported.
  • Bare method calls only work for a curated list of 49 common Ruby/Rails methods. Other methods need parentheses (e.g., assert_includes(errors, "msg") instead of assert_includes errors, "msg").
  • Line-based indentation — The indent engine uses regex line scanning rather than tree-based analysis. Most patterns work well, but complex multi-line expressions (e.g., multi-line method args followed by a body, trailing commas inside nested delimiters) may not indent perfectly.

Development

npm install          # Install dependencies
npm run build        # Build grammar + bundle to dist/
npm test             # Run 105 grammar tests (721 total across all suites)
npm run lint         # TypeScript type check
npm run demo:build   # Build the demo page

Built with Claude Code

This entire project — grammar, external tokenizers, tests, editor integration, and demo — was written by Claude Code, guided by @jeanpaulsio.

License

MIT