If you've worked with JavaScript for a while, you've probably experienced something like this:
You clone a repository.
You install dependencies.
A few seconds later:
Unsupported engine.
"Okay, I'll switch my Node version."
You switch versions.
Now pnpm isn't the right version.
You fix that.
Then another project suddenly stops working because it expected a different Node release.
Rinse and repeat.
At some point you start wondering why managing JavaScript environments feels harder than actually writing JavaScript.
It's not just a Node.js problem
For a long time I thought the issue was Node itself.
It isn't.
The real problem is that modern JavaScript development doesn't depend on a single runtime anymore. Every project has its own combination of tools.
One project might expect:
- Node.js 24
- pnpm 11
Another one might require:
- Node.js 22
- Yarn 4
Maybe another project uses Bun.
Another uses Deno.
Some repositories rely on packageManager, others use .nvmrc, some use .node-version, and some have no version information at all.
If you're working across multiple repositories, it's easy to end up constantly switching runtimes and package managers just to get a project running.
The "works on my machine" problem
It gets even worse when you're working with other people.
Maybe your teammate has Node 24 installed.
You still have Node 22.
CI downloads yet another version.
Someone updates pnpm without telling anyone.
Suddenly the same repository behaves differently depending on who runs it.
We've all seen bugs that weren't actually bugs, they were just different environments.
The current solutions
There are already some great tools out there.
- nvm
- fnm
- Volta
- mise
They all solve parts of the problem, and many developers use them every day.
But I kept running into the same thought:
“Why am I managing multiple tools just to manage my tools?”
One application manages Node.
Another helps with package managers.
CI needs its own setup.
Documentation tells contributors what to install.
There's a lot of moving pieces.
A different idea
That's why I started building Jolter.
The goal wasn't to replace Node.
It wasn't even just to replace another version manager.
The goal was much simpler:
A project should be able to describe its entire JavaScript toolchain in one place.
Instead of asking contributors to manually install the right versions, the repository simply declares what it needs.
For example:
{
"$schema": "https://schemas.jolter.dev/project/v2/schema.json",
"schemaVersion": 2,
"runtime": {
"node": "24"
},
"tools": {
"pnpm": "11"
}
}
Enter fullscreen mode Exit fullscreen mode
That's it.
The project says it needs Node 24 and pnpm 11.
No guessing.
No README instructions that slowly become outdated.
No "which version are you using?"
Getting started
Installing Jolter takes a single command.
Linux / macOS
curl -fsSL https://jolter.dev/install.sh | sh
Enter fullscreen mode Exit fullscreen mode
Windows (Powershell)
irm https://jolter.dev/install.ps1 | iex
Enter fullscreen mode Exit fullscreen mode
Then initialize it:
jolter setup
Enter fullscreen mode Exit fullscreen mode
Pick your preferred defaults:
jolter use node@lts
jolter use pnpm@11
Enter fullscreen mode Exit fullscreen mode
And whenever you're inside a project:
jolter pin node@24
jolter pin pnpm@11
jolter sync
Enter fullscreen mode Exit fullscreen mode
Jolter creates a jolter.json file that you commit to your repository, so everyone, including CI, uses the same toolchain.
No more switching versions manually
One thing I always found annoying was manually changing runtimes whenever I switched projects.
Jolter approaches this a little differently.
Instead of relying on shell hooks, it creates lightweight command shims.
Whenever you run a command like:
node
pnpm
npm
yarn
Enter fullscreen mode Exit fullscreen mode
Jolter figures out which project you're currently in and automatically launches the correct runtime and tools for that repository.
That means you can jump between completely different projects without manually switching versions every time.
The same setup works in CI
One of my biggest goals was making local development and CI behave the same way.
Instead of maintaining separate setup scripts, CI can simply run:
jolter setup-ci
Enter fullscreen mode Exit fullscreen mode
The same project configuration is used to install and activate the required runtime and tools.
If it works locally, it should work in CI too.
Still early, but already useful
Jolter is still a young project, and there are plenty of ideas I want to build over the coming months.
But even today it already supports:
- Node.js
- Bun
- Deno
- npm
- pnpm
- Yarn
- Automatic project switching
- GitHub Actions
- GitLab CI
- A plugin system for managing additional developer tools
The goal is to have one place that manages your JavaScript toolchain, whether you're working alone, with a team, or inside CI.
Final thoughts
I don't think JavaScript needs another package manager.
It doesn't need another runtime either.
What I think it needs is a simpler way to manage the tooling we already have.
That's the problem I'm trying to solve with Jolter.
If that sounds interesting, I'd love to hear what you think.
Feedback, ideas, and even criticism are always welcome—it's how open source gets better.
Thanks for reading. ❤️
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.