Skip to content
Ruby logo

Ruby

First appeared 1995 · Yukihiro Matsumoto

Optimised for programmer happiness — and, with Rails, for shipping a product faster than anyone expects.

Overview

Ruby is a dynamic, open-source, object-oriented programming language with a strong focus on simplicity, productivity, and developer happiness. Created by Yukihiro 'Matz' Matsumoto in Japan in the mid-1990s, Ruby was designed with the explicit philosophy that programming should be enjoyable and that the language should prioritize human needs over computer needs. Ruby emphasizes elegant, natural, and human-friendly syntax that reads almost like English, making code easy to write, read, and understand. It's a pure object-oriented language where absolutely everything is an object, including primitive types like numbers and booleans, providing remarkable consistency in how you interact with different data types. Ruby supports multiple programming paradigms including procedural, object-oriented, and functional programming, giving developers flexibility in how they approach problems. The language is best known for Ruby on Rails, the revolutionary web application framework that transformed web development in the mid-2000s with its convention-over-configuration philosophy, emphasis on developer productivity, and elegant approach to building database-backed web applications. Ruby features automatic memory management through garbage collection, dynamic typing that allows for flexible and expressive code, powerful metaprogramming capabilities that enable developers to write code that writes code, blocks and closures as first-class language features, mixins through modules for sharing behavior across classes without traditional inheritance, and an elegant syntax for everything from string interpolation to regular expressions. The language includes a comprehensive standard library covering file I/O, networking, data structures, and much more, plus a rich ecosystem of gems (Ruby's term for libraries and packages) distributed through RubyGems, the package manager that makes it trivial to share and use code. Ruby's syntax is remarkably clean and expressive, often allowing developers to accomplish in a few lines what might take many more in other languages, without sacrificing readability. The language emphasizes the principle of least surprise, meaning it should behave in a way that minimizes confusion for experienced users, though this is balanced with Matz's philosophy that the language should be optimized for programmer happiness. Ruby has powerful features like duck typing (if it walks like a duck and quacks like a duck, it's a duck), open classes that allow you to modify existing classes including built-in ones, symbols for efficient string-like identifiers, and a flexible syntax that often makes parentheses and other punctuation optional. The language has excellent support for text processing, making it popular for scripting and automation tasks, and its expressiveness makes it a favorite for domain-specific languages (DSLs). Ruby's community is known for being friendly, welcoming, and focused on best practices, with a strong emphasis on testing, clean code, and continuous improvement. The language has influenced many other languages and frameworks, and its philosophy of developer happiness has shaped how many programmers think about language design and software development.

Key facts

The reference details, without the paragraph.

First appeared
1995
Designed by
Yukihiro 'Matz' Matsumoto
Typing
Dynamic, strong and duck-typed, with optional type signatures via RBS and Sorbet
Execution
Compiled to bytecode for the YARV virtual machine, with the YJIT just-in-time compiler
Memory model
Automatic — generational, incremental, compacting garbage collection
Package manager
RubyGems with Bundler
File extensions
.rb, .rake, .gemspec
Current line
Ruby 3.x, with a release every December
Design principle
The principle of least surprise — the language should behave as you expect
Licence
Ruby License and BSD 2-clause

History

How the language got here — the decisions that still shape how you write it.

Ruby was created by Yukihiro Matsumoto, affectionately known as 'Matz' in the Ruby community, in Japan in the mid-1990s, with the first public release (version 0.95) on December 21, 1995. Matz began working on Ruby on February 24, 1993, motivated by his dissatisfaction with existing scripting languages and his desire to create a language that would make programming more enjoyable. He wanted to create a language that was more powerful and object-oriented than Perl, more elegant and consistent than Python, and more fun to use than any existing language. Matz drew inspiration from his favorite programming languages, combining features from Perl (text processing and regular expressions), Smalltalk (pure object-oriented design and message passing), Eiffel (design by contract concepts), Ada (exception handling), and Lisp (functional programming features and powerful metaprogramming). The name 'Ruby' was chosen as a gemstone name, following the tradition of Perl (which sounds like 'pearl'), and because it was the birthstone of one of Matz's colleagues. Ruby was also chosen because it comes after Perl in several contexts (ruby is more valuable than pearl, and Ruby comes after Perl alphabetically). For its first several years, Ruby remained relatively unknown outside of Japan, where it developed a dedicated following and was used for various applications. The language evolved through the late 1990s and early 2000s with incremental improvements, but remained largely a Japanese phenomenon with limited English documentation. The turning point for Ruby came in 2004-2005 with the emergence of Ruby on Rails, a web application framework created by David Heinemeier Hansson (DHH) while building Basecamp, a project management application. Rails was extracted from Basecamp and released as open-source software in July 2004, with version 1.0 arriving in December 2005. Ruby on Rails revolutionized web development with its convention-over-configuration approach, which eliminated much of the boilerplate code required in other frameworks, its emphasis on RESTful design, its integrated testing framework, its database migrations for managing schema changes, and its overall philosophy of developer happiness and productivity. Rails demonstrated that you could build sophisticated web applications rapidly without sacrificing code quality or maintainability. The framework's success was phenomenal, sparking what became known as the 'Rails revolution' and bringing Ruby into the international spotlight. Suddenly, developers around the world were learning Ruby specifically to use Rails, and the language's popularity exploded. This period saw the emergence of numerous Ruby conferences, user groups, books, tutorials, and a vibrant global community. The success of Rails also validated Ruby's design philosophy, showing that a language optimized for developer happiness could lead to remarkable productivity gains. Ruby's growth led to increased attention to performance and scalability. Ruby 1.8, which was the version when Rails emerged, was relatively slow compared to other languages. The community responded with several initiatives: JRuby (Ruby implemented on the Java Virtual Machine), Rubinius (Ruby implemented in Ruby itself with a custom VM), and most significantly, the development of Ruby 1.9, which included YARV (Yet Another Ruby VM), a new bytecode interpreter that significantly improved performance. Ruby 1.9, released in 2007 with a stable version in 2009, brought major improvements including better performance, improved Unicode support, new syntax features, and a more robust standard library. Ruby 2.0, released in 2013 on the language's 20th anniversary, continued this evolution with keyword arguments, refinements for safer monkey-patching, and other improvements. Subsequent versions (2.1, 2.2, 2.3, etc.) brought incremental performance improvements and new features. Ruby 3.0, released on Christmas Day 2020 (25 years after Ruby's initial release), was a major milestone with the goal of being 3x faster than Ruby 2.0, introducing a JIT compiler, improved concurrency with Ractor (Ruby's actor-model implementation), type signatures through RBS, and many other enhancements. Throughout its history, Ruby has powered numerous significant applications and companies. GitHub, the world's largest code hosting platform, was built with Ruby on Rails and remains largely Rails-based. Shopify, one of the largest e-commerce platforms, is built on Rails and has become one of the biggest contributors to Ruby and Rails development. Basecamp, the project management tool that spawned Rails, continues to be built with Rails. Airbnb, Twitch, Hulu, and countless other companies have used Ruby and Rails for their web applications. The Ruby community has been instrumental in advancing software development practices, particularly around testing (with tools like RSpec and Cucumber), continuous integration, and agile methodologies. The community has also been a leader in promoting diversity and inclusion in tech, with initiatives like RailsBridge providing free workshops to underrepresented groups. Matz has remained actively involved in Ruby's development, guided by his philosophy that 'Ruby is designed to make programmers happy' and the principle of least surprise. The language continues to evolve with annual releases, balancing innovation with stability and backward compatibility. While Ruby faced competition from newer languages like Node.js and Go, and some companies have moved away from Rails for various reasons, Ruby remains a vital and beloved language with a strong community, mature ecosystem, and continued relevance in web development, DevOps tooling, and automation. The language's influence extends far beyond its direct usage, having inspired features in other languages and shaped how many developers think about API design, developer experience, and the joy of programming.

  1. 1993–1995

    Matz wants a language he enjoys

    Yukihiro Matsumoto sets out to build a scripting language more object-oriented than Perl and more practical than Smalltalk. His stated priority is the programmer's happiness rather than the machine's efficiency — an unusual goal that shows everywhere in the design.

  2. 2000

    Ruby reaches the English-speaking world

    *Programming Ruby* — the Pickaxe book — is published, and the language finally has documentation outside Japanese.

  3. 2004

    Rails changes web development

    David Heinemeier Hansson extracts Ruby on Rails from Basecamp. Convention over configuration, scaffolding, migrations and MVC-by-default make it dramatically faster to build a database-backed application, and the ideas spread to every other ecosystem.

  4. 2007–2012

    The startup years

    Twitter, GitHub, Shopify, Airbnb and Groupon are built on Rails. 'Ruby developer' becomes one of the most sought-after roles in the industry.

  5. 2013

    Bundler and the gem ecosystem mature

    Deterministic dependency resolution with `Gemfile.lock` solves the reproducibility problem, and RubyGems becomes one of the best-organised package ecosystems anywhere.

  6. 2020

    Ruby 3.0 — the 3x3 goal

    A target of three times the performance of Ruby 2.0, plus Ractors for parallelism, fibers for lightweight concurrency, and RBS for optional type signatures.

  7. 2022–2025

    YJIT and steady gains

    Shopify's YJIT, written in Rust, delivers substantial real-world speed-ups on Rails workloads. Rails 7 and 8 lean into Hotwire, importmaps and 'no build step' front ends.

What it is good at

The reasons teams pick it, stated concretely.

  • Genuinely pleasant to write

    Blocks, expressive method names ending in `?` and `!`, and syntax that reads close to English. Ruby code is often the closest thing in software to a description of what it does — this is not a small thing on a codebase you live with for years.

  • Rails is still the fastest way to build a web application

    Two decades of accumulated conventions mean the routing, ORM, migrations, background jobs, mailers, caching and testing are all decided for you and all work together. A small team can ship what would take much longer elsewhere.

  • Everything is an object, consistently

    Integers, `nil` and classes themselves all respond to methods. There are no primitives with special rules, which makes the mental model unusually uniform.

  • Metaprogramming that libraries use well

    `method_missing`, `define_method` and open classes let libraries create APIs that feel built into the language. ActiveRecord's dynamic finders and RSpec's readable syntax both come from here.

  • A culture of testing

    The Ruby community adopted automated testing earlier and more thoroughly than most. RSpec, Minitest, factories and fixtures are standard practice rather than a discipline you have to argue for.

Trade-offs

Every language costs you something. Knowing what, before you commit, is the whole point.

  • Slower than compiled and JIT-heavy alternatives

    Even with YJIT, CPU-bound Ruby is well behind Go, Java or Rust. For typical web applications, database time dominates and it rarely matters — but it does set a ceiling.

  • Memory-hungry per process

    The traditional multi-process deployment model means each worker carries a full copy of the application. Hosting a Rails app costs more RAM than the Go or PHP equivalent.

  • The GVL limits real parallelism

    Like CPython, MRI holds a global lock so threads cannot run Ruby code simultaneously. Ractors are the answer and are still marked experimental; in practice teams scale with processes.

  • Metaprogramming cuts both ways

    Methods that do not exist in the source, monkey patches applied at load time, and behaviour assembled at runtime make some Ruby codebases genuinely hard to navigate. `grep` does not always find the definition.

  • Rails is a strong opinion

    Follow the conventions and it is remarkable. Need something structured differently and you are working against a large, opinionated framework. 'Magic' is a fair description, and its cost lands on new team members.

Code examples

Not syntax tours — the idioms that make code read like the language rather than a translation of another one.

Blocks and enumerables
orders = [
  { region: 'EU', total: 120, status: :paid },
  { region: 'US', total: 340, status: :pending },
  { region: 'EU', total: 80,  status: :paid },
]

revenue = orders
  .select { |order| order[:status] == :paid }
  .sum    { |order| order[:total] }

by_region = orders.group_by { |order| order[:region] }
                  .transform_values { |list| list.sum { |o| o[:total] } }

puts revenue    # 200
puts by_region  # {"EU"=>200, "US"=>340}
Blocks are Ruby's defining feature: a chunk of behaviour passed to a method. `Enumerable` gives every collection more than fifty of these methods, and chaining them reads almost as prose. `transform_values` is the kind of small, exactly-right method that Ruby's standard library is full of.
Classes, attributes and duck typing
class Invoice
  attr_reader :id, :amount

  def initialize(id:, amount:)
    raise ArgumentError, 'amount must be positive' unless amount.positive?
    @id     = id
    @amount = amount
  end

  def large?                        # `?` by convention means it returns a boolean
    amount > 1_000
  end

  def to_s = "#{id}: #{format('%.2f', amount)}"
end

invoice = Invoice.new(id: 'INV-1', amount: 1_500)
puts invoice          # INV-1: 1500.00
puts invoice.large?   # true
Keyword arguments make the call site self-documenting, and `attr_reader` generates the getters. Ruby does not care what class an object is, only which methods it responds to — anything with a `to_s` can be printed, which is duck typing in practice.
A Rails model, in a few lines
class Book < ApplicationRecord
  belongs_to :author
  has_many   :reviews, dependent: :destroy

  validates :title, presence: true, length: { maximum: 200 }
  validates :isbn,  uniqueness: true, allow_nil: true

  scope :recent,    -> { where(published_at: 1.year.ago..) }
  scope :highly_rated, -> { joins(:reviews).group(:id).having('AVG(reviews.rating) > 4') }

  def average_rating = reviews.average(:rating)&.round(1)
end

# Composable, and lazily executed — one SQL query at the end.
Book.recent.highly_rated.includes(:author).limit(10)
ActiveRecord derives the columns from the database schema, so there is no field mapping to maintain. Scopes compose into a single query, and `includes` avoids the N+1 problem — the most common Rails performance mistake by a wide margin.
Modules for shared behaviour
module Auditable
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def audited_fields(*fields)
      @audited_fields = fields
    end

    def audited = @audited_fields || []
  end

  def audit_trail
    self.class.audited.map { |field| "#{field}=#{public_send(field)}" }.join(' ')
  end
end

class Order
  include Auditable
  audited_fields :id, :total

  attr_reader :id, :total
  def initialize(id, total) = (@id, @total = id, total)
end

puts Order.new('A-1', 99).audit_trail   # id=A-1 total=99
Modules are Ruby's answer to multiple inheritance — mixins that add both instance and class methods. This is the mechanism behind most of Rails' concerns, and a good illustration of metaprogramming used to build a small, declarative API.

Common pitfalls

The mistakes that cost everyone an afternoon at least once.

  • N+1 queries in Rails

    Looping over records and touching an association issues one query per row. Use `includes` or `preload`, and run the Bullet gem in development to catch them automatically.

  • Monkey patching core classes

    Reopening `String` or `Hash` to add a method affects every gem in the process and produces conflicts nobody can trace. Use a refinement, or just a module function.

  • Confusing `nil` and `false` with everything else

    In Ruby only `nil` and `false` are falsy — `0` and `""` are both truthy, unlike most other dynamic languages. This catches people arriving from JavaScript or Python.

  • Mutating a string or array you were handed

    Bang methods such as `gsub!` and `sort!` modify in place, so a caller elsewhere sees the change. Prefer the non-bang versions unless mutation is the point.

  • Fat models and fatter controllers

    Rails makes it easy to keep adding to a model until it is two thousand lines. Extract service objects, form objects and query objects before it gets there.

  • Symbols and strings as different hash keys

    `{ name: 'a' }["name"]` returns nil. Rails' `HashWithIndifferentAccess` hides this in some places and not others, which makes it more confusing, not less.

In production

Where it is running at scale, and what it is doing there.

  • GitHub

    Web application backend built with Ruby on Rails.

  • Shopify

    E-commerce platform and merchant tools.

  • Basecamp

    Project management and team collaboration tools.

  • Airbnb

    Backend services and web application development.

Learning path

A realistic order to learn things in, with something to build at each step.

  1. 1

    Week 1

    The language and its feel

    Objects and methods, strings and symbols, arrays and hashes, blocks, and control flow. Use `irb` constantly — Ruby rewards experimentation.

    Build this: Write a script that parses a log file and reports the most frequent errors.

  2. 2

    Weeks 2–3

    Objects, modules and Enumerable

    Classes, inheritance, modules and mixins, exceptions, and the `Enumerable` methods in depth. Learning `each_with_object`, `group_by`, `partition` and `reduce` well changes how you write everything else.

    Build this: Model a small domain with classes and mixins, and write Minitest or RSpec tests for it.

  3. 3

    Weeks 4–5

    Tooling and gems

    Bundler and `Gemfile.lock`, writing a gem, RuboCop, and debugging with `debug` or Pry. Understand how `require` and load paths work.

    Build this: Package your script as a gem with a command-line executable and tests.

  4. 4

    Months 2–4

    Rails

    MVC, routing, ActiveRecord and migrations, validations, ActionMailer, background jobs with Solid Queue or Sidekiq, and Hotwire for interactivity without a JavaScript framework.

    Build this: Build and deploy a complete application with authentication, background jobs and system tests.

  5. 5

    Ongoing

    Depth and performance

    Metaprogramming and when to avoid it, N+1 detection with Bullet, query and memory profiling, YJIT, and concurrency with fibers or Ractors.

    Build this: Profile a slow Rails endpoint and cut its response time in half, starting with the queries.

Ecosystem and tooling

The tools you will end up installing whichever project you join.

ToolWhat it does
Ruby on RailsThe full-stack web framework that made Ruby popular and still defines its ecosystem
Bundler + RubyGemsDependency resolution and packaging, with a lockfile for reproducible installs
RSpec / MinitestTesting — RSpec for expressive specs, Minitest for a fast, minimal default
Sidekiq / Solid QueueBackground job processing; Solid Queue ships with recent Rails and needs no Redis
RuboCopLinting and formatting against a widely adopted community style guide
Hotwire (Turbo + Stimulus)Server-rendered interactivity, the Rails answer to single-page applications
Sorbet / RBSOptional static typing for large codebases
rbenv / asdfRuby version management per project

Ruby libraries

10 catalogued, each with installation, worked examples and best practices.

Frequently asked

Is Ruby still relevant, or did it peak with Rails?

Its share of new startups is smaller than in 2010, but Shopify, GitHub, Stripe's early stack and a great many profitable businesses run on it at scale. Rails 7 and 8 have been genuinely well received, and YJIT delivered real performance gains. It is a mature, productive choice rather than a fashionable one.

Should I learn Ruby or go straight to Rails?

Spend two or three weeks on Ruby first. Rails leans heavily on blocks, modules and metaprogramming, and without those fundamentals the framework feels like unexplainable magic — which is exactly the complaint people who skipped this step tend to have.

Is Ruby too slow for production?

For typical web applications, no — response time is usually dominated by database queries and external calls, not by the interpreter. YJIT has improved things substantially. For CPU-bound work such as data processing or numerical computation, choose something else or push that part into a native extension.

Rails or a JavaScript framework for a new product?

Rails if a small team needs to ship a database-backed application quickly and the interface is mostly server-rendered — Hotwire covers a surprising amount of interactivity without a separate front end. A JavaScript stack if the product is genuinely application-like in the browser, or if you want one language across the whole system.

What is the deal with symbols?

A symbol such as `:name` is an immutable, interned identifier — the same symbol is the same object every time, so comparison is fast and no garbage accumulates. Use symbols for hash keys and identifiers, strings for text you will manipulate or display.

Do I need static typing in Ruby?

Most Ruby codebases run without it and rely on a strong test suite instead, which is a coherent position given the community's testing culture. For very large or long-lived codebases, Sorbet and RBS add real safety — Shopify and Stripe both invested heavily in this. For a small application, tests are usually the better use of your time.