Open-source project
OpenRailAssociation/osrd avatar
OpenRailAssociation/osrd

OSRD: open source railway design, capacity analysis and simulation

An open source web application for railway infrastructure design, capacity analysis, timetabling and simulation

668 stars91 forksTypeScriptLicense varies

At a glance

What is it?
OSRD is an open source web application for railway infrastructure design, capacity analysis, timetabling, simulation and short term path request, built as a multi-service stack around a PostGIS database with a TypeScript front end and a Rust core. The project is free and open-source forever, actively developed with interfaces that are not yet stable, and it runs a public demo that is refreshed daily.
Who is it for?
Adopt OSRD if you are a European infrastructure manager or a researcher who needs railway design, capacity analysis, timetabling and simulation in one open source tool rather than a commercial suite, and if you can work around the fact that the interfaces are still moving.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What OSRD covers, and where it sits in the OpenRail process

OSRD, which stands for Open Source Railway Designer, is an open source web application for railway infrastructure design, capacity analysis, timetabling and simulation and short term path request. The last of those, short term path request, is the feature the project abbreviates as STDCM elsewhere in the documentation, and it is the one an infrastructure manager would recognise as a standalone tool.

The project states plainly that it is free and open-source forever, and the homepage is osrd.fr. The project site hosts the documentation, the contribution guide and the deployment guide, so the repository README is the entry point rather than the manual itself.

The governance picture is visible in the badges and the tree. There is a Public Money Public Code badge, an LGPL licence badge pointing at a LICENSES/ directory in the repository root, a REUSE status badge driven by a REUSE.toml file, a GOVERNANCE.md, a MAINTAINERS.md and a CODE_OF_CONDUCT.md. The OpenRail Association project stage badge shows the project at incubation stage 2, which is the association's own process for a project moving toward maturity.

The primary language is TypeScript, the default branch is dev, and the last push was on 2026-10-20. The project is not archived, and the recent releases are v1.3.2 from 2026-10-16, v1.3.1 from 2026-10-09 and v1.3.0 from 2026-09-18, so there is a steady release rhythm on a 1.x line.

One caveat the README states without hedging: OSRD is still in active development, user and programming interfaces are not entirely stable and are still occasionally modified, and if you rely on OSRD, be prepared to deal with regular changes.

The stack: a web front end over PostGIS and a Rust core

The repository layout is the clearest description of the architecture, and it is a multi-service system rather than a single application.

There is a front/ directory for the web interface, an editoast/ directory for the API layer, a core/ directory for the domain core, a gateway/ directory, a chart/ directory, and osrd_schemas/ for the schema definitions, plus osrdyne/ and railway_manager_interface/ as the interfaces to external railway management systems. The python/ directory holds the Python parts, and there is a scripts/ directory with the loaders you will actually use, a tests/ directory, a docker/ directory and a docker-compose.yml at the root.

The compose file shows the backing services. Postgres runs the postgis image by default, with the image overridable, and it has a healthcheck using pg_isready against the osrd database. Valkey is the cache and message store, RabbitMQ is the queue, OpenFGA is the authorisation service and it runs its own migration step against Postgres before starting, and there are containers for Jaeger, which is the tracing backend, and S3-compatible storage.

The OpenFGA arrangement is worth noting for anyone deploying this. There is a separate openfga-migrate service that depends on Postgres being healthy and runs the migrate command, and the openfga service waits for the migration to complete successfully before it starts. So authorisation is modelled as a relationship graph with a relational authorisation model, and the schema is managed as part of the deployment rather than by hand.

The presence of osrd_schemas/ as a separate directory, and of osrdyne/ and railway_manager_interface/ for external systems, tells you the design assumes the application will sit alongside a railway management system rather than replace it. That is the shape of an infrastructure design tool in practice.

Getting the stack up and loading an example network

The Getting Started section is a copy-and-paste sequence that takes you from an empty checkout to a running application with data in it.

sh
# build and run the entire stack
docker compose up -d --build

# import an small example infrastructure ("small_infra")
./scripts/load-railjson-infra.sh small_infra tests/data/infras/small_infra/infra.json

# import rolling stocks with realistic characterics, representative of the industry
./scripts/load-railjson-rolling-stock.sh tests/data/rolling_stocks/realistic/*.json --force

# open the web app
xdg-open http://localhost:4000/

The data format the loaders consume is RailJSON, and the two scripts separate the concerns: one loads the infrastructure, the other loads the rolling stock, and the rolling stock import takes a set of realistic examples with a --force flag, then a broader set without it. The application itself is served on port 4000.

There are three platform-specific notes that are the kind of thing a README usually omits and that you will hit anyway.

Linux or WSL users can use ./osrd-compose host instead of docker compose to enable host networking, which can be useful to launch services in a debugger. macOS users on Apple Silicon should make sure to set an arm64 image name for Postgres and PostGIS to prevent slow amd64 emulation, done by creating a .env with OSRD_POSTGIS_IMAGE='nickblah/postgis:16-postgis-3' in it before running the first docker compose command. And the compose file exposes the Postgres port on 5432, so it will conflict with a local Postgres if you have one running.

The STDCM module needs one further step, because it inherits its search environment from an existing scenario. You create a scenario, copy its ID from its URL, then run:

sh
docker compose exec editoast editoast stdcm-search-env set-from-scenario <id>

And if you need to use speed limits tags and loading gauge, there is a longer form that writes a JSON file, copies it into the container and passes the tags through:

sh
echo '{ "LG1": [], "LG2": [] }' > /tmp/allowed_tracks.json
docker cp /tmp/allowed_tracks.json osrd-editoast:/tmp/
docker compose exec editoast editoast stdcm-search-env set-from-scenario <id> --speed-limit-tags "CC100|100" "CC90|90" "CC200|200" --default-speed-limit-tag "CC100" /tmp/allowed_tracks.json

The speed limit tags are the European conventional speed codes, and the loading gauge keys are the track gauge identifiers, so this is where a European infrastructure's conventions enter the tool.

The nix and process-compose path, and the warning attached to it

There is an alternative to Docker Compose that the README marks as experimental. The project also attempts to maintain a flake.nix to have a full development environment, which means installing the nix package manager and enabling flakes as explained in the flakes docs. Then you enter the shell with:

sh
nix develop

And in that shell you start the stack with the following commands:

sh
export OSRD_PATH="$(pwd)"
# Launch all the external services, still relies on Docker
./osrd-compose up --detach postgres rabbitmq valkey openfga jaeger s3
# Launch the OSRD stack
process-compose

The split is the interesting part. The external services, meaning the databases, the queue, the cache, the authorisation service, the tracing backend and the object storage, still run under Docker, while the OSRD services themselves are launched by process-compose. The process-compose.yaml file in the root is the definition of what that means.

The warning is explicit and worth heeding: most scripts in the scripts/ folder depend on using the Docker stack, so use them with precaution if you start the stack with process-compose, as they may work, or crash, or produce weird behaviors.

That is a candid statement of the situation. The nix path gives you a reproducible development environment for the code without the Docker build for every service, but the data loaders, which are shell scripts wired to the compose setup, are not part of that. For a contributor working on the front end or the core, the nix path is the faster loop. For anyone who needs to import an infrastructure and then explore it, the Docker path is the one that works.

Working on a single component, and the demo you should not use in production

The project has a per-component development workflow that is worth knowing about, because running the whole stack to change one front end file is wasteful.

Each component has a justfile to run usual development tasks. You install just and run it to see available recipes, and all the components include run, install, test, format, lint and fix-lint. So the same six verbs exist everywhere, and the justfile is where the per-component specifics live.

There is also a public demo at demo.osrd.fr, and the important thing about it is the warning attached. That environment is not intended for use in production, it is refreshed daily, and the data entered is accessible to everyone. That last clause is the one to pay attention to: anything you load into the demo is visible to other users of the demo. It is a place to click through the interface, not a place to enter real infrastructure data.

The languages section adds another dimension. OSRD supports multiple languages, with a table of translation status per language and a column marking whether the language is integrated, meaning users can actually activate it in the application. English, French, German and Portuguese are integrated, and Spanish is not. Translations are contributed through Weblate, and the README says contributing to the translation can be done easily.

For a European infrastructure project, four live interface languages and a fifth in progress is a reasonable place to be, and the integrated column is a genuinely useful distinction that many projects do not track: a translation that exists but cannot be switched on in the app is not a translation yet.

Editorial conclusion

Adopt OSRD if you are a European infrastructure manager or a researcher who needs railway design, capacity analysis, timetabling and simulation in one open source tool rather than a commercial suite, and if you can work around the fact that the interfaces are still moving. Do not adopt it as a production system without reading the development status note, because the README says plainly that the user and programming interfaces are not entirely stable, and do not put real infrastructure data into the public demo, which is refreshed daily and visible to everyone. Before you commit, run the docker compose stack with the small_infra example and the realistic rolling stock so you can see the whole chain working, and set OSRD_POSTGIS_IMAGE in a .env before the first run if you are on Apple Silicon, otherwise you will spend the first build inside an emulation layer.

Frequently asked questions

What is OSRD and what does it cover?

OSRD, the Open Source Railway Designer, is an open source web application for railway infrastructure design, capacity analysis, timetabling and simulation, and short term path request. The project states it is free and open-source forever, and it is published under the LGPL with a LICENSES directory in the repository root.

How do I run OSRD locally?

Build and start the whole stack with docker compose up -d --build, import an example infrastructure with ./scripts/load-railjson-infra.sh, import rolling stock with ./scripts/load-railjson-rolling-stock.sh, and open http://localhost:4000/. Linux or WSL users can use ./osrd-compose host instead to enable host networking.

What is the STDCM setup step in OSRD?

The last-minute train module needs its search environment set from an existing scenario. You create a scenario, copy its ID from its URL, and run docker compose exec editoast editoast stdcm-search-env set-from-scenario <id>, with longer options for speed limit tags and loading gauge.

Is the OSRD demo environment safe to use?

No. The README states the demo is not intended for use in production, that it is refreshed daily, and that the data entered is accessible to everyone. Treat it as a place to try the interface rather than a place to enter real infrastructure data.

What are the stability caveats for OSRD?

The README says OSRD is still in active development, that user and programming interfaces are not entirely stable and are still occasionally modified, and that if you rely on OSRD you should be prepared to deal with regular changes. The recent releases v1.3.0 to v1.3.2 landed between September and October 2026.

Official sources

  1. Issues
  2. OpenRailAssociation/osrd on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/openrailassociation-osrd.svg)](https://hysenlabs.com/projects/openrailassociation-osrd)

Was this useful?