NJTransit

Gem Version

A Ruby gem for NJ Transit's real-time and schedule data — buses, trains, and light rail. Built to be easy to drop into AI agents, chatbots, and creative projects that need live transit data.

What You Can Do

  • Real-time departures — "When is the next bus/train?" with live arrival times and delay status
  • Train tracking — GPS positions, speed, and delay info for every active train
  • Schedule lookups — Full timetables via GTFS static data, not just the next hour
  • Stop discovery — Find nearby stops by coordinates
  • Route planning — Find which routes connect two stops
  • Light rail — Hudson-Bergen, Newark, and RiverLINE via the same API
  • GTFS-RT feeds — Raw protobuf feeds for alerts, trip updates, and vehicle positions

Quick Start

1. Get API Credentials

Register at developer.njtransit.com to get a username and password.

2. Install

gem 'njtransit'

3. Configure

require 'njtransit'

NJTransit.configure do |config|
  config.username = ENV['NJTRANSIT_USERNAME']
  config.password = ENV['NJTRANSIT_PASSWORD']
end

4. Start Querying

# Two clients: one for buses/light rail, one for trains
client = NJTransit.client
rail_client = NJTransit.rail_client

# When is the next bus from Port Authority?
client.bus.departures(stop: "PABT", enrich: false)

# Next trains from NY Penn Station
rail_client.rail.train_schedule_19(station: "NY")

# Where is train #3837 right now?
rail_client.rail.train_stop_list(train_id: "3837")

# What stops are within 2000 feet of me?
client.bus.stops_nearby(lat: 40.878, lon: -74.221, radius: 2000, enrich: false)
# radius is in feet

# Light rail routes
client.bus.routes(mode: "HBLR")  # Hudson-Bergen Light Rail

Two Clients, One Gem

NJ Transit splits its API across two hosts. The gem handles this with two clients:

Client Host What it covers
NJTransit.client pcsdata.njtransit.com Buses, light rail, bus GTFS-RT
NJTransit.rail_client raildata.njtransit.com Trains, rail GTFS-RT

Both authenticate automatically. The bus client also supports light rail by passing a mode parameter (HBLR, NLR, RL, or ALL).

Capabilities Overview

Bus & Light Rail (client.bus)

Real-time departures, routes, stops, directions, nearby stops/vehicles, and trip tracking. Most methods accept an enrich flag — set enrich: false if you haven't imported GTFS static data.

Rail (rail_client.rail)

Train schedules (real-time and full-day), station alerts and delay messages, train stop lists, and live vehicle positions for every active train.

GTFS Static Data

Full offline schedules imported into a local SQLite database. Useful for answering "what's the schedule tomorrow?" when the real-time API only shows the next hour.

# Import once
NJTransit::GTFS.import("/path/to/gtfs/data")

# Then query
gtfs = NJTransit::GTFS.new
gtfs.schedule(route: "191", stop: "27005", date: Date.new(2026, 3, 28))
gtfs.routes_between(from: "WBRK", to: "PABT")

Rake tasks are also available: rake njtransit:gtfs:import, rake njtransit:gtfs:status, rake njtransit:gtfs:clear.

GTFS-RT Feeds

Raw protobuf feeds for real-time alerts, trip updates, and vehicle positions:

client.bus_gtfs.alerts            # Bus alerts
client.bus_gtfs.vehicle_positions # Bus vehicle positions
rail_client.rail_gtfs.trip_updates # Rail trip updates

A newer G2 version of the bus feeds is also available via client.bus_gtfs_g2.

Using with Claude Code

Install the gem, then run the skill installer:

gem install njtransit
njtransit install-skill

This adds a /njtransit slash command to Claude Code (CLI, desktop app, and IDE extensions). Then ask transit questions from any session:

/njtransit when is the next train from NY Penn to Trenton?
/njtransit what buses stop near 40.878, -74.221?
/njtransit is the Northeast Corridor delayed?

Claude writes and runs Ruby code against the gem to answer your question. To remove the skill:

njtransit uninstall-skill

Environment Variables

Variable Description Default
NJTRANSIT_USERNAME API username
NJTRANSIT_PASSWORD API password
NJTRANSIT_LOG_LEVEL silent, info, or debug silent
NJTRANSIT_BASE_URL Bus API base URL https://pcsdata.njtransit.com
NJTRANSIT_TIMEOUT Request timeout (seconds) 30
NJTRANSIT_GTFS_DATABASE_PATH SQLite database path ~/.local/share/njtransit/gtfs.sqlite3

Development

bin/setup          # Install dependencies
bundle exec rspec  # Run tests
bin/console        # Interactive prompt

CI & Release

CI runs automatically on pull requests (RuboCop + RSpec on Ruby 3.2/3.3). Merging to main with a version bump triggers the release workflow, which publishes to RubyGems via Trusted Publishing and creates a GitHub release.

bin/ci-watch <pr-number>         # Check CI status for a PR
bin/ci-watch <pr-number> --poll  # Poll until CI completes
bin/release-watch                # Check release workflow status
bin/release-watch --poll         # Poll until gem is published

Contributing

Bug reports and pull requests are welcome at github.com/jayrav13/njtransit.

License

MIT — see LICENSE.