Write Once, Build Once, Anywhere
One of the core philosophies ofsame is the guarantee that if a build works on your machine, it will work on your colleague’s machine and in your CI/CD pipeline. This property is known as hermeticity.
In many build systems, scripts rely on tools and environment variables present on the host system. This leads to the infamous “it works on my machine” problem, where a build succeeds locally because of a specific version of a tool or a set environment variable, but fails elsewhere where those conditions differ.
same eliminates this class of problems by enforcing strict isolation for every task it executes.
How It Works
To achieve hermeticity,same controls the execution environment of every task with two primary mechanisms:
1. Environment Filtering
Whensame launches a task, it does not inherit the full environment of your shell. Instead, it strips away almost everything to ensure no accidental dependencies leak into your build.
Only a strict allow-list of system environment variables is passed through:
HOME: Required for tools that need to write to user configuration directories.TERM: Preserved to ensure colorful and formatted output is displayed correctly.USER: Passed for tools that rely on user identity.PATH: Injected carefully (see below).
AWS_ACCESS_KEY_ID, GOPATH, or custom flags) is invisible to the task unless explicitly declared in your same.yaml configuration.
2. Tool Injection
ThePATH variable is constructed in a specific order to prioritize reproducibility:
- Nix Environment: The bin directories of the tools defined in your configuration are prepended to the
PATH. This ensures that when you callgo,node, orpython, you are using the exact version pinned in yoursame.yaml, not the version installed on the host system. - System PATH: The system
PATHis appended at the end to allow access to basic system utilities if absolutely necessary, but shadowed by the declared tools.
same creates a “clean room” for every execution.
The Benefits
- Portability: You can onboard a new developer simply by having them install
same. They don’t need to manually install twenty different tools or configure their shell profile. - Reproducibility: CI pipelines become reliable. You won’t face issues where a CI runner has a slightly different version of a compiler than your local machine.
- Debuggability: If a build fails, you know it’s likely due to the code or configuration, not a hidden environment variable changing the behavior of a tool.