What is the difference between OSH and YSH in Oils?
Updated
OSH and YSH are the two languages inside Oils, and they ship in the same 2 MB oils-for-unix binary. OSH runs your existing shell scripts, so it is the one to use when you need bash compatibility. YSH is a newer language aimed at Python and JavaScript users who avoid shell, and it adds features like JSON handling that plain shell does not have. Pick OSH to run what you already have; pick YSH to write new code with a cleaner, more structured language.
OSH: run existing shell scripts
OSH is the compatibility layer. The Oils homepage describes it as the "upgrade path from bash," and its job is to execute the shell scripts you already have.
The example on the site shows what that means in practice:
echo "hello $oops"
^~~~~ fatal: Undefined variable 'oops'
Instead of silently expanding an unset variable to an empty string, OSH reports it as a fatal error. That is the "better language and runtime" part: you keep running your scripts, but the runtime catches mistakes that bash would let pass.
Choose OSH when:
- You have existing bash or POSIX shell scripts you want to run without rewriting them.
- You want stricter error detection on the scripts you already depend on.
- You are migrating gradually and want a drop-in path rather than a new language.
YSH: for Python and JavaScript users who avoid shell
YSH is the second language in the same binary, and the homepage frames it directly: "YSH is for Python and JavaScript users who avoid shell!"
The distinction is about who the language is for. If you come from Python or JavaScript and find shell syntax awkward, YSH is the part of Oils designed for you. It is not a compatibility layer for old scripts; it is a language you write new code in.
The site's example shows the kind of structured data handling that is painful in plain shell:
ysh$ json read < x.json
ysh$ = _reply
(Dict) {shell: "ysh", fun: true}
Here json read parses JSON from standard input, and = _reply prints the resulting value with its type shown as (Dict). In a traditional shell, reading and inspecting JSON usually means piping through an external tool and losing type information. YSH handles it as a first-class value.
Choose YSH when:
- You are writing new scripts and prefer a language closer to Python or JavaScript.
- You need to read, inspect, or manipulate structured data such as JSON.
- You want typed values rather than everything being a string.
Side-by-side
| Dimension | OSH | YSH |
|---|---|---|
| Primary purpose | Run existing shell scripts | Write new code in a shell-like language |
| Audience | People with bash/POSIX scripts | Python and JavaScript users who avoid shell |
| Compatibility goal | Bash compatibility / upgrade path | New language, not a compatibility layer |
| Example feature | Fatal error on undefined variable | json read and typed value output |
| Distribution | Same oils-for-unix binary |
Same oils-for-unix binary |
How they relate
The two are not competing products you install separately. The homepage states that "OSH and YSH live inside the same 2 MB oils-for-unix binary," so installing Oils gives you both. You decide which language to use per script or per task.
A practical way to think about it: OSH is the bridge from where you are (existing shell scripts), and YSH is the destination if you want a better language for new work. You can start with OSH to run what you have, then adopt YSH for new scripts without changing your installation.
Where to go next
- Install and reference material are linked from the Oils site under Install, Docs, and the Oils Reference.
- The blog covers background such as "Why Create a New Unix Shell?" and a "Tour of YSH," which are useful if you want the reasoning behind the design.
- For questions, the site points to Zulip at
oilshell.zulipchat.com, with#oil-helpfor user questions and#oil-discuss-publicfor general discussion. - Source and editor support are on GitHub at
oils-for-unix/oils, includingoils.vimeditor support.