@nylas/connect runs the OAuth flow that connects a user’s mailbox to your app. It opens the provider prompt, completes the PKCE exchange, stores the tokens, and refreshes them, so the work that would otherwise be a redirect route plus a callback handler plus refresh logic becomes one connect() call.
New to the library? Start with the quickstart, which walks through a working setup end to end and compares the 3 ways to run it.
Install the library
Section titled “Install the library”@nylas/connect is published on npm with zero runtime dependencies, so it adds exactly 1 package to your bundle. It’s TypeScript-first and ships its own type definitions.
npm install @nylas/connectpnpm add @nylas/connectReact apps should install @nylas/react instead, which wraps the same client in the useNylasConnect hook.
Configure the client
Section titled “Configure the client”NylasConnect accepts 11 options, and only 2 are required: clientId and redirectUri. Both fall back to environment variables, so new NylasConnect() with no arguments works once NYLAS_CLIENT_ID and NYLAS_REDIRECT_URI are set.
import { NylasConnect } from "@nylas/connect";
const nylasConnect = new NylasConnect({ clientId: "<NYLAS_CLIENT_ID>", redirectUri: "http://localhost:3000/auth/callback", apiUrl: "https://api.us.nylas.com",});| Option | Type | Default | Description |
|---|---|---|---|
clientId | string | NYLAS_CLIENT_ID | Your Nylas application’s client ID |
redirectUri | string | NYLAS_REDIRECT_URI | Where Nylas returns the user after they authorize |
apiUrl | string | https://api.us.nylas.com | Set to https://api.eu.nylas.com for EU accounts |
environment | Environment | detected automatically | development, staging, or production |
defaultScopes | NylasScope[] or object | connector scopes | Scopes to request, optionally keyed per provider |
persistTokens | boolean | true | Store tokens in localStorage; false keeps them in memory only |
autoHandleCallback | boolean | true | Let the browser exchange the code; set false for backend callbacks |
debug | boolean | on in development | Enable debug logging |
logLevel | LogLevel or "off" | follows debug | error, warn, info, debug, or off |
codeExchange | CodeExchangeMethod | built-in PKCE exchange | Replace the token exchange with your own implementation |
identityProviderToken | IdentityProviderTokenCallback | none | Returns your IdP’s JWT, sent to Nylas as idp_claims |
Setting identityProviderToken is what links a grant to your existing user identity. See using external identity providers for the 5 documented setups.
Connect a mailbox with a popup
Section titled “Connect a mailbox with a popup”The popup flow keeps the user on your page while they authorize, which suits single-page apps. connect() resolves with a ConnectResult once the popup closes, and the mailbox address is on result.grantInfo?.email rather than on the result itself.
import { NylasConnect } from "@nylas/connect";
const nylasConnect = new NylasConnect();
try { const result = await nylasConnect.connect({ method: "popup" }); console.log(`Connected ${result.grantInfo?.email} via ${result.grantInfo?.provider}`);} catch (error) { console.error("Authentication failed:", error);}The provider option accepts 4 values: google, microsoft, imap, and icloud. Omit it and the user picks their own provider from the login screen.
Connect a mailbox with a redirect
Section titled “Connect a mailbox with a redirect”The inline flow sends the browser to the provider instead of opening a window, which is the safer choice on mobile browsers and anywhere popups get blocked. connect() returns a URL string rather than a result, and you navigate to it yourself.
const url = await nylasConnect.connect({ method: "inline" });window.location.href = url;The method option accepts these 2 values and nothing else. Both produce the same grant; the only difference is where the user authorizes and how the result comes back to you.
Handle the OAuth callback
Section titled “Handle the OAuth callback”On the page at your redirectUri, call callback() to complete the exchange. With the default autoHandleCallback: true the client also detects the 2 callback parameters, code and state, exchanges them, and strips them from the address bar.
try { const result = await nylasConnect.callback(); console.log(`Authenticated: ${result.grantInfo?.email}`);} catch (error) { console.error("Callback handling failed:", error);}To exchange the code on your own server instead, see handling the OAuth callback on your backend.
Check the session and connection status
Section titled “Check the session and connection status”Grants break when a user changes their password or revokes access, so check the status rather than assuming a stored session still works. getConnectionStatus() returns 1 of 4 values: connected, expired, invalid, or not_connected.
const status = await nylasConnect.getConnectionStatus();
const session = await nylasConnect.getSession();if (session?.grantInfo) { console.log(`Connected as: ${session.grantInfo.email}`); console.log(`Grant ID: ${session.grantId}`);}Calling getSession() on page load is how you restore an existing session. It returns null when nobody is connected, which is your cue to show a connect button. To end a session, call logout(), optionally with a grant ID to target one mailbox out of several.
await nylasConnect.logout();await nylasConnect.logout("specific-grant-id");Handle connection errors
Section titled “Handle connection errors”The client throws 15 named error types, all extending NylasConnectError, and separately emits state-change events you can subscribe to. The 3 you’ll handle most often are PopupError, ConfigError, and OAuthError. Use try-catch when you’re driving the flow from a button handler, and onConnectStateChange when several parts of your UI react to the same connection.
try { const result = await nylasConnect.connect({ method: "popup" });} catch (error) { if (error.name === "PopupError") { console.error("Popup was blocked or closed"); } else if (error.name === "ConfigError") { console.error("Configuration error:", error.message); } else if (error.name === "OAuthError") { console.error("OAuth error:", error.message); }}nylasConnect.onConnectStateChange((event, session, data) => { switch (event) { case "CONNECT_SUCCESS": console.log("Connected:", session?.grantInfo?.email); break; case "CONNECT_ERROR": console.error("Connection failed:", data?.error); break; case "CONNECT_CANCELLED": console.log("User cancelled authentication"); break; case "CONNECT_STARTED": console.log("Authentication started"); break; }});A blocked popup is the most common failure in practice. Catch PopupError and fall back to the inline flow rather than leaving the user on a button that appears to do nothing.
Connect more than one mailbox
Section titled “Connect more than one mailbox”Call connect() again to add a second mailbox to the same user. Each call produces exactly 1 grant, and getSession() takes a grant ID so you can read them back individually.
const secondAccount = await nylasConnect.connect({ method: "popup", provider: "microsoft",});
const allSessions = await Promise.all([ nylasConnect.getSession("grant-1"), nylasConnect.getSession("grant-2"),]);What’s next
Section titled “What’s next”- Using external identity providers links grants to your existing user identities across Auth0, Clerk, Google, WorkOS, and custom JSON Web Key Set (JWKS) endpoints.
- Handling the callback on your backend keeps tokens out of the browser when you don’t use an identity provider.
NylasConnectclass reference documents every method signature and return type.@nylas/reactprovides the same client as a React hook and a prebuilt button.