Skip to content

sam-peach/static-ruby

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Static Ruby

A lightweight type checker for Ruby that adds optional type safety using YARD annotations. Designed to run alongside your existing Ruby LSP (like Shopify's Ruby LSP or Solargraph), not replace it.

What This Does

Static Ruby analyzes your YARD type annotations and reports:

  • Nil safety issues - Calling methods on values that might be nil
  • Type mismatches - Passing wrong types to annotated methods
  • Argument errors - Wrong number of arguments to methods

It's a simple, focused tool for teams that want some type checking without adopting Sorbet or RBS.

Installation

git clone https://github.com/sampeach/static-ruby
cd static-ruby
go build -o rubyls ./cmd/rubyls

Quick Start

Add YARD annotations to your Ruby code:

# @param name [String]
# @param age [Integer]
# @return [User]
def create_user(name, age)
  User.new(name, age)
end

# @param user [User, nil]
# @return [String]
def greet(user)
  user.name  # Warning: called on potentially nil receiver
end

create_user(123, "wrong")  # Error: type mismatch

Run the analyzer:

./test-analyze your_file.rb

YARD Annotations

Methods

# @param name [String]
# @param count [Integer]
# @return [Array<String>]
def repeat(name, count)
  [name] * count
end

Nilable Types

# @param user [User, nil]
def maybe_greet(user)
  user&.greet  # Safe navigation - no warning
  user.greet   # Warning: potentially nil
end

Variables

# @type [Hash{String => Integer}]
@cache = {}

Supported Types

  • Basic: String, Integer, Float, Symbol, Boolean
  • Nilable: String, nil or String | nil
  • Collections: Array<T>, Hash{K => V}, Set<T>
  • Your classes: User, MyModule::MyClass

Running with Your Editor

Static Ruby runs as a separate LSP server focused only on type diagnostics. Configure your editor to run both your main Ruby LSP and this one.

VS Code

Use a multi-LSP setup or run it as a standalone checker.

Neovim

-- Add alongside your existing Ruby LSP
local configs = require('lspconfig.configs')
configs.static_ruby = {
  default_config = {
    cmd = { '/path/to/rubyls' },
    filetypes = { 'ruby' },
    root_dir = require('lspconfig.util').root_pattern('Gemfile', '.git'),
  },
}
require('lspconfig').static_ruby.setup{}

CLI Usage

For CI or one-off checks:

# Build the test tool
go build -o test-analyze ./cmd/test-analyze

# Analyze a file
./test-analyze app/models/user.rb

Example output:

Parsed app/models/user.rb successfully
  Parse errors: 0
  Comments: 12

Diagnostics: 2
  [warning] Line 24: method 'name' called on potentially nil receiver (type: User | nil)
  [error] Line 43: argument 1 has type 'String' but parameter 'id' expects 'Integer'

Limitations

  • Only checks code with YARD annotations (unannotated code is ignored)
  • No cross-file type inference
  • No metaprogramming support
  • No RBS/Sorbet compatibility

This is intentionally simple. For full type systems, use Sorbet or Steep with RBS.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published