# Authenticator puts 2-step codes in the browser, and every npm script ends at one bash file

> Authenticator is a TypeScript browser extension that generates 2-Step Verification codes for Chrome, Firefox and Edge. Its build is a single bash script reached through npm targets, which is simple to read and awkward on Windows.

**Authenticator-Extension/Authenticator** — Authenticator generates 2-Step Verification codes in your browser.

- Repository: https://github.com/Authenticator-Extension/Authenticator
- Website: https://authenticator.cc
- Stars: 4,705 · Forks: 1,168
- Language: TypeScript
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/authenticator-extension-authenticator

## The codes live in the browser, not on a phone

Authenticator generates 2-Step Verification codes in your browser. That single sentence is the whole product, and it is why the project ships as a browser extension rather than an application. It is published for three browsers, Chrome, Firefox, and Microsoft Edge, and a separate Safari edition is available on the App Store. That last one carries its own condition: the project states plainly that no official support is provided for the Safari edition, and the guidance for producing a Safari build lives in a different repository, Authenticator-Extension/Authen. So the practical consequence is that anyone on Safari is running a build whose problems nobody is contractually obliged to fix, while Chrome, Firefox, and Edge users get the code path the project maintains.

## Every npm target ends at scripts/build.sh

The package manifest keeps the scripts small and pushes the work into one bash file:

```json
"scripts": {
  "compile": "bash scripts/build.sh firefox",
  "chrome": "bash scripts/build.sh chrome",
  "firefox": "bash scripts/build.sh firefox",
  "edge": "bash scripts/build.sh edge",
  "prod": "bash scripts/build.sh prod",
  "test": "node scripts/test-runner.js"
}
```

Five build targets differ only by the argument they pass, and test is the exception because it hands off to a Node runner instead of the build script. This is easy to read, and it has one cost: the build is bash, not Node. The project says so directly for Windows users, who should install a tool like Git Bash or Cygwin to build at all. On Windows without one of those, the failure is not a missing dependency you can install from npm, it is a missing shell.

## npm run dev:chrome watches into ./test/chrome

Day to day work on the Chrome build uses the development target rather than a one-shot compile:

```bash
npm run dev:chrome
```

That target runs the pretest build first and then webpack in watch mode against ./webpack.watch.js, and the compiled extension lands in the ./test/chrome directory, which you load as an unpacked extension in Chrome. The tree explains why there is more than one webpack file: webpack.config.js sits next to webpack.dev.js, webpack.prod.js, and webpack.watch.js. For the developer this means the loop is watch, build, reload in the browser, with no packaging step in the way, and the unpacked directory is a build artefact you can delete at any time. For a reader it shows the shape of the project, TypeScript in src/, styling in sass/, and views under view/.

## npm ci then npm run prod is the reproducible path

The documented way to reproduce a build is two commands:

```bash
npm ci
npm run prod
```

The difference from the development path matters. npm install resolves dependencies afresh and will happily move the tree forward, while npm ci installs exactly what package-lock.json pins and fails if the lockfile and the manifest disagree. Since the repository commits package-lock.json, the reproducible path is the locked one, and a change to dependencies that does not land with the lockfile will break that build for whoever tries it next. The general build setup section, which pairs npm install with npm run [chrome, firefox, prod], is fine for trying things out and wrong for reproducing a release.

## The manifest says 0.1.0 and the tags say v8.0.2

The package manifest reports version 0.1.0 under the name authenticator-extension, while the tagged releases are v8.0.0 from 2024-08-19, v8.0.1 from 2024-08-23, and v8.0.2 from 2024-09-15. The manifest version is therefore not a reliable way to tell what you are running, which matters when you are comparing two installs or writing a support question. Two dates matter alongside it: the default branch is dev rather than master, and the most recent push on that branch is dated 2026-09-18, well after the newest tag. Whatever has landed since v8.0.2 exists in the repository, but it is not something a tagged install gives you, so pin a release and read the changelog rather than assuming the branch head is the shipped state.

## The devDependencies say how the tests work

The test story is visible in the dependency list rather than described anywhere. mocha and chai cover the assertion side, sinon, sinon-chai, and sinon-chrome stand in for the extension APIs a browser would otherwise provide, nyc handles coverage, puppeteer brings its own browser download, and @vue/test-utils points at component level testing. Two things follow for anyone building this. A plain npm test pulls a browser through puppeteer, so the first run needs network access and disk space before it can say anything about your change. And because the extension APIs are stubbed with sinon-chrome, a green suite is evidence about logic rather than about the browser, which is why the Chrome development target and a real unpacked load still matter before you trust a change.

## Translations arrive through Crowdin, not through pull requests

Localization is a first-class part of this repository rather than an afterthought. The tree carries crowdin.yml next to the _locales/ directory, and the project badge points at the translation platform, so strings move through that workflow instead of being edited in place by contributors. The rest of the root is conventional and worth knowing before you open a pull request: .eslintrc.js and .eslintignore for lint rules, tsconfig.json for the TypeScript build, manifests/ for the browser manifests, images/ and svg/ for assets, and scripts/ for the build and test runners. A LICENSE file and a SECURITY.md sit alongside, and the project is MIT licensed.

## Security review came from a university CISO office

The acknowledgment section is unusual and worth reading for what it credits. The project thanks Laurent, the Chief Information Security Officer of the University of Luxembourg, and states that the CISO team provided security recommendations during development that helped identify and address potential vulnerabilities in the code. A second paragraph makes the same point at more length, describing the university's information security team as contributing beyond its own institution. Two observations follow. The credit is specific about who reviewed the security work, which is more information than most extension projects give you. And the repository carries a SECURITY.md file at the root, so there is a named place for disclosure, although what that file instructs reporters to do is not covered anywhere in the build documentation.

## Conclusion

Authenticator fits anyone who wants 2-Step Verification codes generated in the browser rather than on a phone, and it is a reasonable codebase to read if you want to see how an extension handles codes, localization and packaging. Two caveats come with it. The Safari edition is published on the App Store and explicitly not officially supported, and the build requires bash, so Windows contributors need Git Bash or Cygwin. Before you rely on a build, check which release you are actually running, because the manifest in package.json carries version 0.1.0 while the newest tagged release is v8.0.2 from 2024-09-15, and the most recent push on the default branch is dated 2026-09-18.

## FAQ

### Can I use Microsoft Authenticator without downloading the app?

This project is not the Microsoft app. It is a browser extension, published for Chrome, Firefox, and Microsoft Edge, that generates 2-Step Verification codes in the browser, plus a separate Safari edition on the App Store.

### Where can I install the Authenticator extension?

It is listed in the Chrome Web Store, in Firefox add-ons, and in Microsoft Edge add-ons. A Safari edition is on the App Store, and the project states it does not provide official support for that edition.

### How do I build the Chrome development version?

Run npm install, then npm run dev:chrome. That target builds first and then runs webpack in watch mode, compiling the Chrome extension into the ./test/chrome directory, which you load as an unpacked extension in Chrome.

### How do I reproduce a release build of Authenticator?

Use npm ci followed by npm run prod. Every build target passes a single argument to bash scripts/build.sh, with chrome, firefox, edge, prod, and test as the options, and npm test instead runs node scripts/test-runner.js.

### Can I build Authenticator on Windows?

Yes, with a shell. The project says Windows users should download a tool like Git Bash or Cygwin to build, because every npm build target calls bash scripts/build.sh.

## Sources

- [Authenticator-Extension/Authenticator on GitHub](https://github.com/Authenticator-Extension/Authenticator)
- [License: MIT](https://github.com/Authenticator-Extension/Authenticator/blob/dev/LICENSE)
- [Project website](https://authenticator.cc)
- [README](https://github.com/Authenticator-Extension/Authenticator/blob/dev/README.md)
- [Releases](https://github.com/Authenticator-Extension/Authenticator/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/authenticator-extension-authenticator
