LLM-friendly CLI for NS train departures and journey planning
npm install trein


A CLI for the NS (Dutch Railways) API. Get real-time train departures, plan journeys, and check disruptions from your terminal.
``bash`
npm install -g trein
Download the latest binary for your platform from the releases page.
`bash`
git clone https://github.com/Joehoel/trein.git
cd trein
bun install
bun run build:bin
This creates a trein binary in the project root.
Trein requires an NS API key. Get your free key at: https://apiportal.ns.nl/
`bash`
export NS_API_KEY="your-api-key"
Create ~/.config/trein/config.json:
`json`
{
"apiKey": "your-api-key"
}
Or create trein.config.ts in your project:
`typescript`
export default {
apiKey: "your-api-key",
defaultStation: "ASD",
watch: {
interval: 30,
},
};
Get departures from a station.
`bash`
trein departures
trein d
Options:
| Flag | Alias | Description |
|------|-------|-------------|
| --json | | Output as JSON |--watch
| | -w | Auto-refresh mode |--type
| | -t | Filter by train type (IC, SPR, INT) |--limit
| | -n | Number of departures (default: 10) |
Examples:
`bashGet departures from Amsterdam Centraal
trein departures "Amsterdam Centraal"
trein d ASD
JSON Output:
`bash
trein d ASD --json
``json
{
"departures": [
{
"direction": "Rotterdam Centraal",
"plannedTime": "14:23",
"actualTime": "14:25",
"delay": "+2",
"platform": "5a",
"trainType": "IC",
"operator": "NS",
"cancelled": false
}
]
}
`---
$3
Search for stations by name or code.
`bash
trein stations
trein s # shorthand
`Options:
| Flag | Description |
|------|-------------|
|
--json | Output as JSON |Examples:
`bash
Search for stations
trein stations amsterdam
trein s schipholJSON output
trein s utrecht --json
`JSON Output:
`bash
trein s amsterdam --json
``json
{
"stations": [
{
"name": "Amsterdam Centraal",
"code": "ASD"
},
{
"name": "Amsterdam Amstel",
"code": "ASA"
}
]
}
`---
$3
Plan a journey from A to B.
`bash
trein trip
trein t # shorthand
`Options:
| Flag | Description |
|------|-------------|
|
--json | Output as JSON |
| --via | Travel via a specific station |Examples:
`bash
Plan a trip
trein trip Amsterdam Rotterdam
trein t ASD RTDTrip via Utrecht
trein t Amsterdam Rotterdam --via UtrechtJSON output
trein t ASD RTD --json
`JSON Output:
`bash
trein t ASD RTD --json
``json
{
"trips": [
{
"departure": "14:30",
"arrival": "15:12",
"duration": "42 min",
"transfers": 0,
"status": "ON_TIME",
"legs": [
{
"from": "Amsterdam Centraal",
"to": "Rotterdam Centraal",
"departure": "14:30",
"arrival": "15:12",
"trainType": "IC",
"platform": "4b"
}
]
}
]
}
`---
$3
Show current disruptions and maintenance.
`bash
trein disruptions
`Options:
| Flag | Alias | Description |
|------|-------|-------------|
|
--json | | Output as JSON |
| --active | -a | Show only active disruptions |
| --type | -t | Filter: DISRUPTION, MAINTENANCE, CALAMITY |Examples:
`bash
Show all disruptions
trein disruptionsActive disruptions only
trein disruptions -aFilter by type
trein disruptions -t MAINTENANCEJSON output
trein disruptions --json
`JSON Output:
`bash
trein disruptions --json
``json
{
"disruptions": [
{
"title": "Defect aan de trein",
"type": "DISRUPTION",
"isActive": true,
"start": "2026-01-25T10:00:00",
"end": "2026-01-25T14:00:00",
"trajectories": ["Amsterdam - Utrecht"]
}
]
}
`---
$3
Manage station aliases for quick access.
`bash
trein alias # list aliases
trein alias list # list aliases
trein alias set
trein alias rm
`Options:
| Flag | Description |
|------|-------------|
|
--json | Output as JSON |Examples:
`bash
Set aliases
trein alias set home "Amsterdam Centraal"
trein alias set work UtrechtUse aliases in commands
trein d home
trein t home workList all aliases
trein alias listRemove an alias
trein alias rm workJSON output
trein alias list --json
`JSON Output:
`bash
trein alias list --json
``json
{
"home": "ASD",
"work": "UT"
}
`---
LLM Usage
All commands support
--json for structured output. This makes Trein ideal for LLM tool use:`bash
Get data in JSON format
trein d Amsterdam --json
trein t Amsterdam Rotterdam --json
trein disruptions --json
trein s utrecht --json
`Error responses are also JSON:
`json
{
"error": "Station not found: \"xyz\""
}
`Station resolution:
- Full names:
"Amsterdam Centraal"
- Station codes: ASD, RTD, UT
- Partial matches: amsterdam, schiphol
- Aliases: home, work (user-defined)Troubleshooting
$3
`
Error: NS API key not found. Set NS_API_KEY environment variable or add apiKey to trein.config.ts
`Solution: Set your API key via environment variable or config file. Get a free key at https://apiportal.ns.nl/
$3
`json
{ "error": "Station not found: \"xyz\"" }
`Solution: Use
trein stations In interactive mode, you'll be prompted to select. In JSON mode, the best match is used automatically.
MIT - see LICENSE