Open-source project
vercel/hyper avatar
vercel/hyper

Hyper: an Electron terminal whose postinstall does nine things

GitHub describes it as A terminal built on web technologies. The repository metadata lists TypeScript as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.

44,743 stars3,579 forksTypeScriptMIT

At a glance

What is it?
Hyper is Vercel's terminal built on web technologies, an Electron app with a webpack bundle and a V8 snapshot, developed on the canary branch. The build is where the real documentation lives: a postinstall chain that downloads a snapshot binary, three documented native-toolchain failures, and four package managers that can all serve a build older than the code you are reading.
Who is it for?
Adopt Hyper if you want an Electron-based terminal with a plugin and theme API and you are prepared to own the native toolchain, since node-pty, GraphicsMagick and the platform build tools are part of the dependency. Do not adopt it on the assumption that a package manager gives you current code: the newest GitHub release is 4.0.0-canary.5 from 2023-07-13 while the canary branch has moved since.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 39 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 September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A webpack bundle, a TypeScript watch, and a snapshot for startup

Hyper is an Electron application, and the two scripts that matter say how it is put together. Development runs two watchers side by side:

json
    "app": "cross-env ELECTRONMON_LOGLEVEL=error electronmon target",
    "dev": "concurrently -n \"Webpack,TypeScript\" -c \"cyan.bold,blue.bold\" \"webpack -w\" \"tsc --build -v --pretty --watch --preserveWatchOutput\" -k",

The renderer is bundled by webpack, the rest is compiled by tsc, and the two are run under concurrently with -k so one dying takes the other with it. electronmon then launches Electron against the target/ directory, which is why the README insists on two terminal tabs: pnpm run dev in one, pnpm run app in the other.

Startup speed comes from a second mechanism. There is a v8-snapshot script that builds a snapshot twice, once for x64 and once for arm64, from a base produced by mk-snapshot and cp-snapshot, and a production build that runs webpack, then tsc, then Babel over target/renderer/bundle.js with --minified and --no-comments. The terminal is a web stack, and the snapshot is what keeps that stack feeling fast.

The README also spells out the consequence of this design: if you interrupt pnpm run dev you must relaunch the app every time, because webpack only rebuilds what changed and Electron is not restarted for you.

postinstall downloads a binary and copies node_modules twice

The install step is not quiet. Here is the whole chain:

json
    "postinstall": "pnpm run v8-snapshot && webpack --config-name hyper-app && electron-builder install-app-deps && pnpm run rebuild-node-pty && cpy --cwd=target node_modules \"../../app/\" && husky install && pnpm run generate-schema",

Counted: build the V8 snapshot for both architectures, run a webpack config, install native app dependencies through electron-builder, rebuild node-pty, copy node_modules from target into the app/ directory, install the git hooks with husky, and generate a schema. There is also a v8-snapshot pair that names the architectures explicitly:

json
    "v8-snapshot": "cross-env npm_config_arch=x64 pnpm run v8-snapshot:arch && cross-env npm_config_arch=arm64 pnpm run v8-snapshot:arch",
    "v8-snapshot:arch": "pnpm run mk-snapshot && pnpm run cp-snapshot",

Two things follow. A pnpm install needs the network, a working native toolchain and a successful snapshot download, and any of those failing leaves a checkout that looks installed and is not. And there are two copies of node_modules, one under target/ and one under app/, which is why the clean target has to remove both:

json
    "clean": "node ./bin/rimraf-standalone.js node_modules && node ./bin/rimraf-standalone.js ./app/node_modules && node ./bin/rimraf-standalone.js ./app/renderer",

The start script is a courtesy notice in this style: it only prints that you should run pnpm run dev in one tab and pnpm run app in another.

Three native build failures, each with a documented one-line fix

The README keeps a section of known development issues, and all three entries are environment problems with an explicit remedy.

The first is an alert dialog about node-pty after a build. The fix is pnpm run rebuild-node-pty, which runs electron-rebuild against node-pty in target, and on macOS the cause is usually Xcode, specifically not having agreed to the Terms of Service, which the README says you fix by running sudo xcodebuild after a fresh Xcode install.

The second is compiler errors during pnpm install on macOS, fixed by exporting CXX=clang++. The third is a failure in the codesign step when running pnpm run dist on macOS, which you can work around for the current terminal session by exporting CSC_IDENTITY_AUTO_DISCOVERY=false.

That is three toolchain-dependent steps in one dependency, and the project treats that as normal. A contributor on Windows is told to run pnpm add --global windows-build-tools from an elevated prompt, on RPM-based Linux to install GraphicsMagick, libicns-utils and xz, and on Debian-based Linux graphicsmagick, icnsutils and xz-utils. macOS is the only platform listed as needing nothing extra.

The practical reading is that your OS packages are part of this project's dependencies, and a failing install is usually your machine rather than the code.

The newest release tag is from 2023 and the branch is called canary

The default branch is canary, the manifest version is 4.0.0-canary.5, and the three most recent releases are 4.0.0-canary.5 on 2023-07-13, 4.0.0-canary.4 on 2023-07-01 and 4.0.0-canary.3 on 2023-01-29.

Read those dates next to the last push, which was on 2026-08-21. The repository is not archived and code is still landing on it, but the newest GitHub release predates that by three years, and the manifest still carries the canary number from that release rather than a bumped one. So the code you read on the default branch and the build a package manager gives you are different things, and nothing in the version string tells you which one you have.

The name canary is part of the same message. There is no stable channel described here, only a canary line with numbered prereleases, and the project's own stated focus is speed, stability and getting the extension API right, with the community expected to supply the rest.

For anyone pinning, the useful habit is to record where the binary came from. Version numbers from a package manager and versions from the release page are not comparable, and the README warns about exactly this.

Four package managers, and each may be behind the release

Installation is delegated, one command per platform:

sh
paru -S hyper

for Arch and derivatives through the AUR, and on NixOS:

sh
nix-env -i hyper

On macOS it is Homebrew Cask, with an update first:

bash
brew update
brew install --cask hyper

and on Windows it is Chocolatey:

bash
choco install hyper

Then the caveat, which is the important part. The version available on Homebrew Cask, Chocolatey, Snapcraft or the AUR may not be the latest, and the README asks you to download from hyper.is if that is the case.

So the install path is a choice about freshness. A package manager gives you a dependency-resolved, upgradeable copy that may trail the project by months or years; the site gives you the newest build with no upgrade story at all. Neither is wrong, but you should know which one you have before you file a bug against behaviour you do not have.

Extensions are the product, and PLUGINS.md is the contract

The project states its goal as a beautiful and extensible experience for command line users built on open web standards, and then narrows it: in the beginning the focus is on speed, stability and the development of the correct API for extension authors.

That third item is the one a plugin author cares about, and the repository gives it a home. PLUGINS.md sits at the root, next to app/, lib/, cli/, build/, test/ and typings/, which is a layout that separates the packaged application from the code a plugin might import. Around it sit the reference projects: a website repository, a sample extension called hyperpower, a sample theme called hyperyellow, and a community list of Hyper projects.

Two habits pay off here. Read PLUGINS.md before designing anything, because the API is the stated priority and the fastest way to find out what it supports is the document rather than the source. And start from the sample extension and the sample theme, because they show the shape of a working plugin and a working theme against the current API, which is a different and more reliable signal than the age of the release tags.

The theme repository is the smaller of the two experiments and the cheaper place to see how a Hyper extension is packaged.

The manifest still points at zeit/hyper

Small details in the package manifest tell you how the project has moved. The name is hyper and the version is 4.0.0-canary.5, but the repository field still reads zeit/hyper, the organisation the project lived under before it moved to Vercel. Any tool that reads repository.url out of the manifest, which includes some badges and some publish flows, resolves to the old address.

The rest of the configuration is current and strict. The package manager is pinned with an integrity hash, [email protected] plus a sha512 digest, so a contributor and CI get the same pnpm. The lockfile is pnpm-lock.yaml alongside a pnpm-workspace.yaml. Unit tests run through ava with a separate ava-e2e.config.js for end-to-end runs, and the lint script covers every extension that matters:

json
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx,.json",

Running eslint over json as well as source means formatting is a test, not a preference, which is the difference between a tidy repository and an enforced one. There are separate TypeScript configurations, tsconfig.json, tsconfig.base.json and tsconfig.eslint.json, a babel.config.json, a webpack.config.ts, two electron-builder configurations including electron-builder-linux-ci.json, a release.js at the root, and a .husky/ directory that the postinstall wires up.

The licence is MIT. The age of the release tags, not the licence, is what you should raise with the maintainers.

Editorial conclusion

Adopt Hyper if you want an Electron-based terminal with a plugin and theme API and you are prepared to own the native toolchain, since node-pty, GraphicsMagick and the platform build tools are part of the dependency. Do not adopt it on the assumption that a package manager gives you current code: the newest GitHub release is 4.0.0-canary.5 from 2023-07-13 while the canary branch has moved since. Verify first by running pnpm run rebuild-node-pty after install, and by comparing the version your package manager gives you against the release page on hyper.is.

Frequently asked questions

How do I install Hyper on Linux, macOS and Windows?

Arch and derivatives install from the AUR with an AUR helper such as paru using paru -S hyper, NixOS uses nix-env -i hyper, macOS uses Homebrew Cask with brew install --cask hyper, and Windows uses choco install hyper. The README warns that these package managers may not carry the latest version, in which case you download from hyper.is.

How do I build Hyper from source?

Enable pnpm with corepack enable pnpm, install the platform packages listed for your system, fork and clone the repository, then run pnpm install and pnpm run dev. Launch the app from a second terminal with pnpm run app, or use the Launch Hyper configuration in Visual Studio Code, and generate distributable binaries with pnpm run dist.

Why does my Hyper build fail with a node-pty error?

An alert dialog about node-pty after a development build is fixed by running pnpm run rebuild-node-pty. On macOS the underlying cause is usually Xcode not having its Terms of Service accepted, which you resolve by running sudo xcodebuild after a fresh Xcode installation.

How do I write an extension or theme for Hyper?

PLUGINS.md at the root of the repository is the reference for the extension API, which the project names as one of its three initial focuses along with speed and stability. The related repositories include a sample extension, a sample theme, the website and a community list of Hyper projects.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
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/vercel-hyper.svg)](https://hysenlabs.com/projects/vercel-hyper)