Zasper: a notebook IDE that ships as one static binary and treats auth as mandatory
High Performace IDE for Jupyter Notebooks
At a glance
- What is it?
- A Go and TypeScript reimplementation of the Jupyter notebook experience, built for concurrency and small resource use, with a self-hosting model that assumes every session needs a token.
- Who is it for?
- Zasper is a credible option when you want a notebook environment you can hand to other people on a shared machine, because the access token is enforced rather than optional and the deployment is a single file with no runtime dependencies. The two consecutive breaking releases in September 2026 are the thing to read before adopting it, since scripts talking to the API had to move away from tokens in URLs and now authenticate with a bearer header.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- 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 7, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What replaces JupyterLab, and what does not
The pitch is one sentence: any Jupyter kernel, one static binary, a fraction of JupyterLab's resource use. The mechanics matter more than the slogan, so it is worth being precise about what carries over. Zasper implements Jupyter's wire protocol, which means it drives any kernel that speaks it, and it reads and writes the `.ipynb` format directly, so a notebook saved in Zasper is byte for byte what Jupyter would have written. That second property is the one that decides whether notebooks move between tools, and the README states it as a guarantee rather than an aspiration.
Around the notebook there is an editor, a terminal, and version control in the same window, plus a command palette that finds files and commands in one search, light and dark themes, and window zoom. Notebooks render Plotly output, ipywidgets, HTML, and Markdown with LaTeX inline.
One thing Zasper does not do is install a kernel. It runs kernels but does not provide one, so `pip install ipykernel` is enough to get started, and without a kernel the app still starts and the Launcher tells you what is missing. That is a reasonable division of responsibility, and it means the same binary works for a Python kernel, an R kernel, or anything else on your machine.
Installing from a package manager or a release tarball
Three package routes are documented. Homebrew needs a trust step first, which is not boilerplate: Homebrew 6 loads nothing from a third party tap until it is trusted, and `brew trust` is what records that.
brew tap zasper-io/tap
brew trust zasper-io/tap
brew install zasper-io/tap/zasperThere is a migration note for anyone who installed a 0.x build through Homebrew. From 1.0 onward Zasper ships as a cask rather than a formula, so the old install has to be removed with `brew uninstall zasper` first.
Conda is the shortest route, for anyone who already manages environments:
conda install -c conda-forge zasperThe Snap channel also exists:
sudo snap install zasperFor direct downloads, every release carries signed and notarized macOS builds plus static binaries for Linux and Windows, and each release includes a checksum file you can verify:
sha256sum -c zasper_<version>_checksums.txt --ignore-missingThe archive naming follows a strict pattern, for example `zasper-webapp-2.0.0-linux-amd64.tar.gz`, with the webapp prefix appearing on every platform including Windows, which ships as a zip. The Linux archives are plain tarballs where one build serves every distribution, and the README is explicit that there is no `.deb` or `.rpm` yet. If you want a distribution package for a fleet, you are packaging it yourself from that tarball.
Platform support described honestly, including the gaps
The support table is the most useful paragraph on the page because it names what is incomplete. macOS and Linux are both listed as supported. Windows is listed as supported with a caveat: binaries are published and notebooks run, but terminals are not available yet and some kernel paths are less well exercised, with WSL recommended for terminals and the best experience.
That level of candour is worth crediting. A notebook IDE that runs notebooks but not terminals is still a useful tool on Windows, since the terminal is the part most replaceable by other software, but you should know before you install rather than after.
The application also expects a modern browser. Zasper serves its interface locally rather than shipping as a separate desktop application, which is what keeps the deployment a single binary, and it is why a browser is listed as a requirement.
The stated install target is v2.0.0, and running the binary with no arguments starts it in the current working directory. Docker is supported but not packaged in the repository root; an image can be built from the `docker/` directory, with the details in `docker/README.md`.
Two breaking releases in nine days, both about session security
The release history explains a lot about the project's direction. v1.1.0 landed on 2026-09-14 and made protected mode unconditional. `--protected` is still accepted so existing scripts keep starting, but `--protected=false` is ignored with a warning, and `ZASPER_JWT_SECRET` was removed in favour of deriving the signing key from the access token itself.
Then v2.0.0 on 2026-09-22 moved the browser session into an `HttpOnly` cookie. The stated reason is that a session token in a URL leaks: it ends up in server and reverse proxy access logs, in browser history, and in error reports, and whoever reads it holds a live session for up to 24 hours. The consequence for API clients is concrete. WebSocket routes no longer accept `?token=<jwt>`, so a script opening `/ws/kernels/{id}/channels` or `/ws/terminals/{id}` sends `Authorization: Bearer <jwt>` on the upgrade instead. The `protected` field also disappeared from `/api/config` and `/api/info`, since it has been `true` on every server since 1.1.0; treat a missing field as true.
The app itself upgrades without action. Scripts do not. If you have automation against a Zasper instance, that upgrade path is the part to test first, and `docs/API.md` carries the details under a section on what was removed in 2.0.0.
A Go binary with a TypeScript interface
GitHub reports this repository's primary language as TypeScript, while the topic tags include `golang` and the module declaration at the root of `go.mod` says `module github.com/zasper-io/zasper` with `go 1.26.0`. Both facts are correct at once. The tree explains the split: `app.go`, `browser.go`, `desktop.go`, `serve.go`, `main_cli.go`, and `spa*.go` at the root are the server, the `ui/` directory holds the web interface, and `internal/` holds the bulk of the implementation.
The dependency list describes what the server actually does. `wailsapp/wails/v3` is the desktop shell, which is how the same code serves a local window and a shared server. `gorilla/websocket` and `coder/websocket` handle kernel channels, `creack/pty` is what makes terminals possible at all, `golang-jwt/jwt` handles sessions, `go-git/v5` backs the version control pane, `editorconfig-core-go` picks up `.editorconfig`, `zerolog` does logging, `google/uuid` and `gorilla/mux` are plumbing. There is also `posthog/posthog-go`, which is worth noting because a project with a privacy document and self-hosting as a headline feature is making a choice there.
The version bump process is enforced in the Makefile rather than left to discipline. `bump-version` refuses to run on `main` and prints a message telling you to create a release branch. The comment explains why: it used to commit, tag, and push in one step, which published a release before review or CI, so releases now go through a pull request and the tag is pushed from `main` after the merge.
Reading the performance claim carefully
The README states that in benchmarks against JupyterLab, Zasper uses up to 5 times less CPU and up to 40 times less memory, with higher throughput and lower latency, and that it stays responsive under very high load. There is a chart comparing resource use and a link to a separate `zasper-benchmark` repository for the methodology and full results.
Those are the project's own numbers against a baseline the project selected, published in a repository maintained by the same team, and the two figures are best-case multiples rather than averages. That does not make them wrong. It does mean the useful question is which workload was measured, because resource ratios between two notebook servers depend enormously on how many kernels are running and how much of the work is in the kernel versus the interface. Zasper runs the kernels either way, so the interface and server layers are what the comparison is about.
The design intent behind the numbers is stated plainly in the README: Zasper is built for concurrency and a small footprint, and it implements the wire protocol rather than wrapping a Python notebook server. Both of those choices, protocol implementation and a Go server, are what make a resource comparison against JupyterLab meaningful in the first place.
Activity is current. The last push was on 2026-09-23, one day after v2.0.0, the repository is not archived, and there are 2,351 stars with 77 forks against only 3 open issues.
Editorial conclusion
Zasper is a credible option when you want a notebook environment you can hand to other people on a shared machine, because the access token is enforced rather than optional and the deployment is a single file with no runtime dependencies. The two consecutive breaking releases in September 2026 are the thing to read before adopting it, since scripts talking to the API had to move away from tokens in URLs and now authenticate with a bearer header. The performance claim against JupyterLab points at a separate benchmark repository rather than at anything reproducible inside this tree, so treat the multiples as a reason to look, not as a settled result. Install the Homebrew cask or the conda package, start it in an empty directory, and see whether the terminal and version control panes cover what JupyterLab was doing for you.
Frequently asked questions
What are some alternatives to JupyterLab?
On the notebook IDE side, the notable ones are Zasper and the various hosted notebook platforms. Zasper's specific angle is that it speaks Jupyter's wire protocol and reads and writes `.ipynb` directly, so it runs any Jupyter kernel and your notebooks move between it and JupyterLab unchanged. It also ships as a single static binary rather than a Python server plus extension stack.
Does Zasper require a Jupyter kernel to be installed?
It runs kernels but does not install one, so `pip install ipykernel` is enough to start. Without a kernel the application still launches and the Launcher tells you what to install. This is what lets the same binary drive a Python, R, or any other kernel you already have on the machine.
How do I authenticate API scripts against Zasper after version 2.0.0?
Send `Authorization: Bearer <jwt>` on the WebSocket upgrade instead of putting the token in the URL. Routes such as `/ws/kernels/{id}/channels` and `/ws/terminals/{id}` no longer read `?token=<jwt>`, and a missing `protected` field in `/api/config` or `/api/info` should be treated as `true`.
Does Zasper work on Windows?
Binaries are published for Windows and notebooks run there, but terminals are not available yet and some kernel paths are less well exercised. The README recommends WSL for terminals and the better overall experience.
Official sources
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.
[](https://hysenlabs.com/projects/zasper-io-zasper)