Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ Run `npm run lint` to run the linter and check code styles.

Run `npm install && npm run build && npm run test:es-check:es5 && npm run test:es-check:es2015:module` to check for JS incompatibility.

Run `npm run smoke:modern` to validate the modern bundle (`dist/auth0.modern.js`) end-to-end. The script starts the dev server, drives a headless Chrome through the OIDC implicit (id_token) flow against the bundled oidc-provider, and asserts that `parseHash` returns a valid id_token. Useful before publishing changes to the modern build flavor or any of its shims (`src/helper/*-shim.js`). Requires a chromedriver matching your installed Chrome major version — install with `npm i -D chromedriver@<major>` if you see "session not created".

See [.circleci/config.yml](.circleci/config.yml) for additional checks that might be run as part of
[circleci integration tests](https://circleci.com/).
69 changes: 69 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,75 @@ After installing the `auth0-js` module using [npm](https://npmjs.org), you'll ne
import auth0 from 'auth0-js';
```

### Modern bundle (smaller, evergreen-only)

For applications that don't need to support legacy browsers (IE9–IE11), auth0-js v10 also ships a "modern" bundle that's substantially smaller. It replaces several legacy npm dependencies (`qs`, `superagent`, `es6-promise`, `unfetch`, `base64-js`) with thin shims over native browser APIs (`URLSearchParams`, `fetch`, `Promise`, `btoa`/`atob`).

| Bundle | Raw size | Gzipped |
|---|---|---|
| Default (`auth0-js`) | ~174 KB | ~51 KB |
| Modern (`auth0-js/modern`) | **~101 KB** | **~29 KB** |

**Browser support floor for the modern bundle:**

| Browser | Minimum version | Released |
|---|---|---|
| Chrome / Chromium-Edge | 70 | Oct 2018 |
| Firefox | 65 | Jan 2019 |
| Safari | 12 | Sep 2018 |

Earlier browsers (including any version of IE) are *not* supported by the modern bundle. Consumers needing those should keep using the default import path.

#### Usage — direct import

```js
import auth0 from 'auth0-js/modern';
```

The API surface is identical to the default — `WebAuth`, `Authentication`, and `Management` are all exposed the same way. Switching is a one-line change at each call site.

#### Usage — bundler alias (transparent swap)

To route every `import ... from 'auth0-js'` in your codebase to the modern bundle without editing import statements, alias it in your bundler config:

**webpack** (`webpack.config.js`):
```js
module.exports = {
resolve: {
alias: { 'auth0-js$': 'auth0-js/modern' }
}
};
```

**Vite** (`vite.config.js`):
```js
export default {
resolve: {
alias: { 'auth0-js': 'auth0-js/modern' }
}
};
```

**esbuild**:
```js
build({
alias: { 'auth0-js': 'auth0-js/modern' }
});
```

**Rollup** (with `@rollup/plugin-alias`):
```js
import alias from '@rollup/plugin-alias';

export default {
plugins: [
alias({ entries: [{ find: 'auth0-js', replacement: 'auth0-js/modern' }] })
]
};
```

The default `import auth0 from 'auth0-js'` continues to resolve to the IE-compatible legacy bundle, so consumers who don't opt in are unaffected.

### Configure the SDK

#### auth0.WebAuth
Expand Down
7 changes: 5 additions & 2 deletions dist/auth0.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* auth0-js v10.0.0
* Author: Auth0
* Date: 2026-05-06
* Date: 2026-05-14
* License: MIT
*/

Expand Down Expand Up @@ -8244,7 +8244,10 @@
}).withCredentials().end(wrapCallback(cb));
};

// eslint-disable-next-line no-unused-vars
/**
* @typedef {import('../authentication').default} Authentication
*/

var noop = function noop() {};
var captchaSolved = noop;
var done = noop;
Expand Down
2 changes: 1 addition & 1 deletion dist/auth0.min.esm.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/auth0.min.esm.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/auth0.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/auth0.min.js.map

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions dist/auth0.modern.min.esm.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions dist/auth0.modern.min.esm.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/cordova-auth0-plugin.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* auth0-js v10.0.0
* Author: Auth0
* Date: 2026-05-06
* Date: 2026-05-14
* License: MIT
*/

Expand Down
2 changes: 1 addition & 1 deletion dist/cordova-auth0-plugin.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 97 additions & 0 deletions example/test-modern.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html>
<head>
<title>Auth0.js Modern-Bundle Smoke Test</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body class="container">
<input id="login-username" value="" />
<input id="login-password" type="password" value="" />
<input id="login-scope" value="" />
<input id="login-response-type" value="" />

<input
type="button"
class="login-redirect-usernamepassword"
value="redirect usernamepassword"
/>

<input
type="button"
class="login-redirect-authorize"
value="redirect authorize"
/>

<input type="button" value="logout" class="logout-button" />

<input type="button" class="reset-button" value="reset" />

<div id="err"></div>
<div id="result"></div>

<script type="module">
import auth0 from '/auth0.modern.min.esm.js';
window.auth0 = auth0; // exposed for the selenium smoke test

const webAuth = new auth0.WebAuth({
domain: 'http://127.0.0.1:3000',
redirectUri: window.location.href,
clientID: 'testing',
leeway: 30,
overrides: {
__token_issuer: 'http://127.0.0.1:3000/'
},
prompt: 'login'
});

$('.login-redirect-usernamepassword').click(function (e) {
e.preventDefault();
webAuth.redirect.loginWithCredentials(
{
connection: 'tests',
username: $('#login-username').val(),
password: $('#login-password').val(),
scope: $('#login-scope').val(),
responseType: $('#login-response-type').val()
},
function (err) {
$('#err').html(JSON.stringify(err));
}
);
});

$('.login-redirect-authorize').click(function (e) {
e.preventDefault();
webAuth.authorize({
scope: $('#login-scope').val(),
responseType: $('#login-response-type').val()
});
});

$('.logout-button').click(function (e) {
e.preventDefault();
webAuth.logout({ returnTo: 'http://127.0.0.1:3000/test-modern.html' });
});

$('.reset-button').click(function (e) {
e.preventDefault();
window.location.href = 'http://127.0.0.1:3000/test-modern.html';
});

webAuth.parseHash(function (err, result) {
if (err) {
$('#err').html(JSON.stringify(err));
$(document.body).append($('<div id="parsed"></div>'));
}
if (result) {
$('#result').html(JSON.stringify(result));
$(document.body).append($('<div id="parsed"></div>'));
}
});

$(document).ready(function () {
$(document.body).append($('<div id="loaded"></div>'));
});
</script>
</body>
</html>
16 changes: 15 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
"type": "module",
"module": "dist/auth0.min.esm.js",
"main": "dist/auth0.min.js",
"exports": {
".": {
"import": "./dist/auth0.min.esm.js",
"require": "./dist/auth0.min.js",
"default": "./dist/auth0.min.js"
},
"./modern": {
"import": "./dist/auth0.modern.min.esm.js",
"default": "./dist/auth0.modern.min.esm.js"
},
"./package.json": "./package.json"
},
"files": [
"src",
"plugins",
Expand All @@ -31,9 +43,11 @@
"test:e2e:browserstack": "cross-env BABEL_ENV=test BROWSERSTACK=true npm run test:e2e:services",
"test:e2e:services": "concurrently --raw --kill-others --success first npm:start npm:test:e2e:run",
"test:e2e:run": "wait-on http://localhost:3000 && mocha --delay --require jsdom-global/register --require @babel/register integration/**/*.test.js",
"smoke:modern": "concurrently --raw --kill-others --success first npm:start \"wait-on http://localhost:3000 && node scripts/smoke-modern.mjs\"",
"test:watch": "npm run test -- --watch --reporter min",
"test:es-check:es5": "es-check es5 'dist/!(*.esm)*.js'",
"test:es-check:es5": "es-check es5 'dist/!(*.esm|*.modern).js'",
"test:es-check:es2015:module": "es-check es2015 'dist/auth0.min.esm.js' --module",
"test:es-check:es2019:modern": "es-check es2019 'dist/auth0.modern.min.esm.js' --module",
"ci:test": "nyc npm run test -- --forbid-only --reporter mocha-junit-reporter",
"lint": "eslint ./src",
"lint:fix": "eslint --fix ./src",
Expand Down
73 changes: 65 additions & 8 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import path from 'path';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import replace from '@rollup/plugin-replace';
Expand All @@ -10,6 +11,31 @@ import { createRequire } from 'module';
import MagicString from 'magic-string';
import createApp from './scripts/oidc-provider.mjs';

// Modern build only: redirect packages whose only purpose (or whose modern
// equivalent) is already a built-in browser API. Legacy builds continue to
// bundle the originals for older browser support.
const MODERN_ALIASES = {
qs: 'src/helper/qs-shim.js',
'es6-promise': 'src/helper/es6-promise-shim.js',
unfetch: 'src/helper/unfetch-shim.js',
'base64-js': 'src/helper/base64-js-shim.js',
superagent: 'src/helper/superagent-shim.js',
// idtoken-verifier publishes a pre-bundled artifact that inlines es6-promise
// and unfetch as bytes, so our aliases above never see those specifiers.
// Redirect to the unbundled source so the shims actually take effect.
'idtoken-verifier': 'node_modules/idtoken-verifier/src/index.js'
};

const aliasModernShims = () => ({
name: 'alias-modern-shims',
resolveId(id) {
if (Object.prototype.hasOwnProperty.call(MODERN_ALIASES, id)) {
return path.resolve(MODERN_ALIASES[id]);
}
return null;
}
});

const require = createRequire(import.meta.url);
const pkg = require('./package.json');

Expand Down Expand Up @@ -62,7 +88,19 @@ const fixES5 = () => ({
const isProduction = process.env.PRODUCTION === 'true';
const OUTPUT_PATH = 'dist';

const getPlugins = prod => [
const LEGACY_TARGETS = { ie: '9' };
// Modern target floor sits just below where optional chaining (ES2020) became
// native — Babel transpiles `?.` and any other post-2018 syntax. Picked to widen
// coverage to late-2018 evergreens at a small (~tens of bytes) bundle cost.
const MODERN_TARGETS = {
chrome: '70',
firefox: '65',
safari: '12',
edge: '79'
};

const getPlugins = (prod, { modern = false } = {}) => [
modern && aliasModernShims(),
resolve({
browser: true
}),
Expand All @@ -77,12 +115,13 @@ const getPlugins = prod => [
babelHelpers: 'bundled',
presets: [
['@babel/preset-env', {
targets: {
ie: '9'
}
targets: modern ? MODERN_TARGETS : LEGACY_TARGETS,
bugfixes: modern
}]
],
include: ['src/**', 'node_modules/superagent/**']
include: modern
? ['src/**', 'node_modules/idtoken-verifier/**']
: ['src/**', 'node_modules/superagent/**']
}),
replace({
__DEV__: prod ? 'false' : 'true',
Expand All @@ -102,9 +141,9 @@ const getPlugins = prod => [
License: MIT
`
}),
// Always apply ES5 compatibility fixes since all builds need to support IE9
fixES5()
];
// Legacy builds need ES5 compatibility fixes for IE9; modern builds skip this
!modern && fixES5()
].filter(Boolean);

const prodFiles = [
{
Expand All @@ -125,6 +164,15 @@ const prodFiles = [
],
plugins: getPlugins(isProduction)
},
{
input: 'src/index.js',
output: {
file: `${OUTPUT_PATH}/auth0.modern.min.esm.js`,
format: 'es',
sourcemap: true
},
plugins: getPlugins(isProduction, { modern: true })
},
{
input: 'plugins/cordova/index.js',
output: {
Expand Down Expand Up @@ -160,6 +208,15 @@ const devFiles = [
// !isProduction && livereload()
]
},
{
input: 'src/index.js',
output: {
file: `${OUTPUT_PATH}/auth0.modern.min.esm.js`,
format: 'es',
sourcemap: isProduction ? false : 'inline'
},
plugins: getPlugins(false, { modern: true })
},
{
input: 'plugins/cordova/index.js',
output: {
Expand Down
Loading